241 lines
8.7 KiB
C++
241 lines
8.7 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/>.
|
|
*/
|
|
|
|
/* $Header: /Commando/Code/wwphys/physcon.cpp 13 9/20/01 5:12p Greg_h $ */
|
|
/***********************************************************************************************
|
|
*** Confidential - Westwood Studios ***
|
|
***********************************************************************************************
|
|
* *
|
|
* Project Name : Commando *
|
|
* *
|
|
* $Archive:: /Commando/Code/wwphys/physcon.cpp $*
|
|
* *
|
|
* Author:: Greg_h *
|
|
* *
|
|
* $Modtime:: 9/19/01 7:56p $*
|
|
* *
|
|
* $Revision:: 13 $*
|
|
* *
|
|
*---------------------------------------------------------------------------------------------*
|
|
* Functions: *
|
|
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
|
|
|
|
|
#include "physcon.h"
|
|
#include "chunkio.h"
|
|
#include "wwdebug.h"
|
|
#include "w3d_file.h"
|
|
|
|
|
|
/*
|
|
** Static instance of PhysicsConstants so that the constructor gets called and all arrays are filled
|
|
*/
|
|
static PhysicsConstants _PhysicsConstantsObject;
|
|
|
|
|
|
/*
|
|
** Physics Constants - see the header file for explanation
|
|
*/
|
|
|
|
Vector3 PhysicsConstants::GravityAcceleration(0.0f,0.0f,-9.8f);
|
|
|
|
float PhysicsConstants::LinearDamping = 0.01f;
|
|
|
|
float PhysicsConstants::AngularDamping = 0.05f;
|
|
|
|
float PhysicsConstants::RestingContactVelocity = 0.1f;
|
|
|
|
float PhysicsConstants::MinFrictionVelocity = 0.05f;
|
|
|
|
float PhysicsConstants::DefaultContactFriction = 0.5f;
|
|
|
|
float PhysicsConstants::DefaultContactDrag = 0.0f;
|
|
|
|
int PhysicsConstants::SurfaceTypeOverride = -1;
|
|
float PhysicsConstants::OverrideDrag = 0.0f;
|
|
float PhysicsConstants::OverrideFriction = 0.0f;
|
|
|
|
/*
|
|
** these are all constants computed from the above constants
|
|
*/
|
|
float PhysicsConstants::MinFrictionVelocity2 = (PhysicsConstants::MinFrictionVelocity * PhysicsConstants::MinFrictionVelocity);
|
|
|
|
/*
|
|
** These are constants which are not exposed in the header file
|
|
** Note that SURFACE_TYPE_MAX comes from w3d_file.h
|
|
*/
|
|
float ContactFrictionCoefficient[PhysicsConstants::DYNAMIC_OBJ_TYPE_MAX][SURFACE_TYPE_MAX];
|
|
float ContactDragCoefficient[PhysicsConstants::DYNAMIC_OBJ_TYPE_MAX][SURFACE_TYPE_MAX];
|
|
|
|
float test[2][2] = { 1,2,3,4 };
|
|
|
|
|
|
|
|
|
|
/*
|
|
** PhysicsConstants Member functions
|
|
*/
|
|
void PhysicsConstants::Init(void)
|
|
{
|
|
for (int obj_type=0; obj_type < DYNAMIC_OBJ_TYPE_MAX; obj_type++) {
|
|
for (int surf_type=0; surf_type < SURFACE_TYPE_MAX; surf_type++) {
|
|
ContactFrictionCoefficient[obj_type][surf_type] = DefaultContactFriction;
|
|
ContactDragCoefficient[obj_type][surf_type] = DefaultContactDrag;
|
|
}
|
|
}
|
|
}
|
|
|
|
void PhysicsConstants::Set_Contact_Friction_Coefficient(int obj_type,int surface_type,float friction)
|
|
{
|
|
if ((obj_type < 0) || (obj_type > DYNAMIC_OBJ_TYPE_MAX)) {
|
|
WWDEBUG_SAY(("PhysicsConstants -> Out of range dynamic object type!\n"));
|
|
return;
|
|
}
|
|
if ((surface_type < 0) || (surface_type > SURFACE_TYPE_MAX)) {
|
|
WWDEBUG_SAY(("PhysicsConstants -> Out of range surface type!\n"));
|
|
return;
|
|
}
|
|
ContactFrictionCoefficient[obj_type][surface_type] = friction;
|
|
}
|
|
|
|
float PhysicsConstants::Get_Contact_Friction_Coefficient(int obj_type,int surface_type)
|
|
{
|
|
if (SurfaceTypeOverride != -1) surface_type = SurfaceTypeOverride;
|
|
if (OverrideFriction != 0.0f) return OverrideFriction;
|
|
|
|
if ((obj_type < 0) || (obj_type > DYNAMIC_OBJ_TYPE_MAX)) {
|
|
WWDEBUG_SAY(("PhysicsConstants -> Out of range dynamic object type!\n"));
|
|
return ContactFrictionCoefficient[0][0];
|
|
}
|
|
if ((surface_type < 0) || (surface_type > SURFACE_TYPE_MAX)) {
|
|
WWDEBUG_SAY(("PhysicsConstants -> Out of range surface type!\n"));
|
|
return ContactFrictionCoefficient[0][0];
|
|
}
|
|
return ContactFrictionCoefficient[obj_type][surface_type];
|
|
}
|
|
|
|
void PhysicsConstants::Set_Contact_Drag_Coefficient(int obj_type,int surface_type,float drag)
|
|
{
|
|
if ((obj_type < 0) || (obj_type > DYNAMIC_OBJ_TYPE_MAX)) {
|
|
WWDEBUG_SAY(("PhysicsConstants -> Out of range dynamic object type!\n"));
|
|
return;
|
|
}
|
|
if ((surface_type < 0) || (surface_type > SURFACE_TYPE_MAX)) {
|
|
WWDEBUG_SAY(("PhysicsConstants -> Out of range surface type!\n"));
|
|
return;
|
|
}
|
|
ContactDragCoefficient[obj_type][surface_type] = drag;
|
|
}
|
|
|
|
float PhysicsConstants::Get_Contact_Drag_Coefficient(int obj_type,int surface_type)
|
|
{
|
|
if (SurfaceTypeOverride != -1) surface_type = SurfaceTypeOverride;
|
|
if (OverrideDrag != 0.0f) return OverrideDrag;
|
|
|
|
if ((obj_type < 0) || (obj_type > DYNAMIC_OBJ_TYPE_MAX)) {
|
|
WWDEBUG_SAY(("PhysicsConstants -> Out of range dynamic object type!\n"));
|
|
return ContactDragCoefficient[0][0];
|
|
}
|
|
if ((surface_type < 0) || (surface_type > SURFACE_TYPE_MAX)) {
|
|
WWDEBUG_SAY(("PhysicsConstants -> Out of range surface type!\n"));
|
|
return ContactDragCoefficient[0][0];
|
|
}
|
|
return ContactDragCoefficient[obj_type][surface_type];
|
|
}
|
|
|
|
void PhysicsConstants::Set_Override_Surface_Type(int type)
|
|
{
|
|
if ((type <0) || (type > SURFACE_TYPE_MAX)) {
|
|
SurfaceTypeOverride = -1;
|
|
} else {
|
|
SurfaceTypeOverride = type;
|
|
}
|
|
}
|
|
|
|
void PhysicsConstants::Set_Override_Surface_Friction(float friction)
|
|
{
|
|
OverrideFriction = WWMath::Clamp(friction);
|
|
}
|
|
|
|
void PhysicsConstants::Set_Override_Surface_Drag(float drag)
|
|
{
|
|
OverrideDrag = drag;
|
|
}
|
|
|
|
/*
|
|
** Save-Load Support
|
|
*/
|
|
enum
|
|
{
|
|
PHYSCONSTANTS_CHUNK_VARIABLES = 0x00044005,
|
|
|
|
PHYSCONSTANT_GRAVITYACCELERATION = 0x00,
|
|
PHYSCONSTANT_LINEARDAMPING,
|
|
PHYSCONSTANT_ANGULARDAMPING,
|
|
PHYSCONSTANT_RESTINGCONTACTVELOCITY,
|
|
PHYSCONSTANT_MINFRICTIONVELOCITY,
|
|
PHYSCONSTANT_DEFAULTCONTACTFRICTION,
|
|
PHYSCONSTANT_MINFRICTIONVELOCITY2
|
|
};
|
|
|
|
|
|
void PhysicsConstants::Save(ChunkSaveClass & csave)
|
|
{
|
|
csave.Begin_Chunk(PHYSCONSTANTS_CHUNK_VARIABLES);
|
|
WRITE_MICRO_CHUNK(csave,PHYSCONSTANT_GRAVITYACCELERATION,GravityAcceleration);
|
|
WRITE_MICRO_CHUNK(csave,PHYSCONSTANT_LINEARDAMPING,LinearDamping);
|
|
WRITE_MICRO_CHUNK(csave,PHYSCONSTANT_ANGULARDAMPING,AngularDamping);
|
|
WRITE_MICRO_CHUNK(csave,PHYSCONSTANT_RESTINGCONTACTVELOCITY,RestingContactVelocity);
|
|
WRITE_MICRO_CHUNK(csave,PHYSCONSTANT_MINFRICTIONVELOCITY,MinFrictionVelocity);
|
|
WRITE_MICRO_CHUNK(csave,PHYSCONSTANT_DEFAULTCONTACTFRICTION,DefaultContactFriction);
|
|
WRITE_MICRO_CHUNK(csave,PHYSCONSTANT_MINFRICTIONVELOCITY2,MinFrictionVelocity2);
|
|
csave.End_Chunk();
|
|
}
|
|
|
|
void PhysicsConstants::Load(ChunkLoadClass & cload)
|
|
{
|
|
|
|
while (cload.Open_Chunk()) {
|
|
|
|
switch(cload.Cur_Chunk_ID())
|
|
{
|
|
case PHYSCONSTANTS_CHUNK_VARIABLES:
|
|
while (cload.Open_Micro_Chunk()) {
|
|
switch(cload.Cur_Micro_Chunk_ID()) {
|
|
READ_MICRO_CHUNK(cload,PHYSCONSTANT_GRAVITYACCELERATION,GravityAcceleration);
|
|
READ_MICRO_CHUNK(cload,PHYSCONSTANT_LINEARDAMPING,LinearDamping);
|
|
READ_MICRO_CHUNK(cload,PHYSCONSTANT_ANGULARDAMPING,AngularDamping);
|
|
READ_MICRO_CHUNK(cload,PHYSCONSTANT_RESTINGCONTACTVELOCITY,RestingContactVelocity);
|
|
READ_MICRO_CHUNK(cload,PHYSCONSTANT_MINFRICTIONVELOCITY,MinFrictionVelocity);
|
|
READ_MICRO_CHUNK(cload,PHYSCONSTANT_DEFAULTCONTACTFRICTION,DefaultContactFriction);
|
|
READ_MICRO_CHUNK(cload,PHYSCONSTANT_MINFRICTIONVELOCITY2,MinFrictionVelocity2);
|
|
}
|
|
cload.Close_Micro_Chunk();
|
|
}
|
|
break;
|
|
|
|
|
|
default:
|
|
WWDEBUG_SAY(("Unhandled Chunk: 0x%X File: %s Line: %d\r\n",cload.Cur_Chunk_ID(),__FILE__,__LINE__));
|
|
break;
|
|
}
|
|
|
|
cload.Close_Chunk();
|
|
}
|
|
}
|
|
|