ca846da0f15c932a15b76ea0c84ef137747df7fd
[xonotic/xonotic-data.pk3dir.git] / qcsrc / lib / csqcmodel / interpolate.qc
1 /*
2  * Copyright (c) 2011 Rudolf Polzer
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to
6  * deal in the Software without restriction, including without limitation the
7  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8  * sell copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20  * IN THE SOFTWARE.
21  */
22 #include "interpolate.qh"
23
24 #if defined(CSQC)
25 //      #include "../../client/defs.qh"
26 //      #include "../warpzone/anglestransform.qh"
27 //      #include "../../client/autocvars.qh"
28 //      #include "cl_model.qh"
29 #elif defined(MENUQC)
30 #elif defined(SVQC)
31 #endif
32
33 .vector iorigin1, iorigin2;
34 .vector ivelocity1, ivelocity2;
35 .vector iforward1, iforward2;
36 .vector iup1, iup2;
37 .vector ivforward1, ivforward2;
38 .vector ivup1, ivup2;
39 .float itime1, itime2;
40 void InterpolateOrigin_Reset()
41 {SELFPARAM();
42         self.iflags &= ~IFLAG_INTERNALMASK;
43         self.itime1 = self.itime2 = 0;
44 }
45 void InterpolateOrigin_Note()
46 {SELFPARAM();
47         float dt;
48         int f0;
49
50         dt = time - self.itime2;
51
52         f0 = self.iflags;
53         if(self.iflags & IFLAG_PREVALID)
54                 self.iflags |= IFLAG_VALID;
55         else
56                 self.iflags |= IFLAG_PREVALID;
57
58         if(self.iflags & IFLAG_ORIGIN)
59         {
60                 self.iorigin1 = self.iorigin2;
61                 self.iorigin2 = self.origin;
62         }
63
64         if(self.iflags & IFLAG_AUTOANGLES)
65                 if(self.iorigin2 != self.iorigin1)
66                         self.angles = vectoangles(self.iorigin2 - self.iorigin1);
67
68         if(self.iflags & IFLAG_AUTOVELOCITY)
69                 if(self.itime2 != self.itime1)
70                         self.velocity = (self.iorigin2 - self.iorigin1) * (1.0 / (self.itime2 - self.itime1));
71
72         if(self.iflags & IFLAG_ANGLES)
73         {
74                 fixedmakevectors(self.angles);
75                 if(f0 & IFLAG_VALID)
76                 {
77                         self.iforward1 = self.iforward2;
78                         self.iup1 = self.iup2;
79                 }
80                 else
81                 {
82                         self.iforward1 = v_forward;
83                         self.iup1 = v_up;
84                 }
85                 self.iforward2 = v_forward;
86                 self.iup2 = v_up;
87         }
88
89         if(self.iflags & IFLAG_V_ANGLE)
90         {
91                 fixedmakevectors(self.v_angle);
92                 if(f0 & IFLAG_VALID)
93                 {
94                         self.ivforward1 = self.ivforward2;
95                         self.ivup1 = self.ivup2;
96                 }
97                 else
98                 {
99                         self.ivforward1 = v_forward;
100                         self.ivup1 = v_up;
101                 }
102                 self.ivforward2 = v_forward;
103                 self.ivup2 = v_up;
104         }
105         else if(self.iflags & IFLAG_V_ANGLE_X)
106         {
107                 self.ivforward1_x = self.ivforward2_x;
108                 self.ivforward2_x = self.v_angle.x;
109         }
110
111         if(self.iflags & IFLAG_VELOCITY)
112         {
113                 self.ivelocity1 = self.ivelocity2;
114                 self.ivelocity2 = self.velocity;
115         }
116
117         if(self.iflags & IFLAG_TELEPORTED)
118         {
119                 self.iflags &= ~IFLAG_TELEPORTED;
120                 self.itime1 = self.itime2 = time; // don't lerp
121         }
122         else if(vlen(self.iorigin2 - self.iorigin1) > 1000)
123         {
124                 self.itime1 = self.itime2 = time; // don't lerp
125         }
126         else if((self.iflags & IFLAG_VELOCITY) && (vlen(self.ivelocity2 - self.ivelocity1) > 1000))
127         {
128                 self.itime1 = self.itime2 = time; // don't lerp
129         }
130         else if(dt >= 0.2)
131         {
132                 self.itime1 = self.itime2 = time;
133         }
134         else
135         {
136                 self.itime1 = serverprevtime;
137                 self.itime2 = time;
138         }
139 }
140 void InterpolateOrigin_Do()
141 {SELFPARAM();
142         vector forward, up;
143         if(self.itime1 && self.itime2 && self.itime1 != self.itime2)
144         {
145                 float f;
146                 f = bound(0, (time - self.itime1) / (self.itime2 - self.itime1), 1 + autocvar_cl_lerpexcess);
147                 if(self.iflags & IFLAG_ORIGIN)
148                         setorigin(self, (1 - f) * self.iorigin1 + f * self.iorigin2);
149                 if(self.iflags & IFLAG_ANGLES)
150                 {
151                         forward = (1 - f) * self.iforward1 + f * self.iforward2;
152                         up = (1 - f) * self.iup1 + f * self.iup2;
153                         self.angles = fixedvectoangles2(forward, up);
154                 }
155                 if(self.iflags & IFLAG_V_ANGLE)
156                 {
157                         forward = (1 - f) * self.ivforward1 + f * self.ivforward2;
158                         up = (1 - f) * self.ivup1 + f * self.ivup2;
159                         self.v_angle = fixedvectoangles2(forward, up);
160                 }
161                 else if(self.iflags & IFLAG_V_ANGLE_X)
162                         self.v_angle_x = (1 - f) * self.ivforward1_x + f * self.ivforward2_x;
163                 if(self.iflags & IFLAG_VELOCITY)
164                         self.velocity = (1 - f) * self.ivelocity1 + f * self.ivelocity2;
165         }
166 }
167 void InterpolateOrigin_Undo()
168 {SELFPARAM();
169         if(self.iflags & IFLAG_ORIGIN)
170                 setorigin(self, self.iorigin2);
171         if(self.iflags & IFLAG_ANGLES)
172                 self.angles = fixedvectoangles2(self.iforward2, self.iup2);
173         if(self.iflags & IFLAG_V_ANGLE)
174                 self.v_angle = fixedvectoangles2(self.ivforward2, self.ivup2);
175         else if(self.iflags & IFLAG_V_ANGLE_X)
176                 self.v_angle_x = self.ivforward2_x;
177         if(self.iflags & IFLAG_VELOCITY)
178                 self.velocity = self.ivelocity2;
179 }
180