Richard Boegli's CnC_Generals_Zero_Hour Fork WIP
This is documentation of Richard Boegil's Zero Hour Fork
 
Loading...
Searching...
No Matches
intersec.h
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 : G *
24 * *
25 * $Archive:: /Commando/Code/ww3d2/intersec.h $*
26 * *
27 * $Author:: Naty_h $*
28 * *
29 * $Modtime:: 3/28/01 11:29a $*
30 * *
31 * $Revision:: 5 $*
32 * *
33 *---------------------------------------------------------------------------------------------*
34 * Functions: *
35 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
36
37/*
38
39 Most of the functions of this class are inline functions and if you use them you will need
40 to include <intersec.inl>.
41
42 Exceptions to this are the functions most commonly used by render objects:
43
44
45
46 The constructors/destructors are inline & implemented here.
47
48*/
49
50#if defined(_MSC_VER)
51#pragma once
52#endif
53
54#ifndef INTERSEC_H
55#define INTERSEC_H
56
57#include "always.h"
58#include "matrix3d.h"
59#include "layer.h"
60#include "sphere.h"
61#include "coltype.h"
62
63
64class RenderObjClass;
65typedef unsigned short POLYGONINDEX;
66
67
68/*
69**
70*/
72{
73public:
76
77 Matrix3D ModelMatrix; // this is required for transforming mesh normals from model coords
79 Vector3 Intersection; // location of intersection is placed here
80
81 float Range; // distance from ray to point of intersection
82 float Alpha, Beta; // stored for use by Process_Intersection_Results() - used to interpolate normal across a polygon
83 bool Intersects; // could be in the intersection_type, but it is used in a number of bool operations
84 int CollisionType; // mask for which object types to intersect with (added for 'Generals'. MW)
85
91};
92
93
95{
96 // member data
97
98public:
99 enum {
100 MAX_POLY_INTERSECTION_COUNT = 1000, // arbitrary size of stack array used for storing intersection results within Intersect_Mesh(). Non-recursive function.
102 };
103
104 // this structure is used to store all intersections on the stack for sorting before
105 // copying the nearest intersection to IntersectionClassObject->Result.
106 // note: the convex intersection functions return with the first intersection results.
107
108 Vector3 *RayLocation; // note: these pointers must be Set() to valid pointers by external code
110 Vector3 *IntersectionNormal; // if non-zero then Process_Intersection_Results() will place the (perhaps vertex interpolated) surface normal here.
111
112 // 2d screen coordinates for use by Intersect_Screen_Point...() routines.
114
115 // if true, then interpolate the normal for a polygon intersection from the vertex normals.
116 // note: intersection routines below which take a FinalResult argument do not interpolate
117 // the normal since they are intended to be used to find the nearest of several intersections
118 // and interpolating the normal for intersections that are tossed would be wasteful.
119 // If you need the normal interpolated in that case anyways then call Interpolate_Normal().
121
122 // if true, then perform potentially much faster convex intersection test which will return
123 // the first valid intersection. Generally used for producing silhouettes.
124 // If true, all intersections will be convex tests. If false, test mode will be determined (generally)
125 // by the render object or whatever called the intersection functions and passes the Convex argument.
127
128 // do not consider intersections beyond this range as an intersection.
129 // Note: Get_Screen_Ray sets this to scene->zstop.
131
132 // final intersection results are contained here
134
135 //
136 // Implementation
137 //
138
139 // configures the member data to use the passed pointers
140 inline void Set(Vector3 *location, Vector3 *direction, Vector3 *intersection_normal, bool interpolate_normal, float max_distance, bool convex_test = false)
141 {
142 RayLocation = location;
143 RayDirection = direction;
144 IntersectionNormal = intersection_normal;
145 InterpolateNormal = interpolate_normal;
146 MaxDistance = max_distance;
147 ConvexTest = convex_test;
148 }
149
150
151
152 // this constructor uses static variables for the location/direction/normal variables
153 // so can be only used one thread at a time unless the Set() function is used to
154 // set them to private vector3's
157 {
161 Result.CollisionType=COLL_TYPE_ALL; //added for 'Generals'. MW
162 }
163
164
165 // This will be the most commonly used constructor
166 inline IntersectionClass(Vector3 *location, Vector3 *direction, Vector3 *intersection_normal, bool interpolate_normal = false, float max_distance = WWMATH_FLOAT_MAX, bool convex_test = false)
167 {
168 Set(location, direction, intersection_normal, interpolate_normal, max_distance, convex_test);
169 }
170
171
173
174
175 // this copy routine is used when the model coords are needed to be copied along with the other information.
177 Destination->ModelMatrix = Source->ModelMatrix;
178 Destination->ModelLocation = Source->ModelLocation;
179 Copy_Partial_Results(Destination, Source);
181 }
182
183
187
188
189 // this is called only for the nearest intersection. If the request passes a Interpolated_Normal pointer then it will be calculated.
190 // otherwise the results are copied into the request structure.
191 // This does not copy the matrix or location members; it is intended to be used during poly testing
192 // where these values are identical between results, or as a completion function for Copy_Results()
194 {
195 Destination->IntersectedPolygon = Source->IntersectedPolygon;
196 Destination->Intersection = Source->Intersection;
197 Destination->Range = Source->Range;
198 Destination->Alpha = Source->Alpha;
199 Destination->Beta = Source->Beta;
200 Destination->Intersects = true;
201 Destination->IntersectionType = Source->IntersectionType;
202 }
203
204
205 // used for creating temporary copies
207 {
208 *this = source;
209 }
210
211
213 {
214 Set(source->RayLocation, source->RayDirection, source->IntersectionNormal, source->InterpolateNormal, source->MaxDistance, source->ConvexTest);
215 Copy_Results(&source->Result);
216 return this;
217 }
218
219
220
221 // find the range to the intersection of the ray and sphere (if any)
222 // note: Intersection_Request->RayDirection must be a unit vector
223 // To find the actual intersection location and perhaps the intersection normal, use Intersection_Sphere() instead.
224 // loosly based on code found in Graphics Gems I, p388
225 // this will only set the result's range if intersection occurs; it is intended to be used as a first pass intersection test
226 // before intersecting the mesh polygons itself.
227 // Note: Does NOT do Max_Distance testing
229 {
230 // make a unit vector from the ray origin to the sphere center
231 Vector3 sphere_vector(Sphere.Center - *RayLocation);
232
233 // get the dot product between the sphere_vector and the ray vector
234 FinalResult->Alpha = Vector3::Dot_Product(sphere_vector, *RayDirection);
235
236 FinalResult->Beta = Sphere.Radius * Sphere.Radius - (Vector3::Dot_Product(sphere_vector, sphere_vector) - FinalResult->Alpha * FinalResult->Alpha);
237
238 if(FinalResult->Beta < 0.0f) {
239 return FinalResult->Intersects = false;
240 }
241 return FinalResult->Intersects = true;
242 }
243
244
245 // this will find the intersection with the sphere and the intersection normal if needed.
247 {
248 if(!Intersect_Sphere_Quick(Sphere, FinalResult))
249 return false;
250
251 // determine range to intersection based on stored alpha/beta values
252 float d = sqrtf(FinalResult->Beta);
253 FinalResult->Range = FinalResult->Alpha - d;
254
255 if(FinalResult->Range > MaxDistance) return false;
256
257 FinalResult->Intersection = *RayLocation + FinalResult->Range * (*RayDirection);
258
259 if(IntersectionNormal != 0) {
260 (*IntersectionNormal) = FinalResult->Intersection - Sphere.Center;
261 }
262 return true;
263 }
264
265
266 // inline declarations
267 // Usage of these functions requires including intersec.inl
268
269 // determine location & direction for projected screen coordinate ray
270 inline void Get_Screen_Ray(float ScreenX, float ScreenY, const LayerClass &Layer);
271
272 // uses the Result's range & the Ray_Direction to calculate the actual point of intersection.
274
275 // interpolate the normal for a polygon intersection. Will ONLY work for polygon intersections,
276 // and the Results.Intersection_Data must refer to a polygon with a valid ->mesh pointer.
278
279 // various methods for performing intersections.
280 inline bool Intersect_Plane(IntersectionResultClass *Result, Vector3 &Plane_Normal, Vector3 &Plane_Point);
281 inline bool Intersect_Plane_Quick(IntersectionResultClass *Result, Vector3 &Plane_Normal, Vector3 &Plane_Point);
282 inline bool Intersect_Polygon(IntersectionResultClass *Result, Vector3 &PolygonNormal, Vector3 &v1, Vector3 &v2, Vector3 &v3);
284 inline bool Intersect_Polygon_Z(IntersectionResultClass *Result, Vector3 &PolygonNormal, Vector3 &v1, Vector3 &v2, Vector3 &v3);
285
286 /*
287 ** This function will fill the passed array with the set of points & uv values that represent
288 ** the boolean operation of the anding of the ClipPoints with the TrianglePoints. The UV values
289 ** provided for the TrianglePoints triangle are used to generate accurate UV values for any
290 ** new points created by this operation.
291 ** The clipped points have Z values that make them sit on the ClipPoints triangle plane.
292 */
293 static inline int _Intersect_Triangles_Z(
294 Vector3 ClipPoints[3],
295 Vector3 TrianglePoints[3],
296 Vector2 UV[3],
297 Vector3 ClippedPoints[6],
298 Vector2 ClippedUV[6]
299 );
300
301 /*
302 ** This function will find the z elevation for the passed Vector3 whose x/y components
303 ** are defined, using the specified vertex & surface normal to determine the correct value
304 */
305 static inline float _Get_Z_Elevation(Vector3 &Point, Vector3 &PlanePoint, Vector3 &PlaneNormal);
306
307
308 // test a 2d screen area with the intersection's screen coords, assigning a GENERIC intersection
309 // to the specified object.
310 inline bool Intersect_Screen_Object(IntersectionResultClass *Final_Result, Vector4 &Area, RenderObjClass *obj = 0);
311
312
313 // non-inlined declarations
314
315
316 // accumulates an object array for passing into Intersect_ObjectArray
317 void Append_Object_Array(int MaxCount, int &CurrentCount, RenderObjClass **ObjectArray, RenderObjClass *Object);
318
319 // traverses an RenderObjClass object and adds it's subobjects, potentially performing
320 // a quick sphere intersection test before adding.
321 void Append_Hierarchy_Objects(int MaxCount, int &CurrentCount, RenderObjClass **ObjectArray, RenderObjClass *Heirarchy, bool Test_Bounding_Spheres, bool Convex);
322
323 // top level intersection routines, most store intersection results in the Intersection.Result
324 // member structure and perform normal interpolation as a final step if indicated in the member data.
325
326 bool Intersect_Object_Array(int ObjectCount, RenderObjClass **ObjectArray,IntersectionResultClass *FinalResult, bool Test_Bounding_Sphere, bool Convex);
327 bool Intersect_Object_Array(int ObjectCount, RenderObjClass **ObjectArray,IntersectionResultClass *FinalResult, IntersectionResultClass *TemporaryResults, bool Test_Bounding_Sphere, bool Convex);
329 bool Intersect_Screen_Point_RenderObject(float screen_x, float screen_y, const LayerClass &Layer, RenderObjClass *RObj, IntersectionResultClass *FinalResult);
330
331 bool Intersect_Screen_Point_Layer_Range(float ScreenX, float ScreenY, const LayerClass &TopLayer, const LayerClass &BackLayer);
333 bool Intersect_Layer(const LayerClass &Layer, bool Test_All = true);
334
335 // the various intersection routines, all of which store their intersection results
336 // in the passed Intersection_Result strucuture.
337 bool Intersect_Box(Vector3 &Box_Min, Vector3 &Box_Max, IntersectionResultClass *FinalResult);
338 bool Intersect_Hierarchy(RenderObjClass *Hierarchy, IntersectionResultClass *FinalResult, bool Test_Bounding_Sphere = true, bool Convex = false);
341
342 /*
343 ** Identifies exactly what sub object of a render object is under the screen space vector
344 */
345 RenderObjClass *Intersect_Sub_Object(float screenx, float screeny, LayerClass &layer, RenderObjClass *robj, IntersectionResultClass *result);
346
347
348 /*
349 ** Functions related to determining if a 3d point is within a triangle.
350 */
351 static inline void _Find_Polygon_Dominant_Plane(Vector3 &Normal, int &Axis_1, int &Axis_2);
352 static inline int _Largest_Normal_Index(Vector3 &v);
353 static inline bool _Point_In_Polygon(IntersectionResultClass *FinalResult, Vector3 &Normal, Vector3 &loc1, Vector3 &loc2, Vector3 &loc3);
354 static inline bool _Point_In_Polygon(IntersectionResultClass *FinalResult, Vector3 &loc1, Vector3 &loc2, Vector3 &loc3, int axis_1, int axis_2);
355 static inline bool _Point_In_Polygon(Vector3 &Point, Vector3 &loc1, Vector3 &loc2, Vector3 &loc3, int axis_1, int axis_2,float &Alpha,float &Beta);
356 static inline bool _Point_In_Polygon_Z(Vector3 &Point, Vector3 Corners[3]);
357 static inline bool _Point_In_Polygon_Z(Vector3 &Point, Vector3 &Corner1, Vector3 &Corner2, Vector3 &Corner3);
358
359protected:
360
361 /*
362 ** Find the intersection between two lines and interpolate the UV values for the intersection.
363 ** Designed for use with _Intersect_Triangles_Z.
364 */
365 //static inline void _Intersect_Lines_Z(Vector3 &A, Vector3 &B, Vector2 &UVStart, Vector2 &UVEnd, Vector3 &C, Vector3 &D, Vector3 ClippedPoints[6], Vector2 ClippedUV[6], int &DestIndex);
366 static inline bool IntersectionClass::In_Front_Of_Line
367 (
368 const Vector3 & p, // point to test
369 const Vector3 & e0, // point on edge
370 const Vector3 & de // direction of edge
371 );
372
373 static inline float IntersectionClass::Intersect_Lines
374 (
375 const Vector3 & p0, // start of line segment
376 const Vector3 & p1, // end of line segment
377 const Vector3 & e0, // point on clipping edge
378 const Vector3 & de // direction of clipping edge
379 );
380
382 int incount,
383 Vector3 * InPoints,
384 Vector2 * InUVs,
385 Vector3 * OutPoints,
386 Vector2 * OutUVs,
387 const Vector3 & edge_point0,
388 const Vector3 & edge_point1
389 );
390
391
392
393 inline float Plane_Z_Distance(Vector3 &PlaneNormal, Vector3 &PlanePoint);
395
396 /*
397 ** Static vars available for use by temporary intersection class objects.
398 */
400
401};
402
403
404#endif
@ false
Definition bool.h:59
#define WWMATH_FLOAT_MAX
Definition wwmath.h:57
bool Intersect_Screen_Point_RenderObject(float screen_x, float screen_y, const LayerClass &Layer, RenderObjClass *RObj, IntersectionResultClass *FinalResult)
Definition intersec.cpp:55
bool Intersect_Plane(IntersectionResultClass *Result, Vector3 &Plane_Normal, Vector3 &Plane_Point)
Definition intersec.inl:416
IntersectionResultClass Result
Definition intersec.h:133
void Transform_Model_To_World_Coords(IntersectionResultClass *FinalResult)
Definition intersec.inl:528
RenderObjClass * Intersect_Sub_Object(float screenx, float screeny, LayerClass &layer, RenderObjClass *robj, IntersectionResultClass *result)
Definition intersec.cpp:337
bool Intersect_Hierarchy_Sphere(RenderObjClass *Hierarchy, IntersectionResultClass *FinalResult)
Definition intersec.cpp:267
bool Intersect_Sphere(SphereClass &Sphere, IntersectionResultClass *FinalResult)
Definition intersec.h:246
void Get_Screen_Ray(float ScreenX, float ScreenY, const LayerClass &Layer)
debug code that will be tossed
Definition intersec.inl:81
@ MAX_POLY_INTERSECTION_COUNT
Definition intersec.h:100
bool Intersect_Screen_Point_Layer(float ScreenX, float ScreenY, const LayerClass &Layer)
Definition intersec.cpp:102
bool Intersect_Sphere_Quick(SphereClass &Sphere, IntersectionResultClass *FinalResult)
Definition intersec.h:228
static Vector3 _IntersectionNormal
Definition intersec.h:399
void Append_Hierarchy_Objects(int MaxCount, int &CurrentCount, RenderObjClass **ObjectArray, RenderObjClass *Heirarchy, bool Test_Bounding_Spheres, bool Convex)
Definition intersec.cpp:279
bool Intersect_Box(Vector3 &Box_Min, Vector3 &Box_Max, IntersectionResultClass *FinalResult)
Definition intersec.cpp:177
static float Intersect_Lines(const Vector3 &p0, const Vector3 &p1, const Vector3 &e0, const Vector3 &de)
Definition intersec.inl:804
Vector3 * IntersectionNormal
Definition intersec.h:110
void Set(Vector3 *location, Vector3 *direction, Vector3 *intersection_normal, bool interpolate_normal, float max_distance, bool convex_test=false)
Definition intersec.h:140
bool Intersect_RenderObject(RenderObjClass *RObj, IntersectionResultClass *FinalResult=0)
Definition intersec.cpp:61
static bool In_Front_Of_Line(const Vector3 &p, const Vector3 &e0, const Vector3 &de)
Definition intersec.inl:789
bool Intersect_Hierarchy_Sphere_Quick(RenderObjClass *Hierarchy, IntersectionResultClass *FinalResult)
Definition intersec.cpp:252
IntersectionClass(Vector3 *location, Vector3 *direction, Vector3 *intersection_normal, bool interpolate_normal=false, float max_distance=WWMATH_FLOAT_MAX, bool convex_test=false)
Definition intersec.h:166
static Vector3 _RayLocation
Definition intersec.h:399
Vector3 * RayLocation
Definition intersec.h:108
bool Intersect_Layer(const LayerClass &Layer, bool Test_All=true)
Definition intersec.cpp:124
static Vector3 _RayDirection
Definition intersec.h:399
float Plane_Z_Distance(Vector3 &PlaneNormal, Vector3 &PlanePoint)
Definition intersec.inl:332
void Interpolate_Intersection_Normal(IntersectionResultClass *FinalResult)
static int Clip_Triangle_To_LineXY(int incount, Vector3 *InPoints, Vector2 *InUVs, Vector3 *OutPoints, Vector2 *OutUVs, const Vector3 &edge_point0, const Vector3 &edge_point1)
Definition intersec.inl:832
static void _Find_Polygon_Dominant_Plane(Vector3 &Normal, int &Axis_1, int &Axis_2)
Definition intersec.inl:462
void Copy_Partial_Results(IntersectionResultClass *Destination, IntersectionResultClass *Source)
Definition intersec.h:193
bool Intersect_Plane_Quick(IntersectionResultClass *Result, Vector3 &Plane_Normal, Vector3 &Plane_Point)
Definition intersec.inl:397
static int _Intersect_Triangles_Z(Vector3 ClipPoints[3], Vector3 TrianglePoints[3], Vector2 UV[3], Vector3 ClippedPoints[6], Vector2 ClippedUV[6])
Definition intersec.inl:896
bool Intersect_Screen_Object(IntersectionResultClass *Final_Result, Vector4 &Area, RenderObjClass *obj=0)
Definition intersec.inl:549
bool Intersect_Screen_Point_Layer_Range(float ScreenX, float ScreenY, const LayerClass &TopLayer, const LayerClass &BackLayer)
Definition intersec.cpp:72
static float _Get_Z_Elevation(Vector3 &Point, Vector3 &PlanePoint, Vector3 &PlaneNormal)
Definition intersec.inl:350
Vector3 * RayDirection
Definition intersec.h:109
void Copy_Results(IntersectionResultClass *Destination, IntersectionResultClass *Source)
Definition intersec.h:176
void Calculate_Intersection(IntersectionResultClass *Result)
Definition intersec.inl:385
void Append_Object_Array(int MaxCount, int &CurrentCount, RenderObjClass **ObjectArray, RenderObjClass *Object)
Definition intersec.cpp:157
static bool _Point_In_Polygon_Z(Vector3 &Point, Vector3 Corners[3])
Definition intersec.inl:208
bool Intersect_Polygon_Z(IntersectionResultClass *Result, Vector3 &PolygonNormal, Vector3 &v1, Vector3 &v2, Vector3 &v3)
Definition intersec.inl:371
IntersectionClass(IntersectionClass *source)
Definition intersec.h:206
virtual ~IntersectionClass()
Definition intersec.h:172
bool Intersect_Object_Array(int ObjectCount, RenderObjClass **ObjectArray, IntersectionResultClass *FinalResult, bool Test_Bounding_Sphere, bool Convex)
Definition intersec.cpp:357
static bool _Point_In_Polygon(IntersectionResultClass *FinalResult, Vector3 &Normal, Vector3 &loc1, Vector3 &loc2, Vector3 &loc3)
Definition intersec.inl:319
IntersectionClass * operator=(IntersectionClass *source)
Definition intersec.h:212
bool Intersect_Polygon(IntersectionResultClass *Result, Vector3 &PolygonNormal, Vector3 &v1, Vector3 &v2, Vector3 &v3)
Definition intersec.inl:491
bool Intersect_Hierarchy(RenderObjClass *Hierarchy, IntersectionResultClass *FinalResult, bool Test_Bounding_Sphere=true, bool Convex=false)
Definition intersec.cpp:313
static int _Largest_Normal_Index(Vector3 &v)
Definition intersec.inl:442
RenderObjClass * IntersectedRenderObject
Definition intersec.h:74
POLYGONINDEX IntersectedPolygon
Definition intersec.h:75
enum IntersectionResultClass::INTERSECTION_TYPE IntersectionType
float Radius
Definition sphere.h:91
Vector3 Center
Definition sphere.h:90
static WWINLINE float Dot_Product(const Vector3 &a, const Vector3 &b)
Definition vector3.h:293
@ COLL_TYPE_ALL
Definition coltype.h:75
unsigned short POLYGONINDEX
Definition intersec.h:65