Richard Boegli's CnC_Generals_Zero_Hour Fork WIP
This is documentation of Richard Boegil's Zero Hour Fork
 
Loading...
Searching...
No Matches
aabox.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 : WWMath *
24 * *
25 * $Archive:: /Commando/Code/wwmath/aabox.h $*
26 * *
27 * Author:: Greg_h *
28 * *
29 * $Modtime:: 5/08/01 6:35p $*
30 * *
31 * $Revision:: 30 $*
32 * *
33 *---------------------------------------------------------------------------------------------*
34 * Functions: *
35 * AABoxClass::Transform -- transform an aabox *
36 * AABoxClass::Translate -- transform an aabox *
37 * AABoxClass::Init -- create a box which bounds the given points *
38 * AABoxClass::Init -- initialize from a min-max form of a box *
39 * AABoxClass::Init_Min_Max -- init the box from a min and max vector *
40 * AABoxClass::Add_Point -- expand the box to contain the given point *
41 * AABoxClass::Project_To_Axis -- compute projection onto the given axis *
42 * AABoxClass::Intersects -- test for intersection with another static aabox *
43 * AABoxClass::Add_Box -- expand this box to enclose the passed box *
44 * AABoxClass::Add_Box -- Expand this box to enclose the passed box *
45 * MinMaxAABoxClass::Init -- init the box from an array of points *
46 * MinMaxAABoxClass::Init -- initializes this box from a center-extent box *
47 * MinMaxAABoxClass::Add_Point -- updates this box so it encloses the given point *
48 * MinMaxAABoxClass::Add_Box -- update this box to enclose the given box *
49 * MinMaxAABoxClass::Add_Box -- Updates this box to enclose the specified box *
50 * MinMaxAABoxClass::Transform -- Updates this box to enclose its transformed version *
51 * MinMaxAABoxClass::Translate -- translates the box *
52 * AABoxClass::Init -- Init from a line segment *
53 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
54
55#if defined(_MSC_VER)
56#pragma once
57#endif
58
59#ifndef AABOX_H
60#define AABOX_H
61
62#include "always.h"
63#include "matrix3d.h"
64#include "lineseg.h"
65#include "colmath.h"
66
67class AABoxClass;
69class OBBoxClass;
70class TriClass;
71class PlaneClass;
72struct CastResultStruct;
73
74
75/*
76** AABoxClass
77**
78** Axis-Aligned Boxes. I've coded these similar to the OrientedBoxClass only
79** without a rotation matrix. A similar algorithm is used to test the box
80** for intersection.
81*/
83{
84
85public:
86
88
89 WWINLINE AABoxClass(const Vector3 & center,const Vector3 & extent) :
90 Center(center),
91 Extent(extent)
92 { }
93
94 AABoxClass(const MinMaxAABoxClass & minmaxbox) { Init(minmaxbox); }
95
96 AABoxClass(Vector3 * points,int num) { Init(points,num); }
97
98 bool operator== (const AABoxClass &src);
99 bool operator!= (const AABoxClass &src);
100
101 WWINLINE void Init(const Vector3& center,const Vector3 & extent) { Center = center; Extent = extent; }
102 WWINLINE void Init(Vector3 * points,int num);
103 WWINLINE void Init(const MinMaxAABoxClass & minmaxbox);
104 void Init(const LineSegClass & line);
105 void Init_Min_Max(const Vector3 & min,const Vector3 & max);
106 void Init_Random(float min_center = -1.0f,float max_center = 1.0f,float min_extent = 0.5f,float max_extent = 1.0f);
107
108 void Add_Point(const Vector3 & point);
109 void Add_Box(const AABoxClass & b);
110 void Add_Box(const MinMaxAABoxClass & b);
111 float Project_To_Axis(const Vector3 & axis) const;
112
113 void Transform(const Matrix3D & tm);
114 void Translate(const Vector3 & pos);
115
116 WWINLINE float Volume(void) const { return 2.0*Extent.X * 2.0*Extent.Y * 2.0*Extent.Z; }
117 WWINLINE bool Contains(const Vector3 & point) const;
118 WWINLINE bool Contains(const AABoxClass & other_box) const;
119 WWINLINE bool Contains(const MinMaxAABoxClass & other_box) const;
120
121 static void Transform(const Matrix3D & tm,const AABoxClass & in,AABoxClass * out);
122
123 Vector3 Center; // world space center
124 Vector3 Extent; // size of the box in the three directions
125
126};
127
128/*
129** MinMaxAABoxClass
130** This is another form of an AABox. It can be faster to build one of these
131** and then convert it into a center-extent AABox in some cases. Its purpose
132** is basically that.
133*/
135{
136public:
137
139
140 WWINLINE MinMaxAABoxClass(const Vector3 & min_corner,const Vector3 & max_corner) :
141 MinCorner(min_corner),
142 MaxCorner(max_corner)
143 {
144 }
145
146 WWINLINE MinMaxAABoxClass(Vector3 * points,int num) { Init(points,num); }
147
148 WWINLINE MinMaxAABoxClass(const AABoxClass & that) { Init(that); }
149
150 WWINLINE void Init(Vector3 * points,int num);
151 WWINLINE void Init(const AABoxClass & box);
152 void Init_Empty(void);
153
154 void Add_Point(const Vector3 & point);
155 void Add_Box(const MinMaxAABoxClass & box);
156 void Add_Box(const AABoxClass & box);
157 void Add_Box(const Vector3 & min_corner,const Vector3 & max_corner);
158
159 void Transform(const Matrix3D & tm);
160 void Translate(const Vector3 & pos);
161
162 WWINLINE float Volume(void) const { Vector3 size = MaxCorner - MinCorner; return size.X*size.Y*size.Z; }
163
166};
167
168
169
170
171/***********************************************************************************************
172 * AABoxClass::Transform -- transform an aabox *
173 * *
174 * Note that this function expands the box to enclose its transformed form. *
175 * *
176 * INPUT: *
177 * *
178 * OUTPUT: *
179 * *
180 * WARNINGS: *
181 * *
182 * HISTORY: *
183 * 2/24/98 GTH : Created. *
184 *=============================================================================================*/
186{
187 Vector3 oldcenter = Center;
188 Vector3 oldextent = Extent;
189 tm.Transform_Center_Extent_AABox(oldcenter,oldextent,&Center,&Extent);
190}
191
192
193/***********************************************************************************************
194 * AABoxClass::Translate -- translate an aabox *
195 * *
196 * INPUT: *
197 * *
198 * OUTPUT: *
199 * *
200 * WARNINGS: *
201 * *
202 * HISTORY: *
203 * 2/24/98 GTH : Created. *
204 *=============================================================================================*/
206{
207 Center += trans;
208}
209
210
211/***********************************************************************************************
212 * AABoxClass::operator== -- Comparison operator *
213 * *
214 * INPUT: *
215 * *
216 * OUTPUT: *
217 * *
218 * WARNINGS: *
219 * *
220 * HISTORY: *
221 * 6/21/00 PDS : Created. *
222 *=============================================================================================*/
224{
225 return (Center == src.Center) && (Extent == src.Extent);
226}
227
228
229/***********************************************************************************************
230 * AABoxClass::operator!= -- Comparison operator *
231 * *
232 * INPUT: *
233 * *
234 * OUTPUT: *
235 * *
236 * WARNINGS: *
237 * *
238 * HISTORY: *
239 * 6/21/00 PDS : Created. *
240 *=============================================================================================*/
242{
243 return (Center != src.Center) || (Extent != src.Extent);
244}
245
246
247/***********************************************************************************************
248 * AABoxClass::Init -- create a box which bounds the given points *
249 * *
250 * INPUT: *
251 * *
252 * OUTPUT: *
253 * *
254 * WARNINGS: *
255 * *
256 * HISTORY: *
257 * 2/24/98 GTH : Created. *
258 *=============================================================================================*/
259WWINLINE void AABoxClass::Init(Vector3 * points,int num)
260{
261 Vector3 Min = points[0];
262 Vector3 Max = points[0];
263
264 for (int i=1; i<num; i++) {
265 if (Min.X > points[i].X) Min.X = points[i].X;
266 if (Min.Y > points[i].Y) Min.Y = points[i].Y;
267 if (Min.Z > points[i].Z) Min.Z = points[i].Z;
268
269 if (Max.X < points[i].X) Max.X = points[i].X;
270 if (Max.Y < points[i].Y) Max.Y = points[i].Y;
271 if (Max.Z < points[i].Z) Max.Z = points[i].Z;
272 }
273
274 Center = (Max + Min) * 0.5f;
275 Extent = (Max - Min) * 0.5f;
276}
277
278
279/***********************************************************************************************
280 * AABoxClass::Init -- initialize from a min-max form of a box *
281 * *
282 * INPUT: *
283 * *
284 * OUTPUT: *
285 * *
286 * WARNINGS: *
287 * *
288 * HISTORY: *
289 * 7/31/98 GTH : Created. *
290 *=============================================================================================*/
292{
293 Center = (mmbox.MaxCorner + mmbox.MinCorner) * 0.5f;
294 Extent = (mmbox.MaxCorner - mmbox.MinCorner) * 0.5f;
295}
296
297
298/***********************************************************************************************
299 * AABoxClass::Init -- Init from a line segment *
300 * *
301 * INPUT: *
302 * *
303 * OUTPUT: *
304 * *
305 * WARNINGS: *
306 * *
307 * HISTORY: *
308 * 4/27/2000 gth : Created. *
309 *=============================================================================================*/
311{
312 Vector3 min_corner = line.Get_P0();
313 Vector3 max_corner = line.Get_P0();
314
315 if (min_corner.X > line.Get_P1().X) min_corner.X = line.Get_P1().X;
316 if (min_corner.Y > line.Get_P1().Y) min_corner.Y = line.Get_P1().Y;
317 if (min_corner.Z > line.Get_P1().Z) min_corner.Z = line.Get_P1().Z;
318
319 if (max_corner.X < line.Get_P1().X) max_corner.X = line.Get_P1().X;
320 if (max_corner.Y < line.Get_P1().Y) max_corner.Y = line.Get_P1().Y;
321 if (max_corner.Z < line.Get_P1().Z) max_corner.Z = line.Get_P1().Z;
322
323 Center = (max_corner + min_corner) * 0.5f;
324 Extent = (max_corner - min_corner) * 0.5f;
325}
326
327/***********************************************************************************************
328 * AABoxClass::Init_Min_Max -- init the box from a min and max vector *
329 * *
330 * INPUT: *
331 * *
332 * OUTPUT: *
333 * *
334 * WARNINGS: *
335 * *
336 * HISTORY: *
337 * 4/9/99 GTH : Created. *
338 *=============================================================================================*/
340{
341 Center = (max + min) * 0.5f;
342 Extent = (max - min) * 0.5f;
343}
344
345
346/***********************************************************************************************
347 * AABoxClass::Add_Point -- expand the box to contain the given point *
348 * *
349 * INPUT: *
350 * *
351 * OUTPUT: *
352 * *
353 * WARNINGS: *
354 * *
355 * HISTORY: *
356 * 2/24/98 GTH : Created. *
357 *=============================================================================================*/
359{
360 Vector3 Min = Center - Extent;
361 Vector3 Max = Center + Extent;
362
363 if (Min.X > point.X) Min.X = point.X;
364 if (Min.Y > point.Y) Min.Y = point.Y;
365 if (Min.Z > point.Z) Min.Z = point.Z;
366
367 if (Max.X < point.X) Max.X = point.X;
368 if (Max.Y < point.Y) Max.Y = point.Y;
369 if (Max.Z < point.Z) Max.Z = point.Z;
370
371 Center = (Max + Min) / 2.0f;
372 Extent = (Max - Min) / 2.0f;
373}
374
375
376/***********************************************************************************************
377 * AABoxClass::Add_Box -- expand this box to enclose the passed box *
378 * *
379 * INPUT: *
380 * *
381 * OUTPUT: *
382 * *
383 * WARNINGS: *
384 * *
385 * HISTORY: *
386 * 7/31/98 GTH : Created. *
387 * 9/29/2000 gth : Ok to add boxes with zero extent *
388 *=============================================================================================*/
390{
391 Vector3 newmin = Center - Extent;
392 Vector3 newmax = Center + Extent;
393 newmin.Update_Min(b.Center - b.Extent);
394 newmax.Update_Max(b.Center + b.Extent);
395
396 Center = (newmax + newmin) * 0.5f;
397 Extent = (newmax - newmin) * 0.5f;
398}
399
400
401/***********************************************************************************************
402 * AABoxClass::Add_Box -- Expand this box to enclose the passed box *
403 * *
404 * INPUT: *
405 * *
406 * OUTPUT: *
407 * *
408 * WARNINGS: *
409 * *
410 * HISTORY: *
411 * 7/31/98 GTH : Created. *
412 * 9/29/2000 gth : Ok to add boxes with zero extent *
413 *=============================================================================================*/
415{
416 Vector3 newmin = Center - Extent;
417 Vector3 newmax = Center + Extent;
418 newmin.Update_Min(b.MinCorner);
419 newmax.Update_Max(b.MaxCorner);
420
421 Center = (newmax + newmin) * 0.5f;
422 Extent = (newmax - newmin) * 0.5f;
423}
424
425/***********************************************************************************************
426 * AABoxClass::Project_To_Axis -- compute projection onto the given axis *
427 * *
428 * INPUT: *
429 * *
430 * OUTPUT: *
431 * *
432 * WARNINGS: *
433 * *
434 * HISTORY: *
435 * 2/24/98 GTH : Created. *
436 *=============================================================================================*/
438{
439 float x = Extent[0] * axis[0];
440 float y = Extent[1] * axis[1];
441 float z = Extent[2] * axis[2];
442
443 // projection is the sum of the absolute values of the projections of the three extents
444 return (WWMath::Fabs(x) + WWMath::Fabs(y) + WWMath::Fabs(z));
445}
446
447/***********************************************************************************************
448 * AABoxClass::Contains -- Test whether this box contains the given box *
449 * *
450 * INPUT: *
451 * *
452 * OUTPUT: *
453 * *
454 * WARNINGS: *
455 * *
456 * HISTORY: *
457 * 9/2/98 GTH : Created. *
458 *=============================================================================================*/
459WWINLINE bool AABoxClass::Contains(const AABoxClass & other_box) const
460{
461 return CollisionMath::Overlap_Test(*this,other_box) == CollisionMath::INSIDE;
462}
463
464/***********************************************************************************************
465 * AABoxClass::Contains -- Test whether this box contains the given box *
466 * *
467 * INPUT: *
468 * *
469 * OUTPUT: *
470 * *
471 * WARNINGS: *
472 * *
473 * HISTORY: *
474 * 9/2/98 GTH : Created. *
475 *=============================================================================================*/
476WWINLINE bool AABoxClass::Contains(const MinMaxAABoxClass & other_box) const
477{
478 Vector3 bmin = Center - Extent;
479 Vector3 bmax = Center + Extent;
480
481 if (other_box.MinCorner.X < bmin.X) return false;
482 if (other_box.MinCorner.Y < bmin.Y) return false;
483 if (other_box.MinCorner.Z < bmin.Z) return false;
484
485 if (other_box.MaxCorner.X > bmax.X) return false;
486 if (other_box.MaxCorner.Y > bmax.Y) return false;
487 if (other_box.MaxCorner.Z > bmax.Z) return false;
488
489 return true;
490}
491
492/***********************************************************************************************
493 * AABoxClass::Contains -- test whether this box contains the given point *
494 * *
495 * INPUT: *
496 * *
497 * OUTPUT: *
498 * *
499 * WARNINGS: *
500 * *
501 * HISTORY: *
502 * 9/2/98 GTH : Created. *
503 *=============================================================================================*/
504WWINLINE bool AABoxClass::Contains(const Vector3 & point) const
505{
507}
508
509/***********************************************************************************************
510 * MinMaxAABoxClass::Init -- init the box from an array of points *
511 * *
512 * Makes a box which encloses the given array of points *
513 * *
514 * INPUT: *
515 * *
516 * OUTPUT: *
517 * *
518 * WARNINGS: *
519 * *
520 * HISTORY: *
521 * 7/31/98 GTH : Created. *
522 *=============================================================================================*/
524{
525 assert(num > 0);
526 assert(points != NULL);
527 MinCorner = points[0];
528 MaxCorner = points[0];
529 for (int i=0; i<num; i++) {
530 MinCorner.Update_Min(points[i]);
531 MaxCorner.Update_Max(points[i]);
532 }
533}
534
535
536/***********************************************************************************************
537 * MinMaxAABoxClass::Init -- initializes this box from a center-extent box *
538 * *
539 * INPUT: *
540 * *
541 * OUTPUT: *
542 * *
543 * WARNINGS: *
544 * *
545 * HISTORY: *
546 * 7/31/98 GTH : Created. *
547 *=============================================================================================*/
549{
550 MinCorner = box.Center - box.Extent;
551 MaxCorner = box.Center + box.Extent;
552}
553
554
555/***********************************************************************************************
556 * MinMaxAABoxClass::Add_Point -- updates this box so it encloses the given point *
557 * *
558 * INPUT: *
559 * *
560 * OUTPUT: *
561 * *
562 * WARNINGS: *
563 * *
564 * HISTORY: *
565 * 7/31/98 GTH : Created. *
566 *=============================================================================================*/
568{
569 MinCorner.Update_Min(point);
570 MaxCorner.Update_Max(point);
571}
572
573
574/***********************************************************************************************
575 * MinMaxAABoxClass::Add_Box -- update this box to enclose the given box *
576 * *
577 * INPUT: *
578 * *
579 * OUTPUT: *
580 * *
581 * WARNINGS: *
582 * *
583 * HISTORY: *
584 * 7/31/98 GTH : Created. *
585 *=============================================================================================*/
587{
588 if (box.MinCorner == box.MaxCorner) return;
589
590 MinCorner.Update_Min(box.MinCorner);
591 MaxCorner.Update_Max(box.MaxCorner);
592}
593
594
595/***********************************************************************************************
596 * MinMaxAABoxClass::Add_Box -- update this box to enclose the given box *
597 * *
598 * INPUT: *
599 * *
600 * OUTPUT: *
601 * *
602 * WARNINGS: *
603 * *
604 * HISTORY: *
605 * 7/31/98 GTH : Created. *
606 *=============================================================================================*/
608{
609 if (box.Extent == Vector3(0.0f, 0.0f, 0.0f)) return;
610
611 MinCorner.Update_Min(box.Center - box.Extent);
612 MaxCorner.Update_Max(box.Center + box.Extent);
613}
614
615/***********************************************************************************************
616 * MinMaxAABoxClass::Add_Box -- Updates this box to enclose the specified box *
617 * *
618 * INPUT: *
619 * *
620 * OUTPUT: *
621 * *
622 * WARNINGS: *
623 * *
624 * HISTORY: *
625 * 7/31/98 GTH : Created. *
626 *=============================================================================================*/
627WWINLINE void MinMaxAABoxClass::Add_Box(const Vector3 & min_corner,const Vector3 & max_corner)
628{
629 assert(max_corner.X >= min_corner.X);
630 assert(max_corner.Y >= min_corner.Y);
631 assert(max_corner.Z >= min_corner.Z);
632
633 if (min_corner == max_corner) return;
634
635 MinCorner.Update_Min(min_corner);
636 MaxCorner.Update_Max(max_corner);
637}
638
639
640/***********************************************************************************************
641 * MinMaxAABoxClass::Transform -- Updates this box to enclose its transformed version *
642 * *
643 * INPUT: *
644 * *
645 * OUTPUT: *
646 * *
647 * WARNINGS: *
648 * *
649 * HISTORY: *
650 * 7/31/98 GTH : Created. *
651 *=============================================================================================*/
653{
654 Vector3 oldmin = MinCorner;
655 Vector3 oldmax = MaxCorner;
656 tm.Transform_Min_Max_AABox(oldmin,oldmax,&MinCorner,&MaxCorner);
657}
658
659
660/***********************************************************************************************
661 * MinMaxAABoxClass::Translate -- translates the box *
662 * *
663 * INPUT: *
664 * *
665 * OUTPUT: *
666 * *
667 * WARNINGS: *
668 * *
669 * HISTORY: *
670 * 7/31/98 GTH : Created. *
671 *=============================================================================================*/
673{
674 MinCorner+=pos;
675 MaxCorner+=pos;
676}
677
678
679#endif
#define NULL
Definition BaseType.h:92
#define min(x, y)
Definition BaseType.h:101
#define max(x, y)
Definition BaseType.h:105
#define WWINLINE
Definition always.h:172
WWINLINE AABoxClass(const Vector3 &center, const Vector3 &extent)
Definition aabox.h:89
WWINLINE void Init(const Vector3 &center, const Vector3 &extent)
Definition aabox.h:101
void Add_Point(const Vector3 &point)
Definition aabox.h:358
bool operator!=(const AABoxClass &src)
Definition aabox.h:241
WWINLINE float Volume(void) const
Definition aabox.h:116
void Translate(const Vector3 &pos)
Definition aabox.h:205
void Transform(const Matrix3D &tm)
Definition aabox.h:185
float Project_To_Axis(const Vector3 &axis) const
Definition aabox.h:437
Vector3 Center
Definition aabox.h:123
void Init_Min_Max(const Vector3 &min, const Vector3 &max)
Definition aabox.h:339
AABoxClass(const MinMaxAABoxClass &minmaxbox)
Definition aabox.h:94
Vector3 Extent
Definition aabox.h:124
WWINLINE AABoxClass(void)
Definition aabox.h:87
WWINLINE bool Contains(const Vector3 &point) const
Definition aabox.h:504
bool operator==(const AABoxClass &src)
Definition aabox.h:223
void Add_Box(const AABoxClass &b)
Definition aabox.h:389
AABoxClass(Vector3 *points, int num)
Definition aabox.h:96
void Init_Random(float min_center=-1.0f, float max_center=1.0f, float min_extent=0.5f, float max_extent=1.0f)
Definition aabox.cpp:58
static OverlapType Overlap_Test(const AAPlaneClass &plane, const Vector3 &point)
const Vector3 & Get_P1() const
Definition lineseg.h:71
const Vector3 & Get_P0() const
Definition lineseg.h:70
void Transform_Min_Max_AABox(const Vector3 &min, const Vector3 &max, Vector3 *set_min, Vector3 *set_max) const
Definition matrix3d.cpp:999
void Transform_Center_Extent_AABox(const Vector3 &center, const Vector3 &extent, Vector3 *set_center, Vector3 *set_extent) const
WWINLINE float Volume(void) const
Definition aabox.h:162
void Add_Box(const MinMaxAABoxClass &box)
Definition aabox.h:586
void Add_Point(const Vector3 &point)
Definition aabox.h:567
Vector3 MinCorner
Definition aabox.h:164
void Init_Empty(void)
Definition aabox.cpp:75
WWINLINE MinMaxAABoxClass(void)
Definition aabox.h:138
WWINLINE void Init(Vector3 *points, int num)
Definition aabox.h:523
WWINLINE MinMaxAABoxClass(Vector3 *points, int num)
Definition aabox.h:146
WWINLINE MinMaxAABoxClass(const AABoxClass &that)
Definition aabox.h:148
Vector3 MaxCorner
Definition aabox.h:165
void Transform(const Matrix3D &tm)
Definition aabox.h:652
void Translate(const Vector3 &pos)
Definition aabox.h:672
WWINLINE MinMaxAABoxClass(const Vector3 &min_corner, const Vector3 &max_corner)
Definition aabox.h:140
Definition tri.h:61
float X
Definition vector3.h:90
WWINLINE void Update_Max(const Vector3 &a)
Definition vector3.h:617
WWINLINE void Update_Min(const Vector3 &a)
Definition vector3.h:597
float Z
Definition vector3.h:92
float Y
Definition vector3.h:91
static WWINLINE float Fabs(float val)
Definition wwmath.h:113