Richard Boegli's CnC_Generals_Zero_Hour Fork WIP
This is documentation of Richard Boegil's Zero Hour Fork
 
Loading...
Searching...
No Matches
obbox.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/obbox.cpp $*
26 * *
27 * Org Author:: Greg_h *
28 * *
29 * Author : Kenny Mitchell *
30 * *
31 * $Modtime:: 06/26/02 4:04p $*
32 * *
33 * $Revision:: 24 $*
34 * *
35 * 06/26/02 KM Matrix name change to avoid MAX conflicts *
36 *---------------------------------------------------------------------------------------------*
37 * Functions: *
38 * OBBoxClass::OBBoxClass -- Constructor that computes the box for a set of point *
39 * OBBoxClass::Init_From_Box_Points -- Create an OBBox from 8 corners of a box *
40 * OBBoxClass::Init_Random -- initalize a random oriented box *
41 * Oriented_Boxes_Intersect_On_Axis -- test if two boxes intersect on given axis *
42 * Oriented_Boxes_Intersect -- test if two oriented boxes intersect *
43 * Oriented_Boxes_Collide_On_Axis -- test if two boxes collide on the given axis *
44 * Oriented_Boxes_Collide -- test if two oriented boxes collide *
45 * Oriented_Box_Intersects_Tri_On_Axis -- tests if the box and tri intersect on the axis *
46 * Oriented_Box_Intersects_Tri -- tests if the given box and tri intersect *
47 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
48
49
50#include "obbox.h"
51#include "matrix3.h"
52#include "vector3.h"
53#include "aabox.h"
54#include "tri.h"
55#include "plane.h"
56#include "quat.h"
57#include <assert.h>
58//#include <stdlib.h>
59
60
61/***********************************************************************************************
62 * OBBoxClass::OBBoxClass -- Constructor that computes the box for a set of points *
63 * *
64 * INPUT: *
65 * *
66 * OUTPUT: *
67 * *
68 * WARNINGS: *
69 * *
70 * HISTORY: *
71 * 2/4/98 GTH : Created. *
72 *=============================================================================================*/
73OBBoxClass::OBBoxClass(const Vector3 * /*points*/, int /*n*/)
74{
75 // TODO: IMPLEMENT THIS!!!
76 assert(0);
77
78#if 0
79 int i;
80
81 // compute mean and covariances of points
82 float xsum = 0.0f, ysum = 0.0f, zsum = 0.0f;;
83 float xxsum = 0.0f, xysum = 0.0f, xzsum = 0.0f;
84 float yysum = 0.0f, yzsum = 0.0f, zzsum = 0.0f;
85
86 for (i = 0; i < n; i++)
87 {
88 xsum += points[i].X;
89 ysum += points[i].Y;
90 zsum += points[i].Z;
91
92 xxsum += points[i].X * points[i].X;
93 xysum += points[i].X * points[i].Y;
94 xzsum += points[i].X * points[i].Z;
95
96 yysum += points[i].Y * points[i].Y;
97 yzsum += points[i].Y * points[i].Z;
98 zzsum += points[i].Z * points[i].Z;
99 }
100
101 float xmean = xsum/n;
102 float ymean = ysum/n;
103 float zmean = zsum/n;
104 float xxcov = xxsum/n - xmean*xmean;
105 float xycov = xysum/n - xmean*ymean;
106 float xzcov = xzsum/n - xmean*zmean;
107 float yycov = yysum/n - ymean*ymean;
108 float yzcov = yzsum/n - ymean*zmean;
109 float zzcov = zzsum/n - zmean*zmean;
110
111 // compute eigenvectors for covariance matrix,
112 // these will be the axes.
113 mgcEigen eig(3);
114 eig.Matrix(0,0) = xxcov;
115 eig.Matrix(0,1) = xycov;
116 eig.Matrix(0,2) = xzcov;
117 eig.Matrix(1,0) = xycov;
118 eig.Matrix(1,1) = yycov;
119 eig.Matrix(1,2) = yzcov;
120 eig.Matrix(2,0) = xzcov;
121 eig.Matrix(2,1) = yzcov;
122 eig.Matrix(2,2) = zzcov;
123
124 eig.EigenStuff3();
125 Point3 U =
126 {
127 eig.Eigenvector(0,0),
128 eig.Eigenvector(1,0),
129 eig.Eigenvector(2,0)
130 };
131 Point3 V =
132 {
133 eig.Eigenvector(0,1),
134 eig.Eigenvector(1,1),
135 eig.Eigenvector(2,1)
136 };
137 Point3 W =
138 {
139 eig.Eigenvector(0,2),
140 eig.Eigenvector(1,2),
141 eig.Eigenvector(2,2)
142 };
143
144 // box center is the mean of the distribution
145 box.center.x = xmean;
146 box.center.y = ymean;
147 box.center.z = zmean;
148
149
150 // Box axes are the eigenvectors of the covariance matrix with
151 // adjusted lengths to enclose the points. If U, V, and W are the
152 // eigenvectors, C is the center of the box, and X is a point in
153 // the input list, then X = C + a*U + b*V + c*W. The box extent is
154 // determined by max|a|, max|b|, and max|c|. The box axes are then
155 // defined to be (max|a|)*U and (max|b|)*V. Note that since U and V
156 // are unit length and orthogonal, a = Dot(U,X-C), b = Dot(V,X-C),
157 // and c = Dot(W,X-C).
158 float amax = 0.0f, bmax = 0.0f, cmax = 0.0f;
159 for (i = 0; i < n; i++)
160 {
161 float dx = pt[i].x - box.center.x;
162 float dy = pt[i].y - box.center.y;
163 float dz = pt[i].z - box.center.z;
164 float absdot = float(WWMath::Fabs(U.x*dx+U.y*dy+U.z*dz));
165 if ( absdot > amax )
166 amax = absdot;
167 absdot = float(WWMath::Fabs(V.x*dx+V.y*dy+V.z*dz));
168 if ( absdot > bmax )
169 bmax = absdot;
170 absdot = float(WWMath::Fabs(W.x*dx+W.y*dy+W.z*dz));
171 if ( absdot > cmax )
172 cmax = absdot;
173 }
174
175 box.axis[0].x = amax*U.x;
176 box.axis[0].y = amax*U.y;
177 box.axis[0].z = amax*U.z;
178 box.axis[1].x = bmax*V.x;
179 box.axis[1].y = bmax*V.y;
180 box.axis[1].z = bmax*V.z;
181 box.axis[2].x = cmax*W.x;
182 box.axis[2].y = cmax*W.y;
183 box.axis[2].z = cmax*W.z;
184
185#endif
186}
187
188/***********************************************************************************************
189 * OBBoxClass::Init_From_Box_Points -- Create an OBBox from 8 corners of a box *
190 * *
191 * INPUT: *
192 * *
193 * OUTPUT: *
194 * *
195 * WARNINGS: *
196 * *
197 * HISTORY: *
198 * 2/24/98 GTH : Created. *
199 *=============================================================================================*/
201{
202 int i,j;
203
204 /*
205 ** This function assumes that you pass in 8 points which are the
206 ** corners of a rectangular solid. Bad things will happen if
207 ** this assumption is not true!!!!
208 */
209 assert(num == 8);
210
211 /*
212 ** Just pick the first point as the preliminary center. Compute
213 ** vectors from this point to each of the other points
214 */
215 Vector3 dp[8];
216 for (i=1;i<num;i++) {
217 dp[i] = points[i] - points[0];
218 }
219
220 /*
221 ** Find the shortest two candidate axes. Then the
222 ** third axis will be the cross product of these two.
223 */
224 for (i=1;i<num;i++) {
225 for (j=i+1;j<num;j++) {
226 if (dp[j].Length2() < dp[i].Length2()) {
227 Swap(dp[j],dp[i]);
228 }
229 }
230 }
231
232 Vector3 axis0,axis1,axis2;
233#ifdef ALLOW_TEMPORARIES
234 axis0 = Normalize(dp[1]);
235 axis1 = Normalize(dp[2]);
236#else
237 axis0 = dp[1]; axis0.Normalize();
238 axis1 = dp[2]; axis1.Normalize();
239#endif
240 Vector3::Cross_Product(axis0,axis1,&axis2);
241
242 Basis = Matrix3x3(axis0,axis1,axis2);
243
244 /*
245 ** Center is the average of all of the points
246 */
247 Center.Set(0,0,0);
248 for (i=0; i<num; i++) {
249 Center += points[i];
250 }
251 Center.X /= num;
252 Center.Y /= num;
253 Center.Z /= num;
254
255 /*
256 ** Compute extents along the computed axes. This is done
257 ** by projecting each point onto the three axes and keeping
258 ** the largest projection on each.
259 */
260 Extent.Set(0,0,0);
261
262 for (i=0; i<num; i++) {
263 float dx = points[i].X - Center.X;
264 float dy = points[i].Y - Center.Y;
265 float dz = points[i].Z - Center.Z;
266
267 float xprj = float(WWMath::Fabs(axis0.X * dx + axis0.Y * dy + axis0.Z * dz));
268 if (xprj > Extent.X) Extent.X = xprj;
269
270 float yprj = float(WWMath::Fabs(axis1.X * dx + axis1.Y * dy + axis1.Z * dz));
271 if (yprj > Extent.Y) Extent.Y = yprj;
272
273 float zprj = float(WWMath::Fabs(axis2.X * dx + axis2.Y * dy + axis2.Z * dz));
274 if (zprj > Extent.Z) Extent.Z = zprj;
275 }
276}
277
278
279/***********************************************************************************************
280 * OBBoxClass::Init_Random -- initalize a random oriented box *
281 * *
282 * INPUT: *
283 * *
284 * OUTPUT: *
285 * *
286 * WARNINGS: *
287 * *
288 * HISTORY: *
289 * 4/21/98 GTH : Created. *
290 *=============================================================================================*/
291void OBBoxClass::Init_Random(float min_extent,float max_extent)
292{
293 Center.Set(0,0,0);
294
295 Extent.X = min_extent + WWMath::Random_Float() * (max_extent - min_extent);
296 Extent.Y = min_extent + WWMath::Random_Float() * (max_extent - min_extent);
297 Extent.Z = min_extent + WWMath::Random_Float() * (max_extent - min_extent);
298
299 Quaternion orient;
300 orient.X = WWMath::Random_Float();
301 orient.Y = WWMath::Random_Float();
302 orient.Z = WWMath::Random_Float();
303 orient.W = WWMath::Random_Float();
304 orient.Normalize();
305
306 Basis = Build_Matrix3(orient);
307}
308
309
310
311
312/***********************************************************************************************
313 * Oriented_Boxes_Intersect_On_Axis -- test if two boxes intersect on given axis *
314 * *
315 * INPUT: *
316 * *
317 * OUTPUT: *
318 * *
319 * WARNINGS: *
320 * *
321 * HISTORY: *
322 * 4/7/99 GTH : Created. *
323 *=============================================================================================*/
325(
326 const OBBoxClass & box0,
327 const OBBoxClass & box1,
328 const Vector3 & axis
329)
330{
331 float ra,rb,rsum;
332
333 if (axis.Length2() < WWMATH_EPSILON) return true;
334
335 ra = box0.Project_To_Axis(axis);
336 rb = box1.Project_To_Axis(axis);
337 rsum = WWMath::Fabs(ra) + WWMath::Fabs(rb);
338
339 // project the center distance onto the line:
340 Vector3 C = box1.Center - box0.Center;
341 float cdist = Vector3::Dot_Product(axis,C);
342
343 if ((cdist > rsum) || (cdist < -rsum)) {
344 return false;
345 }
346 return true;
347}
348
349
350/***********************************************************************************************
351 * Oriented_Boxes_Intersect -- test if two oriented boxes intersect *
352 * *
353 * INPUT: *
354 * *
355 * OUTPUT: *
356 * *
357 * WARNINGS: *
358 * *
359 * HISTORY: *
360 * 4/7/99 GTH : Created. *
361 *=============================================================================================*/
363(
364 const OBBoxClass & box0,
365 const OBBoxClass & box1
366)
367{
368 Vector3 axis;
369 Vector3 A[3],B[3];
370
371 // vectors for the axis directions of the two boxes in world space
372 A[0].Set(box0.Basis[0][0],box0.Basis[1][0],box0.Basis[2][0]);
373 A[1].Set(box0.Basis[0][1],box0.Basis[1][1],box0.Basis[2][1]);
374 A[2].Set(box0.Basis[0][2],box0.Basis[1][2],box0.Basis[2][2]);
375
376 B[0].Set(box1.Basis[0][0],box1.Basis[1][0],box1.Basis[2][0]);
377 B[1].Set(box1.Basis[0][1],box1.Basis[1][1],box1.Basis[2][1]);
378 B[2].Set(box1.Basis[0][2],box1.Basis[1][2],box1.Basis[2][2]);
379
381 // Projecting the two boxes onto Box0's X axis. If their intervals
382 // on this line do not intersect, the boxes are not intersecting.
383 // Each of the tests in this function work in a similar way.
385 if (!Oriented_Boxes_Intersect_On_Axis(box0,box1,A[0])) return false;
386 if (!Oriented_Boxes_Intersect_On_Axis(box0,box1,A[1])) return false;
387 if (!Oriented_Boxes_Intersect_On_Axis(box0,box1,A[2])) return false;
388 if (!Oriented_Boxes_Intersect_On_Axis(box0,box1,B[0])) return false;
389 if (!Oriented_Boxes_Intersect_On_Axis(box0,box1,B[1])) return false;
390 if (!Oriented_Boxes_Intersect_On_Axis(box0,box1,B[2])) return false;
391
393 // None of the aligned axes turned out to be separating axes. Now
394 // we check all combinations of cross products of the two boxes axes.
396 Vector3::Cross_Product(A[0],B[0],&axis);
397 if (!Oriented_Boxes_Intersect_On_Axis(box0,box1,axis)) return false;
398
399 Vector3::Cross_Product(A[0],B[1],&axis);
400 if (!Oriented_Boxes_Intersect_On_Axis(box0,box1,axis)) return false;
401
402 Vector3::Cross_Product(A[0],B[2],&axis);
403 if (!Oriented_Boxes_Intersect_On_Axis(box0,box1,axis)) return false;
404
405 Vector3::Cross_Product(A[1],B[0],&axis);
406 if (!Oriented_Boxes_Intersect_On_Axis(box0,box1,axis)) return false;
407
408 Vector3::Cross_Product(A[1],B[1],&axis);
409 if (!Oriented_Boxes_Intersect_On_Axis(box0,box1,axis)) return false;
410
411 Vector3::Cross_Product(A[1],B[2],&axis);
412 if (!Oriented_Boxes_Intersect_On_Axis(box0,box1,axis)) return false;
413
414 Vector3::Cross_Product(A[2],B[0],&axis);
415 if (!Oriented_Boxes_Intersect_On_Axis(box0,box1,axis)) return false;
416
417 Vector3::Cross_Product(A[2],B[1],&axis);
418 if (!Oriented_Boxes_Intersect_On_Axis(box0,box1,axis)) return false;
419
420 Vector3::Cross_Product(A[2],B[2],&axis);
421 if (!Oriented_Boxes_Intersect_On_Axis(box0,box1,axis)) return false;
422
423 // None of the above tests separated the two boxes, so they are intersecting
424 return true;
425}
426
427
428
429
430
431/***********************************************************************************************
432 * Oriented_Boxes_Collide_On_Axis -- test if two boxes collide on the given axis *
433 * *
434 * INPUT: *
435 * *
436 * OUTPUT: *
437 * *
438 * WARNINGS: *
439 * *
440 * HISTORY: *
441 * 4/7/99 GTH : Created. *
442 *=============================================================================================*/
444(
445 const OBBoxClass & box0,
446 const Vector3 & v0,
447 const OBBoxClass & box1,
448 const Vector3 & v1,
449 const Vector3 & axis,
450 float dt
451)
452{
453 float ra,rb,rsum;
454
455 if (axis.Length2() < WWMATH_EPSILON) return true;
456
457 ra = box0.Project_To_Axis(axis);
458 rb = box1.Project_To_Axis(axis);
459 rsum = WWMath::Fabs(ra) + WWMath::Fabs(rb);
460
461 // project the center distance onto the line:
462 Vector3 C = box1.Center - box0.Center;
463 Vector3 V = v1 - v0;
464
465 float cdist = Vector3::Dot_Product(axis,C);
466 float vdist = cdist + dt * Vector3::Dot_Product(axis,V);
467
468 if ((cdist > rsum && vdist > rsum) || (cdist < -rsum && vdist < -rsum)) {
469 return false;
470 }
471 return true;
472}
473
474
475/***********************************************************************************************
476 * Oriented_Boxes_Collide -- test if two oriented boxes collide *
477 * *
478 * INPUT: *
479 * *
480 * OUTPUT: *
481 * *
482 * WARNINGS: *
483 * *
484 * HISTORY: *
485 * 4/7/99 GTH : Created. *
486 *=============================================================================================*/
488(
489 const OBBoxClass & box0,
490 const Vector3 & v0,
491 const OBBoxClass & box1,
492 const Vector3 & v1,
493 float dt
494)
495{
496 bool intersect = true;
497
498 // variables for holding the separating axis and the projected distances
499 Vector3 SepAxis;
500
501 // vectors for the axis directions of the two boxes in world space
502 Vector3 A0(box0.Basis[0][0],box0.Basis[1][0],box0.Basis[2][0]);
503 Vector3 A1(box0.Basis[0][1],box0.Basis[1][1],box0.Basis[2][1]);
504 Vector3 A2(box0.Basis[0][2],box0.Basis[1][2],box0.Basis[2][2]);
505
506 Vector3 B0(box1.Basis[0][0],box1.Basis[1][0],box1.Basis[2][0]);
507 Vector3 B1(box1.Basis[0][1],box1.Basis[1][1],box1.Basis[2][1]);
508 Vector3 B2(box1.Basis[0][2],box1.Basis[1][2],box1.Basis[2][2]);
509
510
512 // L = A0
513 //
514 // Projecting the two boxes onto Box0's X axis. If their intervals
515 // on this line do not intersect, the boxes are not intersecting!
516 // Each of the tests in this function work in a similar way.
518 SepAxis = A0;
519
520 if (!Oriented_Boxes_Collide_On_Axis(box0,v0,box1,v1,SepAxis,dt)) {
521 intersect = false;
522 goto exit;
523 }
524
526 // L = A1
527 // Separating Axis is Box0's Y axis
529 SepAxis = A1;
530
531 if (!Oriented_Boxes_Collide_On_Axis(box0,v0,box1,v1,SepAxis,dt)) {
532 intersect = false;
533 goto exit;
534 }
535
537 // L = A2
538 // Separating Axis is Box0's Z axis
540 SepAxis = A2;
541
542 if (!Oriented_Boxes_Collide_On_Axis(box0,v0,box1,v1,SepAxis,dt)) {
543 intersect = false;
544 goto exit;
545 }
546
548 // L = B0
549 // Separating Axis is Box1's X axis
551 SepAxis = B0;
552
553 if (!Oriented_Boxes_Collide_On_Axis(box0,v0,box1,v1,SepAxis,dt)) {
554 intersect = false;
555 goto exit;
556 }
557
559 // L = B1
560 // Separating Axis is Box1's Y axis
562 SepAxis = B1;
563
564 if (!Oriented_Boxes_Collide_On_Axis(box0,v0,box1,v1,SepAxis,dt)) {
565 intersect = false;
566 goto exit;
567 }
568
570 // L = B2
571 // Separating Axis is Box1's Z axis
573 SepAxis = B2;
574
575 if (!Oriented_Boxes_Collide_On_Axis(box0,v0,box1,v1,SepAxis,dt)) {
576 intersect = false;
577 goto exit;
578 }
579
581 // None of the aligned axes turned out to be separating axes. Now
582 // we check all combinations of cross products of the two boxes axes.
584
586 // L = A0xB0
588 Vector3::Cross_Product(A0,B0,&SepAxis);
589
590 if (!Oriented_Boxes_Collide_On_Axis(box0,v0,box1,v1,SepAxis,dt)) {
591 intersect = false;
592 goto exit;
593 }
594
596 // L = A0xB1
598 Vector3::Cross_Product(A0,B1,&SepAxis);
599
600 if (!Oriented_Boxes_Collide_On_Axis(box0,v0,box1,v1,SepAxis,dt)) {
601 intersect = false;
602 goto exit;
603 }
604
606 // L = A0xB2
608 Vector3::Cross_Product(A0,B2,&SepAxis);
609
610 if (!Oriented_Boxes_Collide_On_Axis(box0,v0,box1,v1,SepAxis,dt)) {
611 intersect = false;
612 goto exit;
613 }
614
616 // L = A1xB0
618 Vector3::Cross_Product(A1,B0,&SepAxis);
619
620 if (!Oriented_Boxes_Collide_On_Axis(box0,v0,box1,v1,SepAxis,dt)) {
621 intersect = false;
622 goto exit;
623 }
624
626 // L = A1xB1
628 Vector3::Cross_Product(A1,B1,&SepAxis);
629
630 if (!Oriented_Boxes_Collide_On_Axis(box0,v0,box1,v1,SepAxis,dt)) {
631 intersect = false;
632 goto exit;
633 }
634
636 // L = A1xB2
638 Vector3::Cross_Product(A1,B2,&SepAxis);
639
640 if (!Oriented_Boxes_Collide_On_Axis(box0,v0,box1,v1,SepAxis,dt)) {
641 intersect = false;
642 goto exit;
643 }
644
646 // L = A2xB0
648 Vector3::Cross_Product(A2,B0,&SepAxis);
649
650 if (!Oriented_Boxes_Collide_On_Axis(box0,v0,box1,v1,SepAxis,dt)) {
651 intersect = false;
652 goto exit;
653 }
654
656 // L = A2xB1
658 Vector3::Cross_Product(A2,B1,&SepAxis);
659
660 if (!Oriented_Boxes_Collide_On_Axis(box0,v0,box1,v1,SepAxis,dt)) {
661 intersect = false;
662 goto exit;
663 }
664
666 // L = A2xB2
668 Vector3::Cross_Product(A2,B2,&SepAxis);
669
670 if (!Oriented_Boxes_Collide_On_Axis(box0,v0,box1,v1,SepAxis,dt)) {
671 intersect = false;
672 goto exit;
673 }
674
675exit:
676
677 return intersect;
678}
679
680
681
682/***********************************************************************************************
683 * Oriented_Box_Intersects_Tri_On_Axis -- tests if the box and tri intersect on the axis *
684 * *
685 * INPUT: *
686 * *
687 * OUTPUT: *
688 * *
689 * WARNINGS: *
690 * *
691 * HISTORY: *
692 * 4/7/99 GTH : Created. *
693 *=============================================================================================*/
695{
696 float leb; // leading edge of box (farthest point from center)
697 float lep; // leading edge of poly (closest point to center)
698 float dist; // distance from box center to v0
699 float tmp;
700
701 if (axis.Length2() < WWMATH_EPSILON) return true;
702
703 Vector3 D = *(tri.V[0]) - box.Center;
704 Vector3 r1 = *(tri.V[1]) - *(tri.V[0]);
705 Vector3 r2 = *(tri.V[2]) - *(tri.V[0]);
706
707 // I want the axis to point from box.center to tri.v0
708 dist = Vector3::Dot_Product(D,axis);
709 if (dist < 0) {
710 dist = -dist;
711 axis = -axis;
712 }
713
714 // compute leading edge of the box
715 leb = box.Project_To_Axis(axis);
716
717 // compute the leading edge of the triangle
718 lep = 0;
719 tmp = Vector3::Dot_Product(r1,axis); if (tmp < lep) lep = tmp;
720 tmp = Vector3::Dot_Product(r2,axis); if (tmp < lep) lep = tmp;
721 lep += dist;
722
723 if (lep >= leb) {
724 return false;
725 } else {
726 return true;
727 }
728}
729
730
731/***********************************************************************************************
732 * Oriented_Box_Intersects_Tri -- tests if the given box and tri intersect *
733 * *
734 * INPUT: *
735 * *
736 * OUTPUT: *
737 * *
738 * WARNINGS: *
739 * *
740 * HISTORY: *
741 * 4/7/99 GTH : Created. *
742 *=============================================================================================*/
744{
745 Vector3 axis;
746
747 // vectors for the axis directions of the two boxes in world space
748 Vector3 A[3];
749 Vector3 E[3];
750 Vector3 normal = *tri.N;
751 A[0].Set(box.Basis[0][0],box.Basis[1][0],box.Basis[2][0]);
752 A[1].Set(box.Basis[0][1],box.Basis[1][1],box.Basis[2][1]);
753 A[2].Set(box.Basis[0][2],box.Basis[1][2],box.Basis[2][2]);
754 E[0] = *(tri.V[1]) - *(tri.V[0]);
755 E[1] = *(tri.V[2]) - *(tri.V[1]);
756 E[2] = *(tri.V[0]) - *(tri.V[2]);
757
758 if (!Oriented_Box_Intersects_Tri_On_Axis(box,tri,normal)) return false;
759 if (!Oriented_Box_Intersects_Tri_On_Axis(box,tri,A[0])) return false;
760 if (!Oriented_Box_Intersects_Tri_On_Axis(box,tri,A[1])) return false;
761 if (!Oriented_Box_Intersects_Tri_On_Axis(box,tri,A[2])) return false;
762
763 Vector3::Cross_Product(A[0],E[0],&axis);
764 if (!Oriented_Box_Intersects_Tri_On_Axis(box,tri,axis)) return false;
765
766 Vector3::Cross_Product(A[0],E[1],&axis);
767 if (!Oriented_Box_Intersects_Tri_On_Axis(box,tri,axis)) return false;
768
769 Vector3::Cross_Product(A[0],E[2],&axis);
770 if (!Oriented_Box_Intersects_Tri_On_Axis(box,tri,axis)) return false;
771
772 Vector3::Cross_Product(A[1],E[0],&axis);
773 if (!Oriented_Box_Intersects_Tri_On_Axis(box,tri,axis)) return false;
774
775 Vector3::Cross_Product(A[1],E[1],&axis);
776 if (!Oriented_Box_Intersects_Tri_On_Axis(box,tri,axis)) return false;
777
778 Vector3::Cross_Product(A[1],E[2],&axis);
779 if (!Oriented_Box_Intersects_Tri_On_Axis(box,tri,axis)) return false;
780
781 Vector3::Cross_Product(A[2],E[0],&axis);
782 if (!Oriented_Box_Intersects_Tri_On_Axis(box,tri,axis)) return false;
783
784 Vector3::Cross_Product(A[2],E[1],&axis);
785 if (!Oriented_Box_Intersects_Tri_On_Axis(box,tri,axis)) return false;
786
787 Vector3::Cross_Product(A[2],E[2],&axis);
788 if (!Oriented_Box_Intersects_Tri_On_Axis(box,tri,axis)) return false;
789
790 return true;
791}
Real Normalize(Real valueToNormalize, Real minRange, Real maxRange)
WWINLINE void Swap(Vector2 &a, Vector2 &b)
Definition vector2.h:488
#define WWMATH_EPSILON
Definition wwmath.h:54
OBBoxClass(void)
Definition obbox.h:80
Vector3 Extent
Definition obbox.h:114
void Init_Random(float min_extent=0.5f, float max_extent=1.0f)
Definition obbox.cpp:291
Matrix3x3 Basis
Definition obbox.h:112
void Init_From_Box_Points(Vector3 *points, int num_points)
Definition obbox.cpp:200
Vector3 Center
Definition obbox.h:113
float Project_To_Axis(const Vector3 &axis) const
Definition obbox.h:137
float X
Definition quat.h:60
Definition tri.h:61
const Vector3 * N
Definition tri.h:64
const Vector3 * V[3]
Definition tri.h:65
static WWINLINE float Dot_Product(const Vector3 &a, const Vector3 &b)
Definition vector3.h:293
float X
Definition vector3.h:90
WWINLINE float Length2(void) const
Definition vector3.h:469
float Z
Definition vector3.h:92
float Y
Definition vector3.h:91
void Normalize(void)
Definition vector3.h:417
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
static float Random_Float(void)
Definition wwmath.cpp:78
#define W(x)
Definition generals.cpp:204
bool Oriented_Boxes_Intersect(const OBBoxClass &box0, const OBBoxClass &box1)
Definition obbox.cpp:363
bool Oriented_Boxes_Collide_On_Axis(const OBBoxClass &box0, const Vector3 &v0, const OBBoxClass &box1, const Vector3 &v1, const Vector3 &axis, float dt)
Definition obbox.cpp:444
bool Oriented_Boxes_Collide(const OBBoxClass &box0, const Vector3 &v0, const OBBoxClass &box1, const Vector3 &v1, float dt)
Definition obbox.cpp:488
bool Oriented_Box_Intersects_Tri_On_Axis(const OBBoxClass &box, const TriClass &tri, Vector3 &axis)
Definition obbox.cpp:694
bool Oriented_Boxes_Intersect_On_Axis(const OBBoxClass &box0, const OBBoxClass &box1, const Vector3 &axis)
Definition obbox.cpp:325
bool Oriented_Box_Intersects_Tri(const OBBoxClass &box, const TriClass &tri)
Definition obbox.cpp:743
Matrix3x3 Build_Matrix3(const Quaternion &q)
Definition quat.cpp:805