This repository has been archived on 2025-02-27. You can view files and clone it, but cannot push or open issues or pull requests.
CnC_Renegade/Code/wwphys/animcollisionmanager.h

288 lines
10 KiB
C++

/*
** 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/animcollisionmanager.h $*
* *
* Original Author:: Greg Hjelstrom *
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 9/09/01 2:44p $*
* *
* $Revision:: 13 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef ANIMCOLLISIONMANAGER_H
#define ANIMCOLLISIONMANAGER_H
#include "always.h"
#include "ridermanager.h"
#include "matrix3d.h"
#include "vector.h"
#include "rendobj.h"
#include "wwstring.h"
class AnimCollisionManagerDefClass;
class HAnimClass;
class ChunkSaveClass;
class ChunkLoadClass;
class BitStreamClass;
class PushRecordClass;
/**
** AnimCollisionManagerClass
** The job of this class is to handle collisions which are caused by animations. Some examples
** of this are: elevators, doors, and "cinematic events". StaticAnimPhysClass and DynamicAnimPhysClass
** both use this code to handle collisions with the dynamic objects in the scene.
*/
class AnimCollisionManagerClass
{
public:
AnimCollisionManagerClass(PhysClass & parent);
~AnimCollisionManagerClass(void);
/*
** Initialization
*/
void Init(const AnimCollisionManagerDefClass & def);
void Update_Cached_Model_Parameters(void);
/*
** Simulation, moves the animation forward, checks for animated collisions, updates riders
** Returns true if the object's animation pose changed.
*/
bool Timestep(float dt);
/*
** Animation Controls
*/
enum AnimModeType
{
ANIMATE_LOOP = 0,
ANIMATE_TARGET,
ANIMATE_MANUAL,
};
void Set_Animation_Mode(AnimModeType mode);
AnimModeType Get_Animation_Mode(void);
void Set_Animation(const char * anim_name);
HAnimClass * Peek_Animation(void);
void Set_Target_Frame(float frame);
void Set_Target_Frame_End(void);
float Get_Target_Frame(void);
bool Is_At_Target(void);
void Set_Current_Frame(float frame);
float Get_Current_Frame(void);
void Set_Loop_Start(float frame0);
void Set_Loop_End(float frame1);
float Get_Loop_Start(void);
float Get_Loop_End(void);
/*
** Collision Control
*/
enum CollisionModeType
{
COLLIDE_NONE = 0,
COLLIDE_STOP,
COLLIDE_PUSH,
COLLIDE_KILL,
};
void Set_Collision_Mode(CollisionModeType mode);
CollisionModeType Get_Collision_Mode(void);
/*
** Rider Support
*/
bool Link_Rider(PhysClass * rider) { RiderManager.Link_Rider(rider); return true; }
bool Unlink_Rider(PhysClass * rider) { RiderManager.Unlink_Rider(rider); return true; }
/*
** Save/Load Support
*/
bool Save(ChunkSaveClass &csave);
bool Load(ChunkLoadClass &cload);
protected:
/*
** Multi-mesh collision detection support
*/
class CollideableObjClass
{
public:
CollideableObjClass(void);
CollideableObjClass(RenderObjClass * collisionmesh);
CollideableObjClass(const CollideableObjClass & that);
~CollideableObjClass(void);
CollideableObjClass & operator = (const CollideableObjClass & that);
bool operator == (const CollideableObjClass & that) const { return false; }
bool operator != (const CollideableObjClass & that) const { return true; }
void Set_Collision_Object(RenderObjClass * mesh);
RenderObjClass * Peek_Collision_Object(void) { return CollisionMesh; }
void Cache_Start_Transform(void) { StartTransform = CollisionMesh->Get_Transform(); }
void Cache_End_Transform(void) { EndTransform = CollisionMesh->Get_Transform(); }
Matrix3D & Get_Start_Transform(void) { return StartTransform; }
Matrix3D & Get_End_Transform(void) { return EndTransform; }
void Install_Start_Transform(void) { CollisionMesh->Set_Transform(StartTransform); }
void Install_End_Transform(void) { CollisionMesh->Set_Transform(EndTransform); }
void Intersect_Scene(int colgroup,NonRefPhysListClass * list);
int Clear_Collision_Bits(void);
void Restore_Collision_Bits(int oldbits);
protected:
RenderObjClass * CollisionMesh;
Matrix3D StartTransform;
Matrix3D EndTransform;
};
/*
** Internal functions
*/
bool Is_Collision_Model(RenderObjClass * model);
int Recursive_Count_Collision_Models(RenderObjClass * model);
void Recursive_Collect_Collision_Models(RenderObjClass * model);
void Revert_Animation_State(void);
bool Check_Collision(CollideableObjClass & collisionobj);
bool Is_Intersecting(void);
bool Push_Collided_Object(PhysClass * obj,const Matrix3D & delta_transform);
void Internal_Set_Animation(const char * anim_name);
/*
** Parent reference
*/
PhysClass & Parent;
/*
** Animation support
*/
AnimModeType AnimationMode; // current animation mode and parameters.
float TargetFrame;
float LoopStart;
float LoopEnd;
HAnimClass * CurAnimation; // current animation state.
float CurFrame;
HAnimClass * PrevAnimation; // temporary variable used in timestep
float PrevFrame; // temporary variable used in timestep
/*
** Attached riders support
*/
RiderManagerClass RiderManager;
/*
** Animated collision support
*/
CollisionModeType CollisionMode;
DynamicVectorClass<CollideableObjClass> CollisionMeshes;
/*
** Revert list, In the case that we have to revert our animation state,
** we have to undo all changes to external objects.
*/
PushRecordClass * PushList;
};
/**
** AnimCollisionManagerDefClass
** This class is meant to be a component of a definition class for a physics object
** which has an AnimCollisionManager. The member variables of this class are public since
** various physics def classes make them directly editable.
*/
class AnimCollisionManagerDefClass
{
public:
AnimCollisionManagerDefClass(void);
~AnimCollisionManagerDefClass(void);
void Validate_Parameters(void);
bool Save(ChunkSaveClass &csave);
bool Load(ChunkLoadClass &cload);
public:
int CollisionMode;
int AnimationMode;
StringClass AnimationName;
};
/*
** Use this macro to make all of the member variables in an AnimCollisionManagerDefClass editable.
** The first parameter to the macro is the type-name of your class (e.g. StaticAnimPhysDefClass) and
** the second parameter is the name of the member variable which is the animation manager (e.g. AnimManager).
*/
#ifdef PARAM_EDITING_ON
#define ANIMCOLLISIONMANAGERDEF_EDITABLE_PARAMS( class_name, member_name ) \
PARAM_SEPARATOR( class_name, "Animation Settings"); \
EnumParameterClass *collision_param = new EnumParameterClass(& member_name ## .CollisionMode); \
collision_param->Set_Name ("CollisionMode"); \
collision_param->Add_Value("NONE",AnimCollisionManagerClass::COLLIDE_NONE); \
collision_param->Add_Value("STOP",AnimCollisionManagerClass::COLLIDE_STOP); \
collision_param->Add_Value("PUSH",AnimCollisionManagerClass::COLLIDE_PUSH); \
collision_param->Add_Value("KILL",AnimCollisionManagerClass::COLLIDE_KILL); \
GENERIC_EDITABLE_PARAM( class_name , collision_param); \
\
EnumParameterClass *anim_param = new EnumParameterClass(& member_name ## .AnimationMode); \
anim_param->Set_Name ("AnimationMode"); \
anim_param->Add_Value("LOOP",AnimCollisionManagerClass::ANIMATE_LOOP); \
anim_param->Add_Value("TARGET",AnimCollisionManagerClass::ANIMATE_TARGET); \
anim_param->Add_Value("MANUAL",AnimCollisionManagerClass::ANIMATE_MANUAL); \
GENERIC_EDITABLE_PARAM( class_name , anim_param); \
\
NAMED_EDITABLE_PARAM( class_name, ParameterClass::TYPE_STRING, member_name ## .AnimationName,"AnimationName"); \
#else
#define ANIMCOLLISIONMANAGERDEF_EDITABLE_PARAMS( class_name, member_name )
#endif
#endif //ANIMCOLLISIONMANAGER_H