]> icculus.org git repositories - divverent/nexuiz.git/blob - data/qcsrc/client/laser.qc
fix laser interpolation
[divverent/nexuiz.git] / data / qcsrc / client / laser.qc
1 // FIXME make this generic code, to be used for other entities too?
2 .vector iorigin1, iorigin2;
3 .vector ivelocity1, ivelocity2;
4 .vector iforward1, iforward2;
5 .vector iright1, iright2;
6 .float itime1, itime2;
7 void InterpolateOrigin_Note()
8 {
9         float dt;
10
11         makevectors(self.angles);
12
13         self.iorigin1 = self.iorigin2;
14         self.iforward1 = self.iforward2;
15         self.iright1 = self.iright2;
16         self.ivelocity1 = self.ivelocity2;
17
18         self.iorigin2 = self.origin;
19         self.iforward2 = v_forward;
20         self.iright2 = v_right;
21         self.ivelocity2 = self.velocity;
22
23         dt = time - self.itime1;
24
25         if(vlen(self.iorigin2 - self.iorigin1) > 1000)
26         {
27                 self.iorigin1 = self.iorigin2;
28                 self.iforward1 = self.iforward2;
29                 self.iright1 = self.iright2;
30                 self.ivelocity1 = self.ivelocity2;
31         }
32         else if(vlen(self.ivelocity2 - self.ivelocity1) > 1000)
33         {
34                 self.iforward1 = self.iforward2;
35                 self.iright1 = self.iright2;
36                 self.ivelocity1 = self.ivelocity2;
37         }
38
39         if(dt < 0.2)
40         {
41                 self.itime1 = time;
42                 self.itime2 = time + getstatf(STAT_SYS_TICRATE);
43         }
44         else
45         {
46                 // don't lerp
47                 self.itime1 = self.itime2 = time;
48         }
49 }
50 void InterpolateOrigin_Do()
51 {
52         vector forward, right;
53         if(self.itime1 && self.itime2 && self.itime1 != self.itime2)
54         {
55                 float f;
56                 f = bound(0, (time - self.itime1) / (self.itime2 - self.itime1), 1);
57                 self.origin = (1 - f) * self.iorigin1 + f * self.iorigin2;
58                 forward = (1 - f) * self.iforward1 + f * self.iforward2;
59                 right = (1 - f) * self.iright1 + f * self.iright2;
60                 self.angles = vectoangles(forward, right);
61                 self.angles_x = -self.angles_x;
62                 self.velocity = (1 - f) * self.ivelocity1 + f * self.ivelocity2;
63         }
64 }
65 void InterpolateOrigin_Undo()
66 {
67         self.origin = self.iorigin2;
68         self.angles = vectoangles(self.iforward2, self.iright2);
69         self.angles_x = -self.angles_x;
70         self.velocity = self.ivelocity2;
71 }
72
73 // a laser goes from origin in direction angles
74 // it has color 'colormod'
75 // and stops when something is in the way
76 .float cnt; // end effect
77 .vector colormod;
78 .float state; // on-off
79 .float count; // flags for the laser
80 .vector velocity;
81 .float alpha;
82
83 void Draw_Laser()
84 {
85         if(!self.state)
86                 return;
87         InterpolateOrigin_Do();
88         if(self.count & 0x80)
89         {
90                 traceline(self.origin, self.velocity, 0, self);
91         }
92         else
93         {
94                 makevectors(self.angles);
95                 traceline(self.origin, self.origin + v_forward * 32768, 0, self);
96         }
97         if(self.alpha)
98         {
99                 Draw_CylindricLine(self.origin, trace_endpos, 2, "particles/laserbeam", 0, time * 3, self.colormod, self.alpha, DRAWFLAG_NORMAL); // TODO make a texture to make the laser look smoother
100         }
101         else
102         {
103                 Draw_CylindricLine(self.origin, trace_endpos, 2, "particles/laserbeam", 0, time * 3, self.colormod, 1, DRAWFLAG_ADDITIVE); // TODO make a texture to make the laser look smoother
104         }
105         pointparticles(self.cnt, trace_endpos, trace_plane_normal, 256 * drawframetime);
106 }
107
108 void Ent_Laser()
109 {
110         float f;
111         // 30 bytes, or 13 bytes for just moving
112         f = ReadByte();
113         self.count = (f & 0xC0);
114         InterpolateOrigin_Undo();
115         if(f & 1)
116         {
117                 self.origin_x = ReadCoord();
118                 self.origin_y = ReadCoord();
119                 self.origin_z = ReadCoord();
120         }
121         if(f & 8)
122         {
123                 self.colormod_x = ReadByte() / 255.0;
124                 self.colormod_y = ReadByte() / 255.0;
125                 self.colormod_z = ReadByte() / 255.0;
126                 if(f & 0x40)
127                         self.alpha = ReadByte() / 255.0;
128                 else
129                         self.alpha = 0;
130                 self.cnt = ReadShort(); // effect number
131         }
132         if(f & 2)
133         {
134                 if(f & 0x80)
135                 {
136                         self.velocity_x = ReadCoord();
137                         self.velocity_y = ReadCoord();
138                         self.velocity_z = ReadCoord();
139                 }
140                 else
141                 {
142                         self.angles_x = ReadCoord();
143                         self.angles_y = ReadCoord();
144                 }
145         }
146         if(f & 4)
147                 self.state = ReadByte();
148         InterpolateOrigin_Note();
149         self.draw = Draw_Laser;
150 }