/* ** Command & Conquer Renegade(tm) ** Copyright 2025 Electronic Arts Inc. ** ** This program is free software: you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation, either version 3 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program. If not, see . */ /*********************************************************************************************** *** 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 *** *********************************************************************************************** * * * Project Name : wwmath * * * * $Archive:: /Commando/Code/wwmath/obbox.h $* * * * Author:: Greg_h * * * * $Modtime:: 6/29/00 6:51p $* * * * $Revision:: 23 $* * * *---------------------------------------------------------------------------------------------* * Functions: * * OBBoxClass::Transform -- transform an oriented box * * OBBoxClass::Project_To_Axis -- compute projection onto the given axis * * OBBoxClass::Compute_Point -- computes position of a parametricly defined point * * OBBoxClass::Compute_Axis_Aligned_Extent -- computes extent of an AABox enclosing this box * * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ #if defined(_MSC_VER) #pragma once #endif #ifndef OBBOX_H #define OBBOX_H #include "always.h" #include "vector3.h" #include "matrix3.h" #include "matrix3d.h" #include "wwmath.h" #include "castres.h" class TriClass; class AABoxClass; class PlaneClass; /* ** OBBoxClass ** ** Oriented-Bounding-Box Class. ** This is a collision box in world space. ** Center - position of the center of the box ** Extents - size of the box ** Basis - rotation matrix defining the orientation of the box ** ** To find the world space coordinates of the "+x,+y,+z" corner of ** the bounding box you could use this equation: ** Vector3 corner = Center + Basis * Extent; */ class OBBoxClass { public: OBBoxClass(void) { } OBBoxClass(const OBBoxClass & that) : Basis(that.Basis), Center(that.Center), Extent(that.Extent) { } OBBoxClass(const Vector3 & center,const Vector3 & extent) : Basis(1), Center(center), Extent(extent) { } OBBoxClass(const Vector3 & center,const Vector3 & extent,const Matrix3 & basis) : Basis(basis), Center(center), Extent(extent) { } OBBoxClass(const Vector3 * points, int num_points); bool operator== (const OBBoxClass &src); bool operator!= (const OBBoxClass &src); void Init_From_Box_Points(Vector3 * points,int num_points); void Init_Random(float min_extent = 0.5f,float max_extent = 1.0f); float Project_To_Axis(const Vector3 & axis) const; float Volume(void) const { return 2.0*Extent.X * 2.0*Extent.Y * 2.0*Extent.Z; } void Compute_Point(float params[3],Vector3 * set_point) const; void Compute_Axis_Aligned_Extent(Vector3 * set_extent) const; Matrix3 Basis; Vector3 Center; Vector3 Extent; static void Transform(const Matrix3D & tm,const OBBoxClass & in,OBBoxClass * out); }; // Test functions: slow, easy to understand version of box intersection code :) bool Oriented_Boxes_Intersect(const OBBoxClass & box0,const OBBoxClass & box1); bool Oriented_Boxes_Collide(const OBBoxClass & box0,const Vector3 & v0,const OBBoxClass & box1,const Vector3 & v1,float dt); bool Oriented_Box_Intersects_Tri(const OBBoxClass & box,const TriClass & tri); /*********************************************************************************************** * OBBoxClass::Project_To_Axis -- compute projection onto the given axis * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 2/24/98 GTH : Created. * *=============================================================================================*/ inline float OBBoxClass::Project_To_Axis(const Vector3 & axis) const { float x = Extent[0] * Vector3::Dot_Product(axis,Vector3(Basis[0][0],Basis[1][0],Basis[2][0])); float y = Extent[1] * Vector3::Dot_Product(axis,Vector3(Basis[0][1],Basis[1][1],Basis[2][1])); float z = Extent[2] * Vector3::Dot_Product(axis,Vector3(Basis[0][2],Basis[1][2],Basis[2][2])); // projection is the sum of the absolute values of the projections of the three extents return (WWMath::Fabs(x) + WWMath::Fabs(y) + WWMath::Fabs(z)); } /*********************************************************************************************** * OBBoxClass::Transform -- transform an oriented box * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 2/24/98 GTH : Created. * *=============================================================================================*/ inline void OBBoxClass::Transform ( const Matrix3D & tm, const OBBoxClass & in, OBBoxClass * out ) { WWASSERT(out); WWASSERT(out!=&in); out->Extent = in.Extent; Matrix3D::Transform_Vector(tm,in.Center,&(out->Center)); Matrix3::Multiply(tm,in.Basis,&(out->Basis)); } /*********************************************************************************************** * OBBoxClass::Compute_Point -- computes position of a parametricly defined point * * * * set_point = Center + params[0]*A0 + params[1]*A1 + params[2]*A2 * * * * INPUT: * * params - parametric description of a point in the box. -1 < params[i] < 1 * * set_point - pointer to a Vector3 to set. * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 4/2/99 GTH : Created. * *=============================================================================================*/ inline void OBBoxClass::Compute_Point(float params[3],Vector3 * set_point) const { Vector3 point = Extent; point.X *= params[0]; point.Y *= params[1]; point.Z *= params[2]; Matrix3::Rotate_Vector(Basis,point,set_point); Vector3::Add(Center,*set_point,set_point); } /*********************************************************************************************** * OBBoxClass::Compute_Axis_Aligned_Extent -- computes extent of an AABox enclosing this box * * * * INPUT: * * set_extent - pointer to a Vector3 to put the result into * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 11/15/99 gth : Created. * *=============================================================================================*/ inline void OBBoxClass::Compute_Axis_Aligned_Extent(Vector3 * set_extent) const { WWASSERT(set_extent != NULL); // x extent is the box projected onto the x axis set_extent->X = WWMath::Fabs(Extent[0] * Basis[0][0]) + WWMath::Fabs(Extent[1] * Basis[0][1]) + WWMath::Fabs(Extent[2] * Basis[0][2]); set_extent->Y = WWMath::Fabs(Extent[0] * Basis[1][0]) + WWMath::Fabs(Extent[1] * Basis[1][1]) + WWMath::Fabs(Extent[2] * Basis[1][2]); set_extent->Z = WWMath::Fabs(Extent[0] * Basis[2][0]) + WWMath::Fabs(Extent[1] * Basis[2][1]) + WWMath::Fabs(Extent[2] * Basis[2][2]); } /*********************************************************************************************** * OBBoxClass::operator== -- Comparison operator * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 6/21/00 PDS : Created. * *=============================================================================================*/ inline bool OBBoxClass::operator== (const OBBoxClass &src) { return (Center == src.Center) && (Extent == src.Extent) && (Basis == src.Basis); } /*********************************************************************************************** * OBBoxClass::operator!= -- Comparison operator * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 6/21/00 PDS : Created. * *=============================================================================================*/ inline bool OBBoxClass::operator!= (const OBBoxClass &src) { return (Center != src.Center) || (Extent != src.Extent) && (Basis == src.Basis); } #endif