Richard Boegli's CnC_Generals_Zero_Hour Fork WIP
This is documentation of Richard Boegil's Zero Hour Fork
 
Loading...
Searching...
No Matches
frustum.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/frustum.cpp $*
26 * *
27 * Author:: Greg Hjelstrom *
28 * *
29 * $Modtime:: 4/01/01 12:47p $*
30 * *
31 * $Revision:: 5 $*
32 * *
33 *---------------------------------------------------------------------------------------------*
34 * Functions: *
35 * FrustumClass::Init -- Initialize a frustum object *
36 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
37
38#include "frustum.h"
39
40
41/***********************************************************************************************
42 * FrustumClass::Init -- Initialize a frustum object *
43 * *
44 * This function initializes a frustum from the description of a camera *
45 * *
46 * INPUT: *
47 * camera - camera transform, note that the camera looks down the -Z axis *
48 * vpmin - min corner of the z=-1.0 view plane (not necessarily the near clip plane) *
49 * vpmax - max corner of the z=-1.0 view plane (not necessarily the near clip plane) *
50 * znear - near clip plane (should be negative, negated if it is not) *
51 * zfar - far clip plane (should be negative, negated if it is not) *
52 * *
53 * OUTPUT: *
54 * *
55 * WARNINGS: *
56 * The vpmin and vpmax variables are the min and max of a view-plane at z=-1.0 *
57 * *
58 * *
59 * HISTORY: *
60 * 2/17/2000 gth : Created. *
61 *=============================================================================================*/
63(
64 const Matrix3D & camera,
65 const Vector2 & vpmin,
66 const Vector2 & vpmax,
67 float znear,
68 float zfar
69)
70{
71 int i;
72
73 // Store the camera transform
74 CameraTransform = camera;
75
76 // Forward is negative Z in our viewspace coordinate system.
77 // Just flip the sign if the user passed in positive values.
78 if ((znear > 0.0f) && (zfar > 0.0f)) {
79 znear = -znear;
80 zfar = -zfar;
81 }
82
83 // Calculate the corners of the camera frustum.
84 // Generate the camera-space frustum corners by linearly
85 // extrapolating the viewplane to the near and far z clipping planes.
86
87 // The camera frustum corners are defined in the following order:
88 // When looking at the frustum from the position of the camera, the near four corners are
89 // numbered: upper left 0, upper right 1, lower left 2, lower right 3. The far plane's
90 // Frustum corners are numbered from 4 to 7 in an analogous fashion.
91 // (remember: the camera space has x going to the right, y up and z backwards).
92
93 //calculate a proper z-vector assuming our right-handed coordinate system
94 Vector3 zv;
95 Vector3::Cross_Product(CameraTransform.Get_X_Vector(),CameraTransform.Get_Y_Vector(),&zv);
96
97 //compare correct z-vector with the one in the camera matrix. If they point in
98 //opposite directions, we have a reflected camera matrix.
99 if (Vector3::Dot_Product(CameraTransform.Get_Z_Vector(),zv) < 0)
100 { //flip the frustum corners horizontally for a reflected matrix
101 Corners[1].Set(vpmin.X, vpmax.Y, 1.0);
102 Corners[5] = Corners[1];
103 Corners[1] *= znear;
104 Corners[5] *= zfar;
105 Corners[0].Set(vpmax.X, vpmax.Y, 1.0);
106 Corners[4] = Corners[0];
107 Corners[0] *= znear;
108 Corners[4] *= zfar;
109 Corners[3].Set(vpmin.X, vpmin.Y, 1.0);
110 Corners[7] = Corners[3];
111 Corners[3] *= znear;
112 Corners[7] *= zfar;
113 Corners[2].Set(vpmax.X, vpmin.Y, 1.0);
114 Corners[6] = Corners[2];
115 Corners[2] *= znear;
116 Corners[6] *= zfar;
117 }
118 else
119 { //normal camera
120 Corners[0].Set(vpmin.X, vpmax.Y, 1.0);
121 Corners[4] = Corners[0];
122 Corners[0] *= znear;
123 Corners[4] *= zfar;
124 Corners[1].Set(vpmax.X, vpmax.Y, 1.0);
125 Corners[5] = Corners[1];
126 Corners[1] *= znear;
127 Corners[5] *= zfar;
128 Corners[2].Set(vpmin.X, vpmin.Y, 1.0);
129 Corners[6] = Corners[2];
130 Corners[2] *= znear;
131 Corners[6] *= zfar;
132 Corners[3].Set(vpmax.X, vpmin.Y, 1.0);
133 Corners[7] = Corners[3];
134 Corners[3] *= znear;
135 Corners[7] *= zfar;
136 }
137
138
139 // Transform the eight corners of the view frustum from camera space to world space.
140 for (i = 0; i < 8; i++) {
142 }
143
144 // Create the six frustum bounding planes from the eight corner Corners.
145 // The bounding planes are oriented so that their normals point outward
146 PlaneClass frustum_planes[6];
147 Planes[0].Set(Corners[0], Corners[3], Corners[1]); // near
148 Planes[1].Set(Corners[0], Corners[5], Corners[4]); // bottom
149 Planes[2].Set(Corners[0], Corners[6], Corners[2]); // right
150 Planes[3].Set(Corners[2], Corners[7], Corners[3]); // top
151 Planes[4].Set(Corners[1], Corners[7], Corners[5]); // left
152 Planes[5].Set(Corners[4], Corners[7], Corners[6]); // far
153
154 // find the bounding box of the entire frustum (may be used for sloppy quick rejection)
156
157 for (i=1; i<8;i++) {
158 if (Corners[i].X < BoundMin.X) BoundMin.X = Corners[i].X;
159 if (Corners[i].X > BoundMax.X) BoundMax.X = Corners[i].X;
160
161 if (Corners[i].Y < BoundMin.Y) BoundMin.Y = Corners[i].Y;
162 if (Corners[i].Y > BoundMax.Y) BoundMax.Y = Corners[i].Y;
163
164 if (Corners[i].Z < BoundMin.Z) BoundMin.Z = Corners[i].Z;
165 if (Corners[i].Z > BoundMax.Z) BoundMax.Z = Corners[i].Z;
166 }
167}
168
Matrix3D CameraTransform
Definition frustum.h:63
Vector3 BoundMax
Definition frustum.h:67
void Init(const Matrix3D &camera, const Vector2 &viewport_min, const Vector2 &viewport_max, float znear, float zfar)
Definition frustum.cpp:63
Vector3 Corners[8]
Definition frustum.h:65
PlaneClass Planes[6]
Definition frustum.h:64
Vector3 BoundMin
Definition frustum.h:66
static WWINLINE void Transform_Vector(const Matrix3D &tm, const Vector3 &in, Vector3 *out)
Definition matrix3d.h:1742
float Y
Definition vector2.h:79
float X
Definition vector2.h:74
static WWINLINE float Dot_Product(const Vector3 &a, const Vector3 &b)
Definition vector3.h:293
static WWINLINE void Cross_Product(const Vector3 &a, const Vector3 &b, Vector3 *result)
Definition vector3.h:374