]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/lib/csqcmodel/interpolate.qc
Add a hack to fix the use of self in .predraw functions
[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 // 1 = old, 2 = new
25 .vector iorigin1, iorigin2;
26 .vector ivelocity1, ivelocity2;
27 .vector iforward1, iforward2;
28 .vector iup1, iup2;
29 .vector ivforward1, ivforward2;
30 .vector ivup1, ivup2;
31 .float itime1, itime2;
32 void InterpolateOrigin_Reset()
33 {
34         SELFPARAM();
35         self.iflags &= ~IFLAG_INTERNALMASK;
36         self.itime1 = self.itime2 = 0;
37 }
38 void InterpolateOrigin_Note(entity this)
39 {
40         float dt = time - this.itime2;
41
42         int f0 = this.iflags;
43         if (this.iflags & IFLAG_PREVALID) this.iflags |= IFLAG_VALID;
44         else this.iflags |= IFLAG_PREVALID;
45
46         if (this.iflags & IFLAG_ORIGIN)
47         {
48                 this.iorigin1 = this.iorigin2;
49                 this.iorigin2 = this.origin;
50         }
51
52         if (this.iflags & IFLAG_AUTOANGLES
53             && this.iorigin2
54             != this.iorigin1) this.angles = vectoangles(this.iorigin2 - this.iorigin1);
55
56         if (this.iflags & IFLAG_AUTOVELOCITY
57             && this.itime2
58             != this.itime1) this.velocity = (this.iorigin2 - this.iorigin1) * (1.0 / (this.itime2 - this.itime1));
59
60         if (this.iflags & IFLAG_ANGLES)
61         {
62                 fixedmakevectors(this.angles);
63                 if (f0 & IFLAG_VALID)
64                 {
65                         this.iforward1 = this.iforward2;
66                         this.iup1 = this.iup2;
67                 }
68                 else
69                 {
70                         this.iforward1 = v_forward;
71                         this.iup1 = v_up;
72                 }
73                 this.iforward2 = v_forward;
74                 this.iup2 = v_up;
75         }
76
77         if (this.iflags & IFLAG_V_ANGLE)
78         {
79                 fixedmakevectors(this.v_angle);
80                 if (f0 & IFLAG_VALID)
81                 {
82                         this.ivforward1 = this.ivforward2;
83                         this.ivup1 = this.ivup2;
84                 }
85                 else
86                 {
87                         this.ivforward1 = v_forward;
88                         this.ivup1 = v_up;
89                 }
90                 this.ivforward2 = v_forward;
91                 this.ivup2 = v_up;
92         }
93         else if (this.iflags & IFLAG_V_ANGLE_X)
94         {
95                 this.ivforward1_x = this.ivforward2_x;
96                 this.ivforward2_x = this.v_angle.x;
97         }
98
99         if (this.iflags & IFLAG_VELOCITY)
100         {
101                 this.ivelocity1 = this.ivelocity2;
102                 this.ivelocity2 = this.velocity;
103         }
104
105         if (this.iflags & IFLAG_TELEPORTED)
106         {
107                 this.iflags &= ~IFLAG_TELEPORTED;
108                 this.itime1 = this.itime2 = time;  // don't lerp
109         }
110         else if (vdist(this.iorigin2 - this.iorigin1, >, 1000))
111         {
112                 this.itime1 = this.itime2 = time;  // don't lerp
113         }
114         else if ((this.iflags & IFLAG_VELOCITY) && vdist(this.ivelocity2 - this.ivelocity1, >, 1000))
115         {
116                 this.itime1 = this.itime2 = time;  // don't lerp
117         }
118         else if (dt >= 0.2)
119         {
120                 this.itime1 = this.itime2 = time;
121         }
122         else
123         {
124                 this.itime1 = serverprevtime;
125                 this.itime2 = time;
126         }
127 }
128
129 /** set origin based on iorigin1 (old pos), iorigin2 (desired pos), and time */
130 void InterpolateOrigin_Do(entity this)
131 {
132         if (this.itime1 && this.itime2 && this.itime1 != this.itime2)
133         {
134                 float f = bound(0, (time - this.itime1) / (this.itime2 - this.itime1), 1 + autocvar_cl_lerpexcess);
135                 float f_1 = 1 - f;
136                 if (this.iflags & IFLAG_ORIGIN) setorigin(this, f_1 * this.iorigin1 + f * this.iorigin2);
137                 if (this.iflags & IFLAG_ANGLES)
138                 {
139                         vector forward = f_1 * this.iforward1 + f * this.iforward2;
140                         vector up = f_1 * this.iup1 + f * this.iup2;
141                         this.angles = fixedvectoangles2(forward, up);
142                 }
143                 if (this.iflags & IFLAG_V_ANGLE)
144                 {
145                         vector forward = f_1 * this.ivforward1 + f * this.ivforward2;
146                         vector up = f_1 * this.ivup1 + f * this.ivup2;
147                         this.v_angle = fixedvectoangles2(forward, up);
148                 }
149                 else if (this.iflags & IFLAG_V_ANGLE_X)
150                 {
151                         this.v_angle_x = f_1 * this.ivforward1.x + f * this.ivforward2.x;
152                 }
153                 if (this.iflags & IFLAG_VELOCITY) this.velocity = f_1 * this.ivelocity1 + f * this.ivelocity2;
154         }
155 }
156
157 /** snap origin to iorigin2 (actual origin) */
158 void InterpolateOrigin_Undo(entity this)
159 {
160         if (this.iflags & IFLAG_ORIGIN) setorigin(this, this.iorigin2);
161         if (this.iflags & IFLAG_ANGLES) this.angles = fixedvectoangles2(this.iforward2, this.iup2);
162         if (this.iflags & IFLAG_V_ANGLE) this.v_angle = fixedvectoangles2(this.ivforward2, this.ivup2);
163         else if (this.iflags & IFLAG_V_ANGLE_X) this.v_angle_x = this.ivforward2_x;
164         if (this.iflags & IFLAG_VELOCITY) this.velocity = this.ivelocity2;
165 }