mirror of
https://github.com/electronicarts/CnC_Renegade.git
synced 2025-12-15 23:21:40 -05:00
Initial commit of Command & Conquer Renegade source code.
This commit is contained in:
201
Code/wwphys/octbox.h
Normal file
201
Code/wwphys/octbox.h
Normal file
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
** 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/***********************************************************************************************
|
||||
*** 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 : WWPhys *
|
||||
* *
|
||||
* $Archive:: /Commando/Code/wwphys/octbox.h $*
|
||||
* *
|
||||
* Original Author:: Greg Hjelstrom *
|
||||
* *
|
||||
* $Author:: Greg_h $*
|
||||
* *
|
||||
* $Modtime:: 11/21/01 2:48p $*
|
||||
* *
|
||||
* $Revision:: 14 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#ifndef OCTBOX_H
|
||||
#define OCTBOX_H
|
||||
|
||||
#include "always.h"
|
||||
#include "obbox.h"
|
||||
#include "rbody.h"
|
||||
|
||||
|
||||
/**
|
||||
** OctBoxClass
|
||||
** This class encapsulates the collision detection algorithms used by Renegade's "rigid-body"
|
||||
** physics. It basically acts like rigid box with a contact zone around it. Contacts are detected
|
||||
** when geometry is within "thickness" distance of the rigid box.
|
||||
*/
|
||||
class OctBoxClass
|
||||
{
|
||||
public:
|
||||
|
||||
OctBoxClass(RigidBodyClass & parent,const OBBoxClass & box);
|
||||
~OctBoxClass(void);
|
||||
|
||||
void Set_Stiffness(float stiffness) { Stiffness = stiffness; }
|
||||
float Get_Stiffness(void) const { return Stiffness; }
|
||||
void Set_Damping(float damping) { Damping = damping; }
|
||||
float Get_Damping(void) const { return Damping; }
|
||||
void Set_Thickness(float thickness);
|
||||
float Get_Thickness(void) { return Thickness; }
|
||||
|
||||
void Update_Contact_Parameters(void);
|
||||
|
||||
enum CollisionResult
|
||||
{
|
||||
RESULT_NO_COLLISION = 0, // this object isn't touching anything
|
||||
RESULT_INTERSECTION, // this object has penetrated another, have to back up
|
||||
RESULT_CONTACT, // no penetration but there is contact.
|
||||
};
|
||||
|
||||
void Set_Transform(const Matrix3D & tm);
|
||||
void Set_Transform(const Quaternion & q,const Vector3 & p);
|
||||
|
||||
bool Is_Intersecting(NonRefPhysListClass * result_list = NULL,bool check_static_objs = true,bool check_dyn_objs = true);
|
||||
bool Is_In_Contact_Zone(void);
|
||||
CollisionResult Compute_Contacts(bool lock_to_centroids = false);
|
||||
|
||||
int Get_Contact_Count(void);
|
||||
const CastResultStruct &Get_Contact(int index);
|
||||
PhysClass * Peek_Contacted_Object(int index);
|
||||
|
||||
void Get_Outer_Bounds(AABoxClass * set_bounds);
|
||||
void Get_Outer_Box(OBBoxClass * set_box) { *set_box = Get_World_Inner_Box(); }
|
||||
void Get_Inner_Box(OBBoxClass * set_box) { *set_box = Get_World_Inner_Box(); set_box->Extent += Vector3(Thickness,Thickness,Thickness); }
|
||||
void Get_Inner_Box(OBBoxClass * set_box, const Quaternion & q, const Vector3 & p);
|
||||
float Get_Extent_Length2() { return InnerBox.Extent.Length2(); }
|
||||
|
||||
public: //protected:
|
||||
|
||||
CollisionResult Internal_Compute_Contacts(bool lock_to_centroids);
|
||||
void Compute_Octant_Contact(int oi,bool lock_to_centroids);
|
||||
|
||||
void Transform_To_World_Space(const Matrix3D & tm);
|
||||
void Transform_To_World_Space(const Quaternion & q,const Vector3 & p);
|
||||
|
||||
void Reset_Contacts(void);
|
||||
void Add_Contact(const CastResultStruct & res,PhysClass * other_obj);
|
||||
|
||||
const OBBoxClass & Get_World_Inner_Box(void) { return WrldInnerBox; }
|
||||
|
||||
/*
|
||||
** Properties
|
||||
*/
|
||||
RigidBodyClass & Parent; // parent object this OctBox is working for
|
||||
OBBoxClass InnerBox; // OBBox for the parent when parent's TM is I
|
||||
float Thickness; // thickness of the "squishy zone"
|
||||
float Stiffness; // spring stiffness to use
|
||||
float Damping; // damping coefficient to use
|
||||
|
||||
Vector3 OctantCenter; // offest to center of octant0 in InnerBox's coord system
|
||||
Vector3 OctantExtent; // extent of the octant boxes
|
||||
|
||||
/*
|
||||
** Current State
|
||||
*/
|
||||
OBBoxClass WrldInnerBox;
|
||||
|
||||
/*
|
||||
** Contact Accumulation
|
||||
*/
|
||||
enum { MAX_CONTACTS = 16 };
|
||||
int ContactCount;
|
||||
CastResultStruct Contacts[MAX_CONTACTS];
|
||||
PhysClass * ContactedObject[MAX_CONTACTS];
|
||||
};
|
||||
|
||||
inline void OctBoxClass::Set_Transform(const Matrix3D & tm)
|
||||
{
|
||||
Transform_To_World_Space(tm);
|
||||
}
|
||||
|
||||
inline void OctBoxClass::Set_Transform(const Quaternion & q,const Vector3 & p)
|
||||
{
|
||||
Transform_To_World_Space(q,p);
|
||||
}
|
||||
|
||||
inline int OctBoxClass::Get_Contact_Count(void)
|
||||
{
|
||||
return ContactCount;
|
||||
}
|
||||
|
||||
inline const CastResultStruct & OctBoxClass::Get_Contact(int index)
|
||||
{
|
||||
static CastResultStruct _no_result;
|
||||
|
||||
if ((index >= 0) && (index < ContactCount)) {
|
||||
return Contacts[index];
|
||||
} else {
|
||||
return _no_result;
|
||||
}
|
||||
}
|
||||
|
||||
inline PhysClass * OctBoxClass::Peek_Contacted_Object(int index)
|
||||
{
|
||||
if ((index >= 0) && (index < ContactCount)) {
|
||||
return ContactedObject[index];
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
inline void OctBoxClass::Transform_To_World_Space(const Matrix3D & tm)
|
||||
{
|
||||
OBBoxClass::Transform(tm,InnerBox,&WrldInnerBox);
|
||||
}
|
||||
|
||||
inline void OctBoxClass::Transform_To_World_Space(const Quaternion & q,const Vector3 & p)
|
||||
{
|
||||
Matrix3D tm(q,p);
|
||||
OBBoxClass::Transform(tm,InnerBox,&WrldInnerBox);
|
||||
}
|
||||
|
||||
inline void OctBoxClass::Reset_Contacts(void)
|
||||
{
|
||||
ContactCount = 0;
|
||||
}
|
||||
|
||||
inline void OctBoxClass::Add_Contact(const CastResultStruct & res,PhysClass * other_obj)
|
||||
{
|
||||
WWASSERT(ContactCount < MAX_CONTACTS);
|
||||
Contacts[ContactCount] = res;
|
||||
ContactedObject[ContactCount] = other_obj;
|
||||
ContactCount++;
|
||||
}
|
||||
|
||||
inline void OctBoxClass::Get_Inner_Box(OBBoxClass * set_box, const Quaternion & q, const Vector3 & p)
|
||||
{
|
||||
Matrix3D tm(q,p);
|
||||
OBBoxClass::Transform(tm,InnerBox,set_box);
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user