Richard Boegli's CnC_Generals_Zero_Hour Fork WIP
This is documentation of Richard Boegil's Zero Hour Fork
 
Loading...
Searching...
No Matches
sr_util.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/* $Header: /Commando/Code/ww3d2/sr_util.cpp 3 2/06/01 6:18p Greg_h $ */
20/***********************************************************************************************
21 *** Confidential - Westwood Studios ***
22 ***********************************************************************************************
23 * *
24 * Project Name : Commando / G 3D Library *
25 * *
26 * $Archive:: /Commando/Code/ww3d2/sr_util.cpp $*
27 * *
28 * Author:: Greg_h *
29 * *
30 * $Modtime:: 2/06/01 2:51p $*
31 * *
32 * $Revision:: 3 $*
33 * *
34 *---------------------------------------------------------------------------------------------*
35 * Functions: *
36 * Set_SR_Transform -- copies our object transform into a Surrender object *
37 * Set_SR_Camera_Transform -- copies our camera transform into a Surrender object *
38 * Get_SR_Camera_Transform -- creates a Matrix3D from a surrender camera transform *
39 * Get_SR_Transform -- Creates a Matrix3D from a surrender object transform *
40 * Get_Camera_Frustum_Corners -- Returns 8 camera frustum corner points. *
41 * Get_ZClamped_Camera_Frustum_Corners -- Gets zclamped frustum corners. *
42 * Push_Multiply_Westwood_Matrix -- push and multiply a matrix into the gerd *
43 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
44
45#include "sr_util.h"
46#include "wwdebug.h"
47#include "camera.h"
48#include "matrix4.h"
49
50#ifdef WW3D_DX8
51
52#include <srNode.hpp>
53#include <srCamera.hpp>
54#include <srMeshModel.hpp>
55#include <srGERD.hpp>
56
57/***********************************************************************************************
58 * Set_SR_Transform -- copies our object transform into a Surrender object *
59 * *
60 * INPUT: *
61 * *
62 * OUTPUT: *
63 * *
64 * WARNINGS: *
65 * *
66 * HISTORY: *
67 * 08/11/1997 GH : Created. *
68 *=============================================================================================*/
69void Set_SR_Transform(srNode * obj,const Matrix3D & tm)
70{
71
72 srMatrix3 srtm;
73
74 obj->setLocation(tm[0][3], tm[1][3], tm[2][3]);
75
76 srtm[0][0] = tm[0][0];
77 srtm[0][1] = tm[0][1];
78 srtm[0][2] = tm[0][2];
79
80 srtm[1][0] = tm[1][0];
81 srtm[1][1] = tm[1][1];
82 srtm[1][2] = tm[1][2];
83
84 srtm[2][0] = tm[2][0];
85 srtm[2][1] = tm[2][1];
86 srtm[2][2] = tm[2][2];
87
88 obj->setRotation(srtm);
89}
90
91
92/***********************************************************************************************
93 * Get_SR_Transform -- Creates a Matrix3D from a surrender object transform *
94 * *
95 * INPUT: *
96 * *
97 * OUTPUT: *
98 * *
99 * WARNINGS: *
100 * *
101 * HISTORY: *
102 * 11/3/97 GTH : Created. *
103 *=============================================================================================*/
104Matrix3D Get_SR_Transform(srNode * obj)
105{
106 Matrix3D tm;
107 srVector3 pos = obj->getLocation();
108 srMatrix3 rot;
109 obj->getRotation(rot);
110
111 tm[0][3] = pos[0];
112 tm[1][3] = pos[1];
113 tm[2][3] = pos[2];
114
115 tm[0][0] = rot[0][0];
116 tm[0][1] = rot[0][1];
117 tm[0][2] = rot[0][2];
118
119 tm[1][0] = rot[1][0];
120 tm[1][1] = rot[1][1];
121 tm[1][2] = rot[1][2];
122
123 tm[2][0] = rot[2][0];
124 tm[2][1] = rot[2][1];
125 tm[2][2] = rot[2][2];
126
127 return(tm);
128}
129
130/***********************************************************************************************
131 * Set_SR_Camera_Transform -- copies our camera transform into a Surrender object *
132 * *
133 * INPUT: *
134 * *
135 * OUTPUT: *
136 * *
137 * WARNINGS: *
138 * *
139 * HISTORY: *
140 * 08/11/1997 GH : Created. *
141 *=============================================================================================*/
142void Set_SR_Camera_Transform(srCamera * obj,const Matrix3D & transform)
143{
144 srMatrix3 srtm;
145 Matrix3D tm = transform;
146
147 obj->setLocation(tm[0][3], tm[1][3], tm[2][3]);
148
149 srtm[0][0] = tm[0][0];
150 srtm[0][1] = tm[0][1];
151 srtm[0][2] = -tm[0][2];
152
153 srtm[1][0] = tm[1][0];
154 srtm[1][1] = tm[1][1];
155 srtm[1][2] = -tm[1][2];
156
157 srtm[2][0] = tm[2][0];
158 srtm[2][1] = tm[2][1];
159 srtm[2][2] = -tm[2][2];
160
161 obj->setRotation(srtm);
162}
163
164
165/***********************************************************************************************
166 * Get_SR_Camera_Transform -- creates a Matrix3D from a surrender camera transform *
167 * *
168 * INPUT: *
169 * *
170 * OUTPUT: *
171 * *
172 * WARNINGS: *
173 * *
174 * HISTORY: *
175 * 11/3/97 GTH : Created. *
176 *=============================================================================================*/
177Matrix3D Get_SR_Camera_Transform(srCamera * obj)
178{
179 Matrix3D tm;
180
181 tm[0][3] = obj->getLocationX();
182 tm[1][3] = obj->getLocationY();
183 tm[2][3] = obj->getLocationZ();
184
185 srMatrix3 srtm;
186 obj->getRotation(srtm);
187
188 tm[0][0] = srtm[0][0];
189 tm[0][1] = srtm[0][1];
190 tm[0][2] = -srtm[0][2];
191
192 tm[1][0] = srtm[1][0];
193 tm[1][1] = srtm[1][1];
194 tm[1][2] = -srtm[1][2];
195
196 tm[2][0] = srtm[2][0];
197 tm[2][1] = srtm[2][1];
198 tm[2][2] = -srtm[2][2];
199
200 return tm;
201}
202
203
204/***********************************************************************************************
205 * Push_Multiply_Westwood_Matrix -- push and multiply a matrix into the gerd *
206 * *
207 * INPUT: *
208 * *
209 * OUTPUT: *
210 * *
211 * WARNINGS: *
212 * *
213 * HISTORY: *
214 * 12/10/98 GTH : Created. *
215 *=============================================================================================*/
216void Push_Multiply_Westwood_Matrix(srGERD * gerd,const Matrix3D & tm)
217{
218 WWASSERT(gerd);
219 gerd->matrixMode(srGERD::MODELVIEW);
220
221 srMatrix4x3 srtm;
222 Convert_Westwood_Matrix(tm,&srtm);
223 gerd->pushMultMatrix(srtm);
224}
225
226
227void Convert_Westwood_Matrix(const Matrix3D & tm,srMatrix4 * set_sr_tm)
228{
229 (*set_sr_tm)[0][0] = tm[0][0];
230 (*set_sr_tm)[0][1] = tm[0][1];
231 (*set_sr_tm)[0][2] = tm[0][2];
232 (*set_sr_tm)[0][3] = tm[0][3];
233
234 (*set_sr_tm)[1][0] = tm[1][0];
235 (*set_sr_tm)[1][1] = tm[1][1];
236 (*set_sr_tm)[1][2] = tm[1][2];
237 (*set_sr_tm)[1][3] = tm[1][3];
238
239 (*set_sr_tm)[2][0] = tm[2][0];
240 (*set_sr_tm)[2][1] = tm[2][1];
241 (*set_sr_tm)[2][2] = tm[2][2];
242 (*set_sr_tm)[2][3] = tm[2][3];
243
244 (*set_sr_tm)[3][0] = 0.0f;
245 (*set_sr_tm)[3][1] = 0.0f;
246 (*set_sr_tm)[3][2] = 0.0f;
247 (*set_sr_tm)[3][3] = 1.0f;
248}
249
250void Convert_Westwood_Matrix(const Matrix3D & wtm,srMatrix4d * set_sr_tm)
251{
252 (*set_sr_tm)[0][0] = wtm[0][0];
253 (*set_sr_tm)[0][1] = wtm[0][1];
254 (*set_sr_tm)[0][2] = wtm[0][2];
255 (*set_sr_tm)[0][3] = wtm[0][3];
256
257 (*set_sr_tm)[1][0] = wtm[1][0];
258 (*set_sr_tm)[1][1] = wtm[1][1];
259 (*set_sr_tm)[1][2] = wtm[1][2];
260 (*set_sr_tm)[1][3] = wtm[1][3];
261
262 (*set_sr_tm)[2][0] = wtm[2][0];
263 (*set_sr_tm)[2][1] = wtm[2][1];
264 (*set_sr_tm)[2][2] = wtm[2][2];
265 (*set_sr_tm)[2][3] = wtm[2][3];
266
267 (*set_sr_tm)[3][0] = 0.0;
268 (*set_sr_tm)[3][1] = 0.0;
269 (*set_sr_tm)[3][2] = 0.0;
270 (*set_sr_tm)[3][3] = 1.0;
271}
272
273void Convert_Westwood_Matrix(const Matrix3D & wtm,srMatrix4x3 * set_sr_tm)
274{
275 (*set_sr_tm)[0][0] = wtm[0][0];
276 (*set_sr_tm)[0][1] = wtm[0][1];
277 (*set_sr_tm)[0][2] = wtm[0][2];
278 (*set_sr_tm)[0][3] = wtm[0][3];
279
280 (*set_sr_tm)[1][0] = wtm[1][0];
281 (*set_sr_tm)[1][1] = wtm[1][1];
282 (*set_sr_tm)[1][2] = wtm[1][2];
283 (*set_sr_tm)[1][3] = wtm[1][3];
284
285 (*set_sr_tm)[2][0] = wtm[2][0];
286 (*set_sr_tm)[2][1] = wtm[2][1];
287 (*set_sr_tm)[2][2] = wtm[2][2];
288 (*set_sr_tm)[2][3] = wtm[2][3];
289}
290
291void Convert_Westwood_Matrix(const Matrix3D & wtm,srMatrix3 * set_sr_tm,srVector3 * set_sr_translation)
292{
293 (*set_sr_tm)[0][0] = wtm[0][0];
294 (*set_sr_tm)[0][1] = wtm[0][1];
295 (*set_sr_tm)[0][2] = wtm[0][2];
296 (*set_sr_translation)[0] = wtm[0][3];
297
298 (*set_sr_tm)[1][0] = wtm[1][0];
299 (*set_sr_tm)[1][1] = wtm[1][1];
300 (*set_sr_tm)[1][2] = wtm[1][2];
301 (*set_sr_translation)[1] = wtm[1][3];
302
303 (*set_sr_tm)[2][0] = wtm[2][0];
304 (*set_sr_tm)[2][1] = wtm[2][1];
305 (*set_sr_tm)[2][2] = wtm[2][2];
306 (*set_sr_translation)[2] = wtm[2][3];
307}
308
309void Convert_Westwood_Matrix(const Matrix4 & wtm,srMatrix4 * set_sr_tm)
310{
311 (*set_sr_tm)[0][0] = wtm[0][0];
312 (*set_sr_tm)[0][1] = wtm[0][1];
313 (*set_sr_tm)[0][2] = wtm[0][2];
314 (*set_sr_tm)[0][3] = wtm[0][3];
315
316 (*set_sr_tm)[1][0] = wtm[1][0];
317 (*set_sr_tm)[1][1] = wtm[1][1];
318 (*set_sr_tm)[1][2] = wtm[1][2];
319 (*set_sr_tm)[1][3] = wtm[1][3];
320
321 (*set_sr_tm)[2][0] = wtm[2][0];
322 (*set_sr_tm)[2][1] = wtm[2][1];
323 (*set_sr_tm)[2][2] = wtm[2][2];
324 (*set_sr_tm)[2][3] = wtm[2][3];
325
326 (*set_sr_tm)[3][0] = wtm[3][0];
327 (*set_sr_tm)[3][1] = wtm[3][1];
328 (*set_sr_tm)[3][2] = wtm[3][2];
329 (*set_sr_tm)[3][3] = wtm[3][3];
330}
331
332void Convert_Surrender_Matrix(const srMatrix4 & srtm,Matrix3D * set_w3d_tm)
333{
334 (*set_w3d_tm)[0][0] = srtm[0][0];
335 (*set_w3d_tm)[0][1] = srtm[0][1];
336 (*set_w3d_tm)[0][2] = srtm[0][2];
337 (*set_w3d_tm)[0][3] = srtm[0][3];
338
339 (*set_w3d_tm)[1][0] = srtm[1][0];
340 (*set_w3d_tm)[1][1] = srtm[1][1];
341 (*set_w3d_tm)[1][2] = srtm[1][2];
342 (*set_w3d_tm)[1][3] = srtm[1][3];
343
344 (*set_w3d_tm)[2][0] = srtm[2][0];
345 (*set_w3d_tm)[2][1] = srtm[2][1];
346 (*set_w3d_tm)[2][2] = srtm[2][2];
347 (*set_w3d_tm)[2][3] = srtm[2][3];
348}
349
350void Convert_Surrender_Matrix(const srMatrix4x3 & srtm,Matrix3D * set_w3d_tm)
351{
352 (*set_w3d_tm)[0][0] = srtm[0][0];
353 (*set_w3d_tm)[0][1] = srtm[0][1];
354 (*set_w3d_tm)[0][2] = srtm[0][2];
355 (*set_w3d_tm)[0][3] = srtm[0][3];
356
357 (*set_w3d_tm)[1][0] = srtm[1][0];
358 (*set_w3d_tm)[1][1] = srtm[1][1];
359 (*set_w3d_tm)[1][2] = srtm[1][2];
360 (*set_w3d_tm)[1][3] = srtm[1][3];
361
362 (*set_w3d_tm)[2][0] = srtm[2][0];
363 (*set_w3d_tm)[2][1] = srtm[2][1];
364 (*set_w3d_tm)[2][2] = srtm[2][2];
365 (*set_w3d_tm)[2][3] = srtm[2][3];
366}
367
368void Multiply_Westwood_And_Surrender_Matrix(const Matrix3D& n,const srMatrix4& m,srMatrix4& srtm_d)
369{
370 srtm_d[0].make(m[0][0]*n[0][0] + m[0][1]*n[1][0] + m[0][2]*n[2][0],
371 m[0][0]*n[0][1] + m[0][1]*n[1][1] + m[0][2]*n[2][1],
372 m[0][0]*n[0][2] + m[0][1]*n[1][2] + m[0][2]*n[2][2],
373 m[0][0]*n[0][3] + m[0][1]*n[1][3] + m[0][2]*n[2][3] + m[0][3]);
374
375 srtm_d[1].make(m[1][0]*n[0][0] + m[1][1]*n[1][0] + m[1][2]*n[2][0],
376 m[1][0]*n[0][1] + m[1][1]*n[1][1] + m[1][2]*n[2][1],
377 m[1][0]*n[0][2] + m[1][1]*n[1][2] + m[1][2]*n[2][2],
378 m[1][0]*n[0][3] + m[1][1]*n[1][3] + m[1][2]*n[2][3] + m[1][3]);
379
380 srtm_d[2].make(m[2][0]*n[0][0] + m[2][1]*n[1][0] + m[2][2]*n[2][0],
381 m[2][0]*n[0][1] + m[2][1]*n[1][1] + m[2][2]*n[2][1],
382 m[2][0]*n[0][2] + m[2][1]*n[1][2] + m[2][2]*n[2][2],
383 m[2][0]*n[0][3] + m[2][1]*n[1][3] + m[2][2]*n[2][3] + m[2][3]);
384
385 srtm_d[3].make(m[3][0]*n[0][0] + m[3][1]*n[1][0] + m[3][2]*n[2][0],
386 m[3][0]*n[0][1] + m[3][1]*n[1][1] + m[3][2]*n[2][1],
387 m[3][0]*n[0][2] + m[3][1]*n[1][2] + m[3][2]*n[2][2],
388 m[3][0]*n[0][3] + m[3][1]*n[1][3] + m[3][2]*n[2][3] + m[3][3]);
389}
390
391/**************************************************************************
392 * Get_Camera_Frustum_Corners -- Returns 8 camera frustum corner points. *
393 * *
394 * INPUT: CameraClass * camera - camera. *
395 * *
396 * OUTPUT: (parameter) Vector3 points[8] - array of corner points. *
397 * *
398 * WARNINGS: points must be an array of length 8 at least, or bad *
399 * things will happen (this is not checked by the compiler). *
400 * *
401 * HISTORY: *
402 * 01/18/1998 NH : Created. *
403 * 04/13/1998 NH : Modified for SR 1.3. *
404 *========================================================================*/
405void Get_Camera_Frustum_Corners(const CameraClass * camera, Vector3 points[8])
406{
407 // Generate the camera-space frustum corner points by linearly
408 // extrapolating the viewplane to the near and far z clipping planes.
409
410 // The camera frustum corner points are defined in the following order:
411 // When looking at the frustum from the position of the camera, the near four points are
412 // numbered: upper left 0, upper right 1, lower left 2, lower right 3. The far plane's
413 // points are numbered from 4 to 7 in an analogous fashion.
414 // (remember: the camera space has x going to the right, y up and z backwards).
415 Vector2 vpmin, vpmax;
416 double znear, zfar;
417 camera->Get_View_Plane(vpmin, vpmax); // Normalized view plane at a depth of 1.0
418 camera->Get_Clip_Planes(znear, zfar);
419
420 // Forward is negative Z in our viewspace coordinate system.
421 znear = -znear;
422 zfar = -zfar;
423
424 points[0].Set(vpmin.X, vpmax.Y, 1.0);
425 points[4] = points[0];
426 points[0] *= znear;
427 points[4] *= zfar;
428 points[1].Set(vpmax.X, vpmax.Y, 1.0);
429 points[5] = points[1];
430 points[1] *= znear;
431 points[5] *= zfar;
432 points[2].Set(vpmin.X, vpmin.Y, 1.0);
433 points[6] = points[2];
434 points[2] *= znear;
435 points[6] *= zfar;
436 points[3].Set(vpmax.X, vpmin.Y, 1.0);
437 points[7] = points[3];
438 points[3] *= znear;
439 points[7] *= zfar;
440
441 // Transform the eight corners of the view frustum from camera space to world space.
442 Matrix3D cam_mat = camera->Get_Transform();
443 for (int i = 0; i < 8; i++) {
444 Matrix3D::Transform_Vector(cam_mat, points[i], &(points[i]));
445 }
446
447}
448
449
450/**************************************************************************
451 * Get_ZClamped_Camera_Frustum_Corners -- Gets zclamped frustum corners. *
452 * *
453 * INPUT: CameraClass * camera - camera. *
454 * float minz, maxz - depth clamps on frustum. *
455 * *
456 * OUTPUT: (parameter) Vector3 points[8] - array of corner points. *
457 * returns false of the intersection between the clamped range *
458 * and the frustum is empty. *
459 * *
460 * WARNINGS: points must be an array of length 8 at least, or bad *
461 * things will happen (this is not checked by the compiler). *
462 * *
463 * HISTORY: *
464 * 11/18/1998 NH : Re-Created. *
465 *========================================================================*/
467 Vector3 points[8], float minz, float maxz)
468{
469 int i;
470
471 // (remember: the camera space has x going to the right, y up and z backwards).
472 Vector2 vpmin, vpmax;
473 double znear, zfar;
474 camera->Get_View_Plane(vpmin, vpmax); // Normalized view plane at a depth of 1.0
475 camera->Get_Clip_Planes(znear, zfar);
476
477 // Clamp znear, zfar by minz, maxz:
478 if (minz > zfar || maxz < znear) {
479 return false;
480 }
481 float startz = minz > znear ? minz : znear;
482 float endz = maxz < zfar ? maxz : zfar;
483
484
485 // Forward is negative Z in our viewspace coordinate system.
486 znear = -startz;
487 zfar = -endz;
488
489 points[0].Set(vpmin.X, vpmax.Y, 1.0);
490 points[4] = points[0];
491 points[0] *= znear;
492 points[4] *= zfar;
493 points[1].Set(vpmax.X, vpmax.Y, 1.0);
494 points[5] = points[1];
495 points[1] *= znear;
496 points[5] *= zfar;
497 points[2].Set(vpmin.X, vpmin.Y, 1.0);
498 points[6] = points[2];
499 points[2] *= znear;
500 points[6] *= zfar;
501 points[3].Set(vpmax.X, vpmin.Y, 1.0);
502 points[7] = points[3];
503 points[3] *= znear;
504 points[7] *= zfar;
505
506 // Transform the eight corners of the view frustum from camera space to world space.
507 Matrix3D cam_mat = camera->Get_Transform();
508 for (i = 0; i < 8; i++) {
509 Matrix3D::Transform_Vector(cam_mat, points[i], &(points[i]));
510 }
511
512 return true;
513}
514
515
516
517#endif //WW3D_DX8
#define WWASSERT
void Get_View_Plane(Vector2 &set_min, Vector2 &set_max) const
Definition camera.cpp:380
void Get_Clip_Planes(float &znear, float &zfar) const
Definition camera.cpp:749
static WWINLINE void Transform_Vector(const Matrix3D &tm, const Vector3 &in, Vector3 *out)
Definition matrix3d.h:1742
const Matrix3D & Get_Transform(void) const
Definition rendobj.h:617
float Y
Definition vector2.h:79
float X
Definition vector2.h:74
WWINLINE void Set(float x, float y, float z)
Definition vector3.h:103
void Push_Multiply_Westwood_Matrix(srGERD *gerd, const Matrix3D &tm)
void Convert_Westwood_Matrix(const Matrix3D &wtm, srMatrix4 *set_sr_tm)
bool Get_ZClamped_Camera_Frustum_Corners(const CameraClass *camera, Vector3 points[8], float minz, float maxz)
void Multiply_Westwood_And_Surrender_Matrix(const Matrix3D &w3d_tm, const srMatrix4 &srtm_s, srMatrix4 &srtm_d)
void Get_Camera_Frustum_Corners(const CameraClass *camera, Vector3 points[8])
void Set_SR_Camera_Transform(srCamera *obj, const Matrix3D &transform)
void Convert_Surrender_Matrix(const srMatrix4 &srtm, Matrix3D *set_w3d_tm)
void Set_SR_Transform(srNode *obj, const Matrix3D &tm)
Matrix3D Get_SR_Camera_Transform(srCamera *obj)
Matrix3D Get_SR_Transform(srNode *obj)