Richard Boegli's CnC_Generals_Zero_Hour Fork WIP
This is documentation of Richard Boegil's Zero Hour Fork
 
Loading...
Searching...
No Matches
tri.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/tri.cpp $*
26 * *
27 * Author:: Greg Hjelstrom *
28 * *
29 * $Modtime:: 5/03/01 3:41p $*
30 * *
31 * $Revision:: 8 $*
32 * *
33 *---------------------------------------------------------------------------------------------*
34 * Functions: *
35 * TriClass::Find_Dominant_Plane -- returns indices of the axes of the dominant plane *
36 * TriClass::Contains_Point -- performs 2D point-in-triangle test. *
37 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
38
39#include "tri.h"
40#include "vector2.h"
41
42
43struct FDPRec
44{
45 int axis1;
46 int axis2;
47 int axis3;
48};
49
50static inline void find_dominant_plane_fast(const TriClass & tri, FDPRec& info)
51{
52 static const FDPRec dominance[3] =
53 {
54 { 1, 2, 0 }, // Dominant is the X axis
55 { 0, 2, 1 }, // Dominant is the Y axis
56 { 0, 1, 2 } // Dominant is the Z axis
57 };
58
59 /*
60 ** Find the largest component of the normal
61 */
62 float x = WWMath::Fabs(tri.N->X);
63 float y = WWMath::Fabs(tri.N->Y);
64 float z = WWMath::Fabs(tri.N->Z);
65
66 float val = x;
67 int ni = 0;
68
69 if (y > val)
70 {
71 ni = 1;
72 val = y;
73 }
74
75 if (z > val)
76 {
77 ni = 2;
78 }
79
80 info = dominance[ni];
81}
82
83static inline void find_dominant_plane(const TriClass & tri, int * axis1,int * axis2,int * axis3)
84{
85 /*
86 ** Find the largest component of the normal
87 */
88 int ni = 0;
89 float x = WWMath::Fabs(tri.N->X);
90 float y = WWMath::Fabs(tri.N->Y);
91 float z = WWMath::Fabs(tri.N->Z);
92 float val = x;
93
94 if (y > val) {
95 ni = 1;
96 val = y;
97 }
98
99 if (z > val) {
100 ni = 2;
101 }
102
103 /*
104 ** return the indices of the two axes perpendicular
105 */
106 switch (ni)
107 {
108 case 0:
109 // Dominant is the X axis
110 *axis1 = 1;
111 *axis2 = 2;
112 *axis3 = 0;
113 break;
114 case 1:
115 // Dominant is the Y axis
116 *axis1 = 0;
117 *axis2 = 2;
118 *axis3 = 1;
119 break;
120 case 2:
121 // Dominant is the Z axis
122 *axis1 = 0;
123 *axis2 = 1;
124 *axis3 = 2;
125 break;
126 }
127}
128
129
130
131/***********************************************************************************************
132 * TriClass::Find_Dominant_Plane -- returns indices of the axes of the dominant plane *
133 * *
134 * INPUT: *
135 * *
136 * OUTPUT: *
137 * *
138 * WARNINGS: *
139 * *
140 * HISTORY: *
141 * 3/24/99 GTH : Created. *
142 *=============================================================================================*/
143void TriClass::Find_Dominant_Plane(int * axis1,int * axis2) const
144{
145 /*
146 ** Find the largest component of the normal
147 */
148 int ni = 0;
149 float x = WWMath::Fabs(N->X);
150 float y = WWMath::Fabs(N->Y);
151 float z = WWMath::Fabs(N->Z);
152 float val = x;
153
154 if (y > val) {
155 ni = 1;
156 val = y;
157 }
158
159 if (z > val) {
160 ni = 2;
161 }
162
163 /*
164 ** return the indices of the two axes perpendicular
165 */
166 switch (ni)
167 {
168 case 0:
169 // Dominant is the X axis
170 *axis1 = 1;
171 *axis2 = 2;
172 break;
173 case 1:
174 // Dominant is the Y axis
175 *axis1 = 0;
176 *axis2 = 2;
177 break;
178 case 2:
179 // Dominant is the Z axis
180 *axis1 = 0;
181 *axis2 = 1;
182 break;
183 }
184}
185
186
187/***********************************************************************************************
188 * TriClass::Contains_Point -- performs 2D point-in-triangle test. *
189 * *
190 * INPUT: *
191 * *
192 * OUTPUT: *
193 * *
194 * WARNINGS: *
195 * Assumes that the point is in the plane of the triangle... use this after you've intersected *
196 * a ray with the plane of the triangle. *
197 * *
198 * HISTORY: *
199 * 3/24/99 GTH : Created. *
200 *=============================================================================================*/
201bool TriClass::Contains_Point(const Vector3 & ipoint) const
202{
203#if 0
204 /*
205 ** Perform the test in 2d on the plane which the normal
206 ** is most perpendicular to. (copied from E.Cosky's intersection code)
207 */
208 int axis1 = 0;
209 int axis2 = 0;
210 Find_Dominant_Plane(&axis1,&axis2);
211
212#if 1
213 unsigned char flags; // dummy variable passed into function and not used here
214 return Point_In_Triangle_2D(*V[0], *V[1], *V[2], ipoint, axis1, axis2, flags);
215#else
216 float u0 = ipoint[axis1] - (*V[0])[axis1];
217 float v0 = ipoint[axis2] - (*V[0])[axis2];
218
219 /*
220 ** determine the 2d vectors on the dominant plane from the first vertex to the other two
221 */
222 float u1 = (*V[1])[axis1] - (*V[0])[axis1];
223 float v1 = (*V[1])[axis2] - (*V[0])[axis2];
224 float u2 = (*V[2])[axis1] - (*V[0])[axis1];
225 float v2 = (*V[2])[axis2] - (*V[0])[axis2];
226
227 float alpha, beta;
228 bool intersect = false;
229
230 // calculate alpha and beta as normalized (0..1) percentages across the 2d projected triangle
231 // and do bounds checking (sum <= 1) to determine whether or not the triangle intersection occurs.
232 if (u1 == 0) {
233 beta = u0 / u2;
234 if ((beta >= 0) && (beta <= 1)) {
235 alpha = (v0 - beta * v2) / v1;
236 intersect = ((alpha >= 0) && ((alpha + beta) <= 1 + WWMATH_EPSILON));
237 }
238 } else {
239 beta = (v0 * u1 - u0 * v1) / (v2 * u1 - u2 * v1);
240 if ((beta >= 0) && (beta <= 1)) {
241 alpha = (u0 - beta * u2) / u1;
242 intersect = ((alpha >= 0) && ((alpha + beta) <= 1 + WWMATH_EPSILON));
243 }
244 }
245
246 return intersect;
247#endif
248#endif
249/*
250** New cross-product based point-containment
251*/
252#if 0
253 int vi;
254 int axis3 = 0;
255
256 for (vi=0; vi<3; vi++) {
257 if ((axis1 != vi) && (axis2 != vi)) axis3 = vi;
258 }
259
260 Vector3 test_point = ipoint;
261 test_point[axis3] = 0.0f;
262
263 Vector3 points[3];
264 for (vi=0; vi<3; vi++) {
265 points[vi] = *(V[vi]);
266 points[vi][axis3] = 0.0f;
267 }
268
269 bool side[3];
270 Vector3 edge;
271 Vector3 cross;
272 Vector3 dp;
273
274 for (vi=0; vi<3; vi++) {
275 edge = points[(vi+1)%3] - points[vi];
276 dp = test_point - points[vi];
277
278 Vector3::Cross_Product(dp,edge,&cross);
279 side[vi] = (cross[axis3] > 0.0f);
280 }
281
282 bool my_intersect = ((side[0] == side[1]) && (side[1] == side[2]));
283 return my_intersect;
284#endif
285
286
287/*
288** "Optimized" version
289*/
290#if 1
291#if 0
292
293 // srj opto version
295
296 FDPRec info;
297 find_dominant_plane_fast(*this, info);
298
299 /*
300 ** Compute the 2D cross product of edge0 with a vector to the point
301 */
302
303 float edge_x, edge_y, dp_x, dp_y, cross;
304 bool side0, side1, side2;
305
306 edge_x = (*V[1])[info.axis1] - (*V[0])[info.axis1];
307 edge_y = (*V[1])[info.axis2] - (*V[0])[info.axis2];
308 dp_x = ipoint[info.axis1] - (*V[0])[info.axis1];
309 dp_y = ipoint[info.axis2] - (*V[0])[info.axis2];
310 cross = edge_x * dp_y - edge_y * dp_x;
311 side0 = (cross >= 0.0f);
312
313 edge_x = (*V[2])[info.axis1] - (*V[1])[info.axis1];
314 edge_y = (*V[2])[info.axis2] - (*V[1])[info.axis2];
315 dp_x = ipoint[info.axis1] - (*V[1])[info.axis1];
316 dp_y = ipoint[info.axis2] - (*V[1])[info.axis2];
317 cross = edge_x * dp_y - edge_y * dp_x;
318 side1 = (cross >= 0.0f);
319
320 edge_x = (*V[0])[info.axis1] - (*V[2])[info.axis1];
321 edge_y = (*V[0])[info.axis2] - (*V[2])[info.axis2];
322 dp_x = ipoint[info.axis1] - (*V[2])[info.axis1];
323 dp_y = ipoint[info.axis2] - (*V[2])[info.axis2];
324 cross = edge_x * dp_y - edge_y * dp_x;
325 side2 = (cross >= 0.0f);
326
327 bool my_intersect = ((side0 == side1) && (side1 == side2));
328 return my_intersect;
329
330#else
331 int vi;
332 int axis1 = 0;
333 int axis2 = 0;
334 int axis3 = 0;
335
336 find_dominant_plane(*this,&axis1,&axis2,&axis3);
337
338 bool side[3];
339
340 /*
341 ** Compute the 2D cross product of edge0 with a vector to the point
342 */
343 Vector2 edge;
344 Vector2 dp;
345
346 for (vi=0; vi<3; vi++) {
347
348 int va=vi;
349 int vb=(vi+1)%3;
350
351 edge.Set((*V[vb])[axis1] - (*V[va])[axis1] , (*V[vb])[axis2] - (*V[va])[axis2]);
352 dp.Set(ipoint[axis1] - (*V[va])[axis1] , ipoint[axis2] - (*V[va])[axis2]);
353 float cross = edge.X * dp.Y - edge.Y * dp.X;
354 side[vi] = (cross >= 0.0f);
355 }
356
357 bool my_intersect = ((side[0] == side[1]) && (side[1] == side[2]));
358 return my_intersect;
359#endif
360#endif
361
362
363}
#define WWMATH_EPSILON
Definition wwmath.h:54
Definition tri.h:61
bool Contains_Point(const Vector3 &ipoint) const
Definition tri.cpp:201
const Vector3 * N
Definition tri.h:64
const Vector3 * V[3]
Definition tri.h:65
void Find_Dominant_Plane(int *axis1, int *axis2) const
Definition tri.cpp:143
float X
Definition vector3.h:90
float Z
Definition vector3.h:92
float Y
Definition vector3.h:91
static WWINLINE void Cross_Product(const Vector3 &a, const Vector3 &b, Vector3 *result)
Definition vector3.h:374
WWINLINE void Set(float x, float y, float z)
Definition vector3.h:103
static WWINLINE float Fabs(float val)
Definition wwmath.h:113
Definition tri.cpp:44
int axis1
Definition tri.cpp:45
int axis2
Definition tri.cpp:46
int axis3
Definition tri.cpp:47
bool Point_In_Triangle_2D(const Vector3 &tri_point0, const Vector3 &tri_point1, const Vector3 &tri_point2, const Vector3 &test_point, int axis_1, int axis_2, unsigned char &flags)
Definition tri.h:107