From ba3810740842d495073195bc5ea6afd1021cd617 Mon Sep 17 00:00:00 2001 From: TimePath Date: Sat, 29 Aug 2015 15:26:23 +1000 Subject: [PATCH] Polytrails! --- gfx/trails/plain.tga | Bin 0 -> 262188 bytes qcsrc/client/mutators/all.inc | 1 + qcsrc/client/mutators/all.qc | 1 + qcsrc/client/mutators/mutator/polytrails.qc | 109 ++++++++++++++++++++ qcsrc/client/progs.src | 1 + qcsrc/common/physics.qc | 8 +- qcsrc/lib/Math.qh | 18 ++++ 7 files changed, 134 insertions(+), 4 deletions(-) create mode 100644 gfx/trails/plain.tga create mode 100644 qcsrc/client/mutators/all.inc create mode 100644 qcsrc/client/mutators/all.qc create mode 100644 qcsrc/client/mutators/mutator/polytrails.qc diff --git a/gfx/trails/plain.tga b/gfx/trails/plain.tga new file mode 100644 index 0000000000000000000000000000000000000000..3761275ad08082b36047b6f94160b7ae821e6649 GIT binary patch literal 262188 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 X_2b`v{Oe!-@b5qU_~#$~_}+g2T{{NU literal 0 HcmV?d00001 diff --git a/qcsrc/client/mutators/all.inc b/qcsrc/client/mutators/all.inc new file mode 100644 index 000000000..22bd5fd8a --- /dev/null +++ b/qcsrc/client/mutators/all.inc @@ -0,0 +1 @@ +#include "mutator/polytrails.qc" diff --git a/qcsrc/client/mutators/all.qc b/qcsrc/client/mutators/all.qc new file mode 100644 index 000000000..14530a3c5 --- /dev/null +++ b/qcsrc/client/mutators/all.qc @@ -0,0 +1 @@ +#include "all.inc" diff --git a/qcsrc/client/mutators/mutator/polytrails.qc b/qcsrc/client/mutators/mutator/polytrails.qc new file mode 100644 index 000000000..09c385e83 --- /dev/null +++ b/qcsrc/client/mutators/mutator/polytrails.qc @@ -0,0 +1,109 @@ +bool autocvar_cl_polytrails = false; +float autocvar_cl_polytrail_segmentsize = 10; +float autocvar_cl_polytrail_lifetime = .2; + +CLASS(PolyTrail, Object) + ATTRIB(PolyTrail, polytrail_follow, entity, NULL) + ATTRIB(PolyTrail, polytrail_tex, string, string_null) + /** Lifetime per segment */ + ATTRIB(PolyTrail, polytrail_lifetime, float, autocvar_cl_polytrail_lifetime) + ATTRIBARRAY(PolyTrail, polytrail_rgb, vector, 3) + ATTRIBARRAY(PolyTrail, polytrail_alpha, float, 3) + ATTRIBARRAY(PolyTrail, polytrail_thickness, float, 3) + + /** + * Increase as necessary if the buffer is overflowing + * symptom: tail of trail is wrong + * cause: projectiles are too fast for the segment size + */ + const int POLYTRAIL_BUFSIZE = 1 << 7; + /** One or more positional points */ + ATTRIBARRAY(PolyTrail, polytrail_bufpos, vector, POLYTRAIL_BUFSIZE) + /** Time of input */ + ATTRIBARRAY(PolyTrail, polytrail_buftime, float, POLYTRAIL_BUFSIZE) + /** Current read index */ + ATTRIB(PolyTrail, polytrail_bufidx, float, -1) + /** Counts positions stored */ + ATTRIB(PolyTrail, polytrail_cnt, float, 0) + #define POLYTRAIL_SEEK(_p, _rel) ((POLYTRAIL_BUFSIZE + (_p).polytrail_bufidx + (_rel)) % POLYTRAIL_BUFSIZE) + + void Trail_draw(); + ATTRIB(PolyTrail, draw, void(), Trail_draw) + void Trail_draw() { + PolyTrail this = self; + if (wasfreed(this.polytrail_follow)) this.polytrail_follow = NULL; + if (!this.polytrail_follow) { + float when = this.polytrail_buftime[this.polytrail_bufidx]; + if (time - when > this.polytrail_lifetime) { + remove(this); + return; + } + } else { + setorigin(this, this.polytrail_follow.origin); + if (this.polytrail_cnt < 0 || vlen(this.origin - this.polytrail_bufpos[this.polytrail_bufidx]) >= autocvar_cl_polytrail_segmentsize) { + int i = POLYTRAIL_SEEK(this, 1); + this.polytrail_bufpos[i] = this.origin; + this.polytrail_buftime[i] = time; + this.polytrail_bufidx = i; + this.polytrail_cnt = bound(this.polytrail_cnt, i + 1, POLYTRAIL_BUFSIZE); + } + } + + int count = this.polytrail_cnt; + for (int i = 0; i < count; ++i) { + int idx = POLYTRAIL_SEEK(this, -i); + float when = this.polytrail_buftime[idx]; + if (time - when >= this.polytrail_lifetime) { + count = i + 1; + break; + } + } + + vector from = this.origin; + for (int i = 0, n = count; i < n; ++i) { + int idx = POLYTRAIL_SEEK(this, -i); + float when = this.polytrail_buftime[idx]; + vector to = this.polytrail_bufpos[idx]; + // head: 0, tail: 1 + float rtime = (time - when) / this.polytrail_lifetime; + noref float rdist = i / n; + vector rgb = lerpv3ratio(this.polytrail_rgb[0], this.polytrail_rgb[1], this.polytrail_rgb[2], rtime); + float a = lerp3ratio(this.polytrail_alpha[0], this.polytrail_thickness[1], this.polytrail_alpha[2], rtime); + int thickness = lerp3ratio(this.polytrail_thickness[0], this.polytrail_thickness[1], this.polytrail_thickness[2], rtime); + vector thickdir = normalize(cross(normalize(to - from), view_origin - from)) * (thickness / 2); + vector A = from + thickdir; + vector B = from - thickdir; + vector C = to + thickdir; + vector D = to - thickdir; + R_BeginPolygon(this.polytrail_tex, DRAWFLAG_SCREEN); + R_PolygonVertex(B, '0 0 0', rgb, a); + R_PolygonVertex(A, '0 1 0', rgb, a); + R_PolygonVertex(C, '1 1 0', rgb, a); + R_PolygonVertex(D, '1 0 0', rgb, a); + R_EndPolygon(); + from = to; + } + } + CONSTRUCTOR(PolyTrail, entity _follow) { + CONSTRUCT(PolyTrail); + this.polytrail_follow = _follow; + } +ENDCLASS(PolyTrail) + +REGISTER_MUTATOR(polytrails, true); + +MUTATOR_HOOKFUNCTION(polytrails, EditProjectile) { + return = false; + if (!autocvar_cl_polytrails) return; + PolyTrail t = NEW(PolyTrail, self); + t.polytrail_tex = "gfx/trails/plain.tga"; + t.polytrail_rgb[0] = '1 0 0'; + t.polytrail_rgb[1] = '0 1 0'; + t.polytrail_rgb[2] = '0 0 1'; + t.polytrail_alpha[0] = 1; + t.polytrail_alpha[1] = 0.5; + t.polytrail_alpha[2] = 0; + t.polytrail_thickness[0] = 10; + t.polytrail_thickness[1] = 5; + t.polytrail_thickness[2] = 0; +} diff --git a/qcsrc/client/progs.src b/qcsrc/client/progs.src index 506669602..5186dc150 100644 --- a/qcsrc/client/progs.src +++ b/qcsrc/client/progs.src @@ -34,6 +34,7 @@ view.qc wall.qc command/all.qc +mutators/all.qc weapons/projectile.qc // TODO diff --git a/qcsrc/common/physics.qc b/qcsrc/common/physics.qc index e5b83443f..b850864c8 100644 --- a/qcsrc/common/physics.qc +++ b/qcsrc/common/physics.qc @@ -188,11 +188,11 @@ float IsMoveInDirection(vector mv, float ang) // key mix factor return ang > 1 ? 0 : ang < -1 ? 0 : 1 - fabs(ang); } -float GeomLerp(float a, float lerp, float b) +float GeomLerp(float a, float _lerp, float b) { - return a == 0 ? (lerp < 1 ? 0 : b) - : b == 0 ? (lerp > 0 ? 0 : a) - : a * pow(fabs(b / a), lerp); + return a == 0 ? (_lerp < 1 ? 0 : b) + : b == 0 ? (_lerp > 0 ? 0 : a) + : a * pow(fabs(b / a), _lerp); } noref float pmove_waterjumptime; diff --git a/qcsrc/lib/Math.qh b/qcsrc/lib/Math.qh index a8a52907a..bdf747429 100644 --- a/qcsrc/lib/Math.qh +++ b/qcsrc/lib/Math.qh @@ -85,6 +85,24 @@ vector vsnap(vector point,float fsize) return vret; } +float lerpratio(float f0, float f1, float ratio) { return f0 * (1 - ratio) + f1 * ratio; } + +float lerp(float t0, float f0, float t1, float f1, float t) { return lerpratio(f0, f1, (t - t0) / (t1 - t0)); } + +float lerp3ratio(float f0, float f1, float f2, float ratio) +{ + int mid = 0.5; + return ratio < mid ? lerpratio(f0, f1, ratio / mid) : ratio > mid ? lerpratio(f1, f2, (ratio - mid) / mid) : f1; +} + +vector lerpvratio(vector f0, vector f1, float ratio) { return f0 * (1 - ratio) + f1 * ratio; } + +vector lerpv3ratio(vector f0, vector f1, vector f2, float ratio) +{ + int mid = 0.5; + return ratio < mid ? lerpvratio(f0, f1, ratio / mid) : ratio > mid ? lerpvratio(f1, f2, (ratio - mid) / mid) : f1; +} + vector lerpv(float t0, vector v0, float t1, vector v1, float t) { return v0 + (v1 - v0) * ((t - t0) / (t1 - t0)); -- 2.39.2