Richard Boegli's CnC_Generals_Zero_Hour Fork WIP
This is documentation of Richard Boegil's Zero Hour Fork
 
Loading...
Searching...
No Matches
catmullromspline.cpp
Go to the documentation of this file.
1/*
2** Command & Conquer Generals Zero Hour(tm)
3** Copyright 2025 Electronic Arts Inc.
4**
5** This program is free software: you can redistribute it and/or modify
6** it under the terms of the GNU General Public License as published by
7** the Free Software Foundation, either version 3 of the License, or
8** (at your option) any later version.
9**
10** This program is distributed in the hope that it will be useful,
11** but WITHOUT ANY WARRANTY; without even the implied warranty of
12** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13** GNU General Public License for more details.
14**
15** You should have received a copy of the GNU General Public License
16** along with this program. If not, see <http://www.gnu.org/licenses/>.
17*/
18
19/***********************************************************************************************
20 *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
21 ***********************************************************************************************
22 * *
23 * Project Name : WWMath *
24 * *
25 * $Archive:: /Commando/Code/wwmath/catmullromspline.cpp $*
26 * *
27 * Author:: Greg Hjelstrom *
28 * *
29 * $Modtime:: 3/08/00 8:50p $*
30 * *
31 * $Revision:: 6 $*
32 * *
33 *---------------------------------------------------------------------------------------------*
34 * Functions: *
35 * CatmullRomSpline3DClass::Update_Tangents -- computes the tangents at each key *
36 * CatmullRomSpline3DClass::Get_Factory -- returns the factory for CatmullRomSpline3D *
37 * CatmullRomSpline3DClass::Save -- save this curve *
38 * CatmullRomSpline3DClass::Load -- load this curve *
39 * CatmullRomSpline1DClass::Update_Tangents -- Computes the tangents at each key *
40 * CatmullRomSpline1DClass::Get_Factory -- returns the factory for CatmullRomSpline1D *
41 * CatmullRomSpline1DClass::Save -- Save this curve *
42 * CatmullRomSpline1DClass::Load -- Load this curve *
43 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
44
45
46#include "catmullromspline.h"
47#include "persistfactory.h"
48#include "wwmathids.h"
49#include "wwhack.h"
50
51/*
52** Force-Link this module because the linker can't detect that we actually need it...
53*/
54DECLARE_FORCE_LINK(catmullromspline);
55
56/*
57** Save-Load stuff
58*/
61
62enum
63{
64 // ID's used by CatmullRomSpline3D
66
67 // ID's used by CatmullRomSpline1D
69};
70
71
72/*
73** Catmull-Rom 3D spline implementation
74*/
75
76/***********************************************************************************************
77 * CatmullRomSpline3DClass::Update_Tangents -- computes the tangents at each key *
78 * *
79 * INPUT: *
80 * *
81 * OUTPUT: *
82 * *
83 * WARNINGS: *
84 * I'm not sure about the tangents for the endpoints of the curve. *
85 * *
86 * HISTORY: *
87 * 3/7/2000 gth : Created. *
88 *=============================================================================================*/
90{
91 if (Keys.Count() < 2) {
92 for (int i=0; i<Keys.Count(); i++) {
93 Tangents[0].InTangent.Set(0,0,0);
94 Tangents[0].OutTangent.Set(0,0,0);
95 }
96 }
97
98 // first and last knot
99 int end = Keys.Count() - 1;
100 Tangents[0].InTangent.Set(0,0,0);
101 Tangents[end].OutTangent.Set(0,0,0);
102
103 if (IsLooping) {
104
105 // This really only works if the start and end points have the same position...
106 Tangents[0].OutTangent.X = 0.5f*(Keys[1].Point.X - Keys[end-1].Point.X);
107 Tangents[0].OutTangent.Y = 0.5f*(Keys[1].Point.Y - Keys[end-1].Point.Y);
108 Tangents[0].OutTangent.Z = 0.5f*(Keys[1].Point.Z - Keys[end-1].Point.Z);
109 Tangents[end].InTangent = Tangents[0].OutTangent;
110
111 } else {
112
113 // TODO: second derivative = 0... what is formula? I'm making this up...
114 Tangents[0].OutTangent.X = 0.25f*(Keys[1].Point.X - Keys[0].Point.X);
115 Tangents[0].OutTangent.Y = 0.25f*(Keys[1].Point.Y - Keys[0].Point.Y);
116 Tangents[0].OutTangent.Z = 0.25f*(Keys[1].Point.Z - Keys[0].Point.Z);
117
118 Tangents[end].InTangent.X = 0.25f*(Keys[end].Point.X - Keys[end-1].Point.X);
119 Tangents[end].InTangent.Y = 0.25f*(Keys[end].Point.Y - Keys[end-1].Point.Y);
120 Tangents[end].InTangent.Z = 0.25f*(Keys[end].Point.Z - Keys[end-1].Point.Z);
121
122 }
123
124 float total_time = (Keys[1].Time - Keys[0].Time) + (Keys[end].Time - Keys[end-1].Time);
125 float in_factor = 2.0f * (Keys[end].Time - Keys[end-1].Time) / total_time;
126 float out_factor = 2.0f * (Keys[1].Time - Keys[0].Time) / total_time;
127 Tangents[end].InTangent *= in_factor;
128 Tangents[0].OutTangent *= out_factor;
129
130 // inner knots
131 for (int i=1; i<Keys.Count()-1; i++) {
132 Tangents[i].InTangent.X = 0.5f*(Keys[i+1].Point.X - Keys[i-1].Point.X);
133 Tangents[i].InTangent.Y = 0.5f*(Keys[i+1].Point.Y - Keys[i-1].Point.Y);
134 Tangents[i].InTangent.Z = 0.5f*(Keys[i+1].Point.Z - Keys[i-1].Point.Z);
135 Tangents[i].OutTangent = Tangents[i].InTangent;
136
137 float in_factor = 2.0f * (Keys[i].Time - Keys[i-1].Time) / (Keys[i+1].Time - Keys[i-1].Time);
138 float out_factor = 2.0f * (Keys[i+1].Time - Keys[i].Time) / (Keys[i+1].Time - Keys[i-1].Time);
139 Tangents[i].InTangent *= in_factor; // compensating for the un-even keys
140 Tangents[i].OutTangent *= out_factor;
141 }
142 TangentsDirty = false;
143}
144
145
146/***********************************************************************************************
147 * CatmullRomSpline3DClass::Get_Factory -- returns the factory for CatmullRomSpline3D *
148 * *
149 * INPUT: *
150 * *
151 * OUTPUT: *
152 * *
153 * WARNINGS: *
154 * *
155 * HISTORY: *
156 * 3/7/2000 gth : Created. *
157 *=============================================================================================*/
162
163
164/***********************************************************************************************
165 * CatmullRomSpline3DClass::Save -- save this curve *
166 * *
167 * INPUT: *
168 * *
169 * OUTPUT: *
170 * *
171 * WARNINGS: *
172 * *
173 * HISTORY: *
174 * 3/7/2000 gth : Created. *
175 *=============================================================================================*/
177{
180 csave.End_Chunk();
181 return true;
182}
183
184
185/***********************************************************************************************
186 * CatmullRomSpline3DClass::Load -- load this curve *
187 * *
188 * INPUT: *
189 * *
190 * OUTPUT: *
191 * *
192 * WARNINGS: *
193 * *
194 * HISTORY: *
195 * 3/7/2000 gth : Created. *
196 *=============================================================================================*/
198{
199 while (cload.Open_Chunk()) {
200
201 switch(cload.Cur_Chunk_ID())
202 {
205 break;
206
207 default:
208 WWDEBUG_SAY(("Unhandled Chunk: 0x%X File: %s Line: %d\r\n",__FILE__,__LINE__));
209 break;
210 }
211 cload.Close_Chunk();
212 }
213
214 return true;
215}
216
217
218/*
219** The 1D Catmull-Rom implementation.
220*/
221
222
223/***********************************************************************************************
224 * CatmullRomSpline1DClass::Update_Tangents -- Computes the tangents at each key *
225 * *
226 * INPUT: *
227 * *
228 * OUTPUT: *
229 * *
230 * WARNINGS: *
231 * *
232 * HISTORY: *
233 * 3/7/2000 gth : Created. *
234 *=============================================================================================*/
236{
237 if (Keys.Count() < 2) {
238 for (int i=0; i<Keys.Count(); i++) {
239 Tangents[i].InTangent = 0.0f;
240 Tangents[i].OutTangent = 0.0f;
241 }
242 return;
243 }
244
245 // first and last knot
246 int end = Keys.Count() - 1;
247 Tangents[0].InTangent = 0.0f;
248 Tangents[end].OutTangent = 0.0f;
249
250 if (IsLooping) {
251
252 // This really only works if the start and end points have the same position...
253 Tangents[0].OutTangent = 0.5f*(Keys[1].Point - Keys[end-1].Point);
254 Tangents[end].InTangent = Tangents[0].OutTangent;
255
256 } else {
257
258 // TODO: second derivative = 0... what is formula? I'm making this up...
259 Tangents[0].OutTangent = 0.25f*(Keys[1].Point - Keys[0].Point);
260
261 Tangents[end].InTangent = 0.25f*(Keys[end].Point - Keys[end-1].Point);
262
263 }
264
265 float total_time = (Keys[1].Time - Keys[0].Time) + (Keys[end].Time - Keys[end-1].Time);
266 float in_factor = 2.0f * (Keys[end].Time - Keys[end-1].Time) / total_time;
267 float out_factor = 2.0f * (Keys[1].Time - Keys[0].Time) / total_time;
268 Tangents[end].InTangent *= in_factor;
269 Tangents[0].OutTangent *= out_factor;
270
271 // inner knots
272 for (int i=1; i<Keys.Count()-1; i++) {
273 Tangents[i].InTangent = 0.5f*(Keys[i+1].Point - Keys[i-1].Point);
274 Tangents[i].OutTangent = Tangents[i].InTangent;
275
276 float in_factor = 2.0f * (Keys[i].Time - Keys[i-1].Time) / (Keys[i+1].Time - Keys[i-1].Time);
277 float out_factor = 2.0f * (Keys[i+1].Time - Keys[i].Time) / (Keys[i+1].Time - Keys[i-1].Time);
278 Tangents[i].InTangent *= in_factor; // compensating for the un-even keys
279 Tangents[i].OutTangent *= out_factor;
280 }
281 TangentsDirty = false;
282}
283
284
285/***********************************************************************************************
286 * CatmullRomSpline1DClass::Get_Factory -- returns the factory for CatmullRomSpline1D *
287 * *
288 * INPUT: *
289 * *
290 * OUTPUT: *
291 * *
292 * WARNINGS: *
293 * *
294 * HISTORY: *
295 * 3/7/2000 gth : Created. *
296 *=============================================================================================*/
301
302
303/***********************************************************************************************
304 * CatmullRomSpline1DClass::Save -- Save this curve *
305 * *
306 * INPUT: *
307 * *
308 * OUTPUT: *
309 * *
310 * WARNINGS: *
311 * *
312 * HISTORY: *
313 * 3/7/2000 gth : Created. *
314 *=============================================================================================*/
316{
319 csave.End_Chunk();
320 return true;
321}
322
323
324/***********************************************************************************************
325 * CatmullRomSpline1DClass::Load -- Load this curve *
326 * *
327 * INPUT: *
328 * *
329 * OUTPUT: *
330 * *
331 * WARNINGS: *
332 * *
333 * HISTORY: *
334 * 3/7/2000 gth : Created. *
335 *=============================================================================================*/
337{
338 while (cload.Open_Chunk()) {
339
340 switch(cload.Cur_Chunk_ID())
341 {
344 break;
345
346 default:
347 WWDEBUG_SAY(("Unhandled Chunk: 0x%X File: %s Line: %d\r\n",__FILE__,__LINE__));
348 break;
349 }
350 cload.Close_Chunk();
351 }
352
353 return true;
354}
@ CATMULLROM3D_CHUNK_HERMITE3D
@ CATMULLROM1D_CHUNK_HERMITE1D
SimplePersistFactoryClass< CatmullRomSpline3DClass, WWMATH_CHUNKID_CATMULLROMSPLINE3D > _CatmullRomSpline3DFactory
SimplePersistFactoryClass< CatmullRomSpline1DClass, WWMATH_CHUNKID_CATMULLROMSPLINE1D > _CatmullRomSpline1DFactory
virtual const PersistFactoryClass & Get_Factory(void) const
virtual bool Load(ChunkLoadClass &cload)
virtual bool Save(ChunkSaveClass &csave)
virtual bool Load(ChunkLoadClass &cload)
virtual bool Save(ChunkSaveClass &csave)
virtual const PersistFactoryClass & Get_Factory(void) const
bool Close_Chunk()
Definition chunkio.cpp:448
uint32 Cur_Chunk_ID()
Definition chunkio.cpp:484
bool Open_Chunk()
Definition chunkio.cpp:412
bool Begin_Chunk(uint32 id)
Definition chunkio.cpp:108
bool End_Chunk()
Definition chunkio.cpp:148
bool IsLooping
Definition curve.h:162
DynamicVectorClass< KeyClass > Keys
Definition curve.h:163
bool IsLooping
Definition curve.h:103
DynamicVectorClass< KeyClass > Keys
Definition curve.h:104
DynamicVectorClass< TangentsClass > Tangents
virtual bool Load(ChunkLoadClass &cload)
virtual bool Save(ChunkSaveClass &csave)
virtual bool Save(ChunkSaveClass &csave)
virtual bool Load(ChunkLoadClass &cload)
DynamicVectorClass< TangentsClass > Tangents
#define WWDEBUG_SAY(x)
Definition wwdebug.h:114
#define DECLARE_FORCE_LINK(module)
Definition wwhack.h:48