physx initial implementation

This commit is contained in:
nillerusr 2023-10-16 07:58:27 +03:00
parent 490bd8b42d
commit 83e334f9b8
12 changed files with 479 additions and 749 deletions

View File

@ -259,89 +259,15 @@ static const IVP_U_Matrix *GetTmpObjectMatrix( IVP_Real_Object *pObject )
void TransformIVPToLocal( const IVP_U_Point &pointIn, IVP_U_Point &pointOut, IVP_Real_Object *pObject, bool translate )
{
#if USE_CACHE_OBJECT
IVP_Cache_Object *cache = pObject->get_cache_object_no_lock();
if ( translate )
{
cache->transform_position_to_object_coords( &pointIn, &pointOut );
}
else
{
cache->transform_vector_to_object_coords( &pointIn, &pointOut );
}
#else
const IVP_U_Matrix *pMatrix = GetTmpObjectMatrix( pObject );
if ( translate )
{
pMatrix->inline_vimult4( &pointIn, &pointOut );
}
else
{
pMatrix->inline_vimult3( &pointIn, &pointOut );
}
#endif
}
void TransformLocalToIVP( const IVP_U_Point &pointIn, IVP_U_Point &pointOut, IVP_Real_Object *pObject, bool translate )
{
#if USE_CACHE_OBJECT
IVP_Cache_Object *cache = pObject->get_cache_object_no_lock();
if ( translate )
{
IVP_U_Float_Point floatPointIn;
floatPointIn.set( &pointIn );
cache->transform_position_to_world_coords( &floatPointIn, &pointOut );
}
else
{
cache->transform_vector_to_world_coords( &pointIn, &pointOut );
}
#else
const IVP_U_Matrix *pMatrix = GetTmpObjectMatrix( pObject );
if ( translate )
{
pMatrix->inline_vmult4( &pointIn, &pointOut );
}
else
{
pMatrix->inline_vmult3( &pointIn, &pointOut );
}
#endif
}
void TransformLocalToIVP( const IVP_U_Float_Point &pointIn, IVP_U_Point &pointOut, IVP_Real_Object *pObject, bool translate )
{
#if USE_CACHE_OBJECT
IVP_Cache_Object *cache = pObject->get_cache_object_no_lock();
if ( translate )
{
cache->transform_position_to_world_coords( &pointIn, &pointOut );
}
else
{
IVP_U_Point doublePointIn;
doublePointIn.set( &pointIn );
cache->transform_vector_to_world_coords( &doublePointIn, &pointOut );
}
#else
const IVP_U_Matrix *pMatrix = GetTmpObjectMatrix( pObject );
IVP_U_Float_Point out;
if ( translate )
{
pMatrix->inline_vmult4( &pointIn, &out );
}
else
{
pMatrix->inline_vmult3( &pointIn, &out );
}
pointOut.set( &out );
#endif
}
void TransformLocalToIVP( const IVP_U_Float_Point &pointIn, IVP_U_Float_Point &pointOut, IVP_Real_Object *pObject, bool translate )

View File

@ -11,8 +11,9 @@
#include "vphysics/collision_set.h"
#include "tier1/tier1.h"
#include "ivu_vhash.hxx"
#include "PxPhysicsAPI.h"
using namespace physx;
#if defined(_WIN32) && !defined(_X360)
#define WIN32_LEAN_AND_MEAN
@ -29,39 +30,24 @@ static void ivu_string_print_function( const char *str )
Msg("%s", str);
}
#if defined(_WIN32) && !defined(_XBOX)
//HMODULE gPhysicsDLLHandle;
#pragma warning (disable:4100)
BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved )
class PhysErrorCallback : public PxErrorCallback
{
if ( fdwReason == DLL_PROCESS_ATTACH )
public:
virtual void reportError(PxErrorCode::Enum code, const char* message, const char* file,
int line)
{
// ivp_set_message_print_function( ivu_string_print_function );
MathLib_Init( 2.2f, 2.2f, 0.0f, 2.0f, false, false, false, false );
// store out module handle
//gPhysicsDLLHandle = (HMODULE)hinstDLL;
}
else if ( fdwReason == DLL_PROCESS_DETACH )
{
}
return TRUE;
// error processing implementation
Warning("Px: %s %s:%d\n", message, file, line);
}
};
#endif // _WIN32
#ifdef POSIX
void __attribute__ ((constructor)) vphysics_init(void);
void vphysics_init(void)
{
// ivp_set_message_print_function( ivu_string_print_function );
MathLib_Init( 2.2f, 2.2f, 0.0f, 2.0f, false, false, false, false );
}
#endif
PhysErrorCallback gPxErrorCallback;
PxDefaultAllocator gPxAllocatorCallback;
PxFoundation *gPxFoundation = NULL;
PxPvd *gPxPvd = NULL;
PxPhysics *gPxPhysics = NULL;
PxCooking *gPxCooking = NULL;
// simple 32x32 bit array
class CPhysicsCollisionSet : public IPhysicsCollisionSet
@ -102,6 +88,8 @@ class CPhysicsInterface : public CTier1AppSystem<IPhysics>
{
public:
CPhysicsInterface() : m_pCollisionSetHash(NULL) {}
virtual InitReturnVal_t Init();
virtual void Shutdown();
virtual void *QueryInterface( const char *pInterfaceName );
virtual IPhysicsEnvironment *CreateEnvironment( void );
virtual void DestroyEnvironment( IPhysicsEnvironment *pEnvironment );
@ -112,6 +100,7 @@ public:
virtual IPhysicsCollisionSet *FindCollisionSet( unsigned int id );
virtual void DestroyAllCollisionSets();
typedef CTier1AppSystem<IPhysics> BaseClass;
private:
CUtlVector<IPhysicsEnvironment *> m_envList;
CUtlVector<CPhysicsCollisionSet> m_collisionSets;
@ -126,6 +115,60 @@ static CPhysicsInterface g_MainDLLInterface;
IPhysics *g_PhysicsInternal = &g_MainDLLInterface;
EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CPhysicsInterface, IPhysics, VPHYSICS_INTERFACE_VERSION, g_MainDLLInterface );
#define PVD_HOST "localhost"
InitReturnVal_t CPhysicsInterface::Init()
{
InitReturnVal_t nRetVal = BaseClass::Init();
if ( nRetVal != INIT_OK )
return nRetVal;
bool recordMemoryAllocations = true;
MathLib_Init( 2.2f, 2.2f, 0.0f, 2.0f, false, false, false, false );
gPxFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, gPxAllocatorCallback, gPxErrorCallback);
if( !gPxFoundation )
{
Error("PxCreateFoundation failed!\n");
return INIT_FAILED;
}
gPxPvd = PxCreatePvd(*gPxFoundation);
PxPvdTransport* transport = PxDefaultPvdSocketTransportCreate(PVD_HOST, 5425, 10000);
if(transport)
Msg("PxDefaultPvdSocketTransportCreate success\n");
gPxPvd->connect(*transport,PxPvdInstrumentationFlag::eALL);
gPxPhysics = PxCreatePhysics(PX_PHYSICS_VERSION, *gPxFoundation, PxTolerancesScale(), recordMemoryAllocations, gPxPvd);
if( !gPxPhysics )
{
Error("PxCreatePhysics failed!\n");
return INIT_FAILED;
}
gPxCooking = PxCreateCooking(PX_PHYSICS_VERSION, *gPxFoundation , PxCookingParams(PxTolerancesScale()));
return INIT_OK;
}
void CPhysicsInterface::Shutdown()
{
if( gPxPhysics )
gPxPhysics->release();
if( gPxFoundation )
gPxFoundation->release();
BaseClass::Shutdown( );
}
//-----------------------------------------------------------------------------
// Query interface
@ -218,25 +261,3 @@ void CPhysicsInterface::DestroyAllCollisionSets()
m_pCollisionSetHash = NULL;
}
// In release build, each of these libraries must contain a symbol that indicates it is also a release build
// You MUST disable this in order to run a release vphysics.dll with a debug library.
// This should not usually be necessary
// #if !defined(_DEBUG) && defined(_WIN32)
// extern int ivp_physics_lib_is_a_release_build;
// extern int ivp_compactbuilder_lib_is_a_release_build;
// extern int hk_base_lib_is_a_release_build;
// extern int hk_math_lib_is_a_release_build;
// extern int havana_constraints_lib_is_a_release_build;
// void DebugTestFunction()
// {
// ivp_physics_lib_is_a_release_build = 0;
// ivp_compactbuilder_lib_is_a_release_build = 0;
// hk_base_lib_is_a_release_build = 0;
// hk_math_lib_is_a_release_build = 0;
// havana_constraints_lib_is_a_release_build = 0;
// }
// #endif

View File

@ -29,6 +29,7 @@
#include "mathlib/polyhedron.h"
#include "tier1/byteswap.h"
#include "physics_globals.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
@ -161,9 +162,110 @@ EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CPhysicsCollision, IPhysicsCollision, VPHYSIC
// You can disable all of the havok Mopp collision model building by undefining this symbol
#define ENABLE_IVP_MOPP 0
struct ivpcompactledge_t {
DECLARE_BYTESWAP_DATADESC()
int c_point_offset; // byte offset from 'this' to (ledge) point array
union {
int ledgetree_node_offset;
int client_data; // if indicates a non terminal ledge
};
union {
int bf1;
struct {
uint has_chilren_flag:2;
int is_compact_flag:2; // if false than compact ledge uses points outside this piece of memory
uint dummy:4;
uint size_div_16:24;
};
};
short n_triangles;
short for_future_use;
};
// 48 bytes
// Just like a btCompoundShape.
struct ivpcompactsurface_t {
DECLARE_BYTESWAP_DATADESC()
float mass_center[3];
float rotation_inertia[3];
float upper_limit_radius;
union {
int bf1; // HACK: Allow datamap to take address of this bitfield
struct {
int max_deviation : 8;
int byte_size : 24;
};
};
int offset_ledgetree_root;
int dummy[3]; // dummy[2] is "IVPS" or 0
};
struct ivpcompactedge_t {
DECLARE_BYTESWAP_DATADESC()
union {
int bf1;
struct {
uint start_point_index:16; // point index
int opposite_index:15; // rel to this // maybe extra array, 3 bits more tha>
uint is_virtual:1;
};
};
};
struct ivpcompactledgenode_t {
DECLARE_BYTESWAP_DATADESC()
int offset_right_node; // (if != 0 than children
int offset_compact_ledge; // (if != 0, pointer to hull that contains all subelements
float center[3]; // in object_coords
float radius; // size of sphere
unsigned char box_sizes[3];
unsigned char free_0;
// Functions
const ivpcompactledge_t *GetCompactLedge() const {
Assert(this->offset_right_node == 0);
return (ivpcompactledge_t *)((char *)this + this->offset_compact_ledge);
}
const ivpcompactledgenode_t *GetLeftSon() const {
Assert(this->offset_right_node);
return this + 1;
}
const ivpcompactledgenode_t *GetRightSon() const {
Assert(this->offset_right_node);
return (ivpcompactledgenode_t *)((char *)this + this->offset_right_node);
}
bool IsTerminal() const {
return (this->offset_right_node == 0);
}
const ivpcompactledge_t *GetCompactHull() const {
if (this->offset_compact_ledge)
return (ivpcompactledge_t *)((char *)this + this->offset_compact_ledge);
else
return NULL;
}
};
struct physcollideheader_t
{
DECLARE_BYTESWAP_DATADESC();
int size;
int vphysicsID;
short version;
short modelType;
@ -306,10 +408,136 @@ void OutputCollideDebugInfo( const CPhysCollide *pCollisionModel )
pCollisionModel->OutputDebugInfo();
}
namespace ivp_compat
{
struct collideheader_t
{
int vphysicsID;
short version;
short modelType;
};
struct compactsurfaceheader_t
{
int surfaceSize;
Vector dragAxisAreas;
int axisMapSize;
};
struct moppsurfaceheader_t
{
int moppSize;
};
struct compactsurface_t
{
float mass_center[3];
float rotation_inertia[3];
float upper_limit_radius;
unsigned int max_factor_surface_deviation : 8;
int byte_size : 24;
int offset_ledgetree_root;
int dummy[3];
};
struct compactmopp_t
{
float mass_center[3];
float rotation_inertia[3];
float upper_limit_radius;
unsigned int max_factor_surface_deviation : 8;
int byte_size : 24;
int offset_ledgetree_root;
int offset_ledges;
int size_convex_hull;
int dummy;
};
struct compactledge_t
{
int c_point_offset;
union
{
int ledgetree_node_offset;
int client_data;
};
struct
{
uint has_children_flag : 2;
int is_compact_flag : 2;
uint dummy : 4;
uint size_div_16 : 24;
};
short n_triangles;
short for_future_use;
};
struct compactedge_t
{
uint start_point_index : 16;
int opposite_index : 15;
uint is_virtual : 1;
};
struct compacttriangle_t
{
uint tri_index : 12;
uint pierce_index : 12;
uint material_index : 7;
uint is_virtual : 1;
compactedge_t c_three_edges[3];
};
struct compactledgenode_t
{
int offset_right_node;
int offset_compact_ledge;
float center[3];
float radius;
unsigned char box_sizes[3];
unsigned char free_0;
const compactledge_t *GetCompactLedge() const
{
//VJoltAssert( this->offset_right_node == 0 );
return ( compactledge_t * )( ( char * )this + this->offset_compact_ledge );
}
const compactledgenode_t *GetLeftChild() const
{
//VJoltAssert( this->offset_right_node );
return this + 1;
}
const compactledgenode_t *GetRightChild() const
{
//VJoltAssert( this->offset_right_node );
return ( compactledgenode_t * )( ( char * )this + this->offset_right_node );
}
bool IsTerminal() const
{
return this->offset_right_node == 0;
}
const compactledge_t *GetCompactHull() const
{
if ( this->offset_compact_ledge )
return ( compactledge_t * )( ( char * )this + this->offset_compact_ledge );
else
return nullptr;
}
};
}
CPhysCollide *CPhysCollide::UnserializeFromBuffer( const char *pBuffer, unsigned int size, int index, bool swap )
{
const physcollideheader_t *pHeader = reinterpret_cast<const physcollideheader_t *>(pBuffer);
const ivp_compat::collideheader_t *pHeader = reinterpret_cast<const ivp_compat::collideheader_t *>(pBuffer);
if ( pHeader->vphysicsID == VPHYSICS_COLLISION_ID )
{
Assert(pHeader->version == VPHYSICS_COLLISION_VERSION);
@ -1623,39 +1851,113 @@ float CPhysicsCollision::CollideSurfaceArea( CPhysCollide *pCollide )
return area;
}
static void GetAllIVPEdges(const ivp_compat::compactledgenode_t *pNode, CUtlVector<const ivp_compat::compactledge_t *> *vecOut)
{
if (!pNode || !vecOut) return;
if ( !pNode->IsTerminal() )
{
GetAllIVPEdges( pNode->GetRightChild(), vecOut );
GetAllIVPEdges( pNode->GetLeftChild(), vecOut );
}
else
vecOut->AddToTail( pNode->GetCompactLedge() );
}
CPhysCollide *DeserializeIVP_Poly( const ivp_compat::compactsurface_t* pSurface )
{
const ivp_compat::compactledgenode_t *pFirstLedgeNode = reinterpret_cast< const ivp_compat::compactledgenode_t * >(
reinterpret_cast< const char * >( pSurface ) + pSurface->offset_ledgetree_root );
CUtlVector< const ivp_compat::compactledge_t * > ledges;
GetAllIVPEdges( pFirstLedgeNode, &ledges );
Msg("ledge count - %d\n", ledges.Count());
return NULL;
}
CPhysCollide *DeserializeIVP_Poly( const ivp_compat::collideheader_t *pCollideHeader )
{
const ivp_compat::compactsurfaceheader_t *pSurfaceHeader = reinterpret_cast< const ivp_compat::compactsurfaceheader_t* >( pCollideHeader + 1 );
const ivp_compat::compactsurface_t *pSurface = reinterpret_cast< const ivp_compat::compactsurface_t* >( pSurfaceHeader + 1 );
return DeserializeIVP_Poly( pSurface );
}
// loads a set of solids into a vcollide_t
void CPhysicsCollision::VCollideLoad( vcollide_t *pOutput, int solidCount, const char *pBuffer, int bufferSize, bool swap )
{
memset( pOutput, 0, sizeof(*pOutput) );
int position = 0;
pOutput->solidCount = solidCount;
pOutput->solids = new CPhysCollide*[ solidCount ];
BEGIN_IVP_ALLOCATION();
const char *pCursor = pBuffer;
for ( int i = 0; i < solidCount; i++ )
{
int size;
memcpy( &size, pBuffer + position, sizeof(int) );
position += sizeof(int);
// Be safe ahead of time as so much can go wrong with
// this mess! :p
pOutput->solids[ i ] = nullptr;
char *tmpbuf = new char[size];
memcpy(tmpbuf, pBuffer + position, size);
const int solidSize = *reinterpret_cast<const int *>( pCursor );
pCursor += sizeof( int );
pOutput->solids[i] = CPhysCollide::UnserializeFromBuffer( tmpbuf, size, i, swap );
position += size;
const ivp_compat::collideheader_t *pCollideHeader = reinterpret_cast<const ivp_compat::collideheader_t *>( pCursor );
delete[] tmpbuf;
if ( pCollideHeader->vphysicsID == VPHYSICS_COLLISION_ID )
{
// This is the main path that everything falls down for a modern
// .phy file with the collide header.
if ( pCollideHeader->version != VPHYSICS_COLLISION_VERSION )
Warning( "Solid with unknown version: 0x%x, may crash!\n", pCollideHeader->version );
switch ( pCollideHeader->modelType )
{
case COLLIDE_POLY:
pOutput->solids[ i ] = DeserializeIVP_Poly( pCollideHeader );
break;
default:
Warning( "Unsupported solid type 0x%x on solid %d. Skipping...\n", (int)pCollideHeader->modelType, i );
break;
}
}
else
{
// This must be a legacy style .phy where it is just a dumped compact surface.
// Some props in shipping HL2 still use this format, as they have a .phy, even after their
// .qc had the $collisionmodel removed, as they didn't get the stale .phy in the game files deleted.
const ivp_compat::compactsurface_t *pCompactSurface = reinterpret_cast<const ivp_compat::compactsurface_t*>( pCursor );
const int legacyModelType = pCompactSurface->dummy[2];
switch ( legacyModelType )
{
case 0:
case IVP_COMPACT_SURFACE_ID:
case IVP_COMPACT_SURFACE_ID_SWAPPED:
pOutput->solids[i] = DeserializeIVP_Poly( pCollideHeader );
break;
default:
Warning( "Unsupported legacy solid type 0x%x on solid %d. Skipping...\n", legacyModelType, i);
break;
}
}
END_IVP_ALLOCATION();
pCursor += solidSize;
}
// The rest of the buffer is KV.
const int keyValuesSize = bufferSize - ( pCursor - pBuffer );
pOutput->pKeyValues = new char[ keyValuesSize + 1 ];
V_memcpy( pOutput->pKeyValues, pCursor, keyValuesSize );
pOutput->pKeyValues[ keyValuesSize ] = '\0';
pOutput->descSize = keyValuesSize;
pOutput->isPacked = false;
int keySize = bufferSize - position;
pOutput->pKeyValues = new char[keySize];
memcpy( pOutput->pKeyValues, pBuffer + position, keySize );
pOutput->descSize = 0;
#ifdef GAME_ASW_OR_NEWER
pOutput->pUserData = nullptr;
#endif
}
// destroys the set of solids created by VCollideCreateCPhysCollide

View File

@ -568,25 +568,9 @@ CPhysicsConstraint::CPhysicsConstraint( CPhysicsObject *pReferenceObject, CPhysi
m_constraintType = CONSTRAINT_UNKNOWN;
m_isBreakable = false;
if ( pReferenceObject && pAttachedObject )
{
m_pObjReference = (CPhysicsObject *)pReferenceObject;
m_pObjAttached = (CPhysicsObject *)pAttachedObject;
if ( !(m_pObjReference->CallbackFlags() & CALLBACK_NEVER_DELETED) )
{
m_pObjReference->GetObject()->add_listener_object( this );
}
if ( !(m_pObjAttached->CallbackFlags() & CALLBACK_NEVER_DELETED) )
{
m_pObjAttached->GetObject()->add_listener_object( this );
}
}
else
{
m_pObjReference = NULL;
m_pObjAttached = NULL;
}
}
// Check to see if this is a single degree of freedom joint, if so, convert to a hinge
static bool ConvertRagdollToHinge( constraint_limitedhingeparams_t *pHingeOut, const constraint_ragdollparams_t &ragdoll, IPhysicsObject *pReferenceObject, IPhysicsObject *pAttachedObject )

View File

@ -36,6 +36,7 @@
#include "ivp_phantom.hxx"
#include "ivp_range_manager.hxx"
#include "ivp_clustering_visualizer.hxx"
#include "physics_globals.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
@ -1113,6 +1114,18 @@ CPhysicsEnvironment::CPhysicsEnvironment( void )
m_fixedTimestep = true; // try to simulate using fixed timesteps
m_enableConstraintNotify = false;
// PHYSX_BEGIN
PxSceneDesc sceneDesc(gPxPhysics->getTolerancesScale());
sceneDesc.gravity = physx::PxVec3(0.0f, -9.81f, 0.0f);
m_pPxDispatcher = PxDefaultCpuDispatcherCreate(2);
sceneDesc.cpuDispatcher = m_pPxDispatcher;
sceneDesc.filterShader = PxDefaultSimulationFilterShader;
m_pPxScene = gPxPhysics->createScene(sceneDesc);
// PHYSX_END
// build a default environment
IVP_Environment_Manager *env_manager;
env_manager = IVP_Environment_Manager::get_environment_manager();
@ -1440,7 +1453,8 @@ IPhysicsFluidController *CPhysicsEnvironment::CreateFluidController( IPhysicsObj
IPhysicsConstraint *CPhysicsEnvironment::CreateRagdollConstraint( IPhysicsObject *pReferenceObject, IPhysicsObject *pAttachedObject, IPhysicsConstraintGroup *pGroup, const constraint_ragdollparams_t &ragdoll )
{
return ::CreateRagdollConstraint( m_pPhysEnv, (CPhysicsObject *)pReferenceObject, (CPhysicsObject *)pAttachedObject, pGroup, ragdoll );
return NULL;
// return ::CreateRagdollConstraint( m_pPhysEnv, (CPhysicsObject *)pReferenceObject, (CPhysicsObject *)pAttachedObject, pGroup, ragdoll );
}
IPhysicsConstraint *CPhysicsEnvironment::CreateHingeConstraint( IPhysicsObject *pReferenceObject, IPhysicsObject *pAttachedObject, IPhysicsConstraintGroup *pGroup, const constraint_hingeparams_t &hinge )
@ -1511,6 +1525,10 @@ void CPhysicsEnvironment::Simulate( float deltaTime )
deltaTime = 0.1f;
}
m_pPxScene->simulate(deltaTime);
m_pPxScene->fetchResults(true);
#if 0
m_pCollisionSolver->EventPSI( this );
m_pCollisionListener->EventPSI( this );
@ -1525,7 +1543,10 @@ void CPhysicsEnvironment::Simulate( float deltaTime )
{
m_pPhysEnv->simulate_time_step();
}
END_IVP_ALLOCATION();
#endif
m_inSimulation = false;
}

View File

@ -12,6 +12,7 @@
#include "vphysics_interface.h"
#include "ivu_types.hxx"
#include "utlvector.h"
#include "physics_globals.h"
class IVP_Environment;
class CSleepObjects;
@ -164,6 +165,9 @@ private:
bool m_queueDeleteObject;
bool m_fixedTimestep;
bool m_enableConstraintNotify;
PxDefaultCpuDispatcher *m_pPxDispatcher;
PxScene *m_pPxScene;
};
extern IPhysicsEnvironment *CreatePhysicsEnvironment( void );

View File

@ -189,6 +189,8 @@ CPhysicsFluidController *CreateFluidController( IVP_Environment *pEnvironment, C
{
pFluidObject->BecomeTrigger();
return NULL;
IVP_Controller_Phantom *pPhantom = pFluidObject->GetObject()->get_controller_phantom();
if ( !pPhantom )
return NULL;

View File

@ -55,7 +55,7 @@ private:
CFrictionSnapshot::CFrictionSnapshot( IVP_Real_Object *pObject ) : m_pObject(pObject)
{
m_pDeleteList = NULL;
SetFrictionSynapse( pObject->get_first_friction_synapse() );
//SetFrictionSynapse( pObject->get_first_friction_synapse() );
}
CFrictionSnapshot::~CFrictionSnapshot()
@ -102,12 +102,7 @@ bool CFrictionSnapshot::IsValid()
IPhysicsObject *CFrictionSnapshot::GetObject( int index )
{
IVP_Synapse_Friction *pFriction = m_pFriction;
if ( index == 1 )
{
pFriction = m_pContactPoint->get_synapse(!m_synapseIndex);
}
return static_cast<IPhysicsObject *>(pFriction->get_object()->client_data);
return NULL;
}
void CFrictionSnapshot::MarkContactForDelete()

View File

@ -101,7 +101,7 @@ void CPhysicsObject::Init( const CPhysCollide *pCollisionModel, IVP_Real_Object
m_pCollide = pCollisionModel;
m_materialIndex = materialIndex;
m_pObject = pObject;
pObject->client_data = (void *)this;
// pObject->client_data = (void *)this;
m_pGameData = NULL;
m_gameFlags = 0;
m_gameIndex = 0;
@ -174,18 +174,18 @@ CPhysicsObject::~CPhysicsObject( void )
void CPhysicsObject::Wake( void )
{
m_pObject->ensure_in_simulation();
//m_pObject->ensure_in_simulation();
}
void CPhysicsObject::WakeNow( void )
{
m_pObject->ensure_in_simulation_now();
//m_pObject->ensure_in_simulation_now();
}
// supported
void CPhysicsObject::Sleep( void )
{
m_pObject->disable_simulation();
//m_pObject->disable_simulation();
}
@ -195,19 +195,19 @@ bool CPhysicsObject::IsAsleep() const
return false;
// double-check that we aren't pending
if ( m_pObject->get_core()->is_in_wakeup_vec )
return false;
//if ( m_pObject->get_core()->is_in_wakeup_vec )
// return false;
return true;
}
void CPhysicsObject::NotifySleep( void )
{
if ( m_sleepState == OBJ_AWAKE )
{
m_sleepState = OBJ_STARTSLEEP;
}
else
// if ( m_sleepState == OBJ_AWAKE )
// {
// m_sleepState = OBJ_STARTSLEEP;
// }
// else
{
// UNDONE: This fails sometimes and we get sleep calls for a sleeping object, debug?
//Assert(m_sleepState==OBJ_STARTSLEEP);
@ -275,40 +275,12 @@ unsigned short CPhysicsObject::GetGameIndex() const
bool CPhysicsObject::IsStatic() const
{
if ( m_pObject->get_core()->physical_unmoveable )
return true;
return false;
}
void CPhysicsObject::EnableCollisions( bool enable )
{
if ( enable )
{
m_callbacks |= CALLBACK_ENABLING_COLLISION;
BEGIN_IVP_ALLOCATION();
m_pObject->enable_collision_detection( IVP_TRUE );
END_IVP_ALLOCATION();
m_callbacks &= ~CALLBACK_ENABLING_COLLISION;
}
else
{
if ( IsCollisionEnabled() )
{
// Delete all contact points with this physics object because it's collision is becoming disabled
IPhysicsFrictionSnapshot *pSnapshot = CreateFrictionSnapshot();
while ( pSnapshot->IsValid() )
{
pSnapshot->MarkContactForDelete();
pSnapshot->NextFrictionData();
}
pSnapshot->DeleteAllMarkedContacts( true );
DestroyFrictionSnapshot( pSnapshot );
}
m_pObject->enable_collision_detection( IVP_FALSE );
}
}
void CPhysicsObject::RecheckCollisionFilter()
@ -316,63 +288,30 @@ void CPhysicsObject::RecheckCollisionFilter()
if ( CallbackFlags() & CALLBACK_MARKED_FOR_DELETE )
return;
m_callbacks |= CALLBACK_ENABLING_COLLISION;
BEGIN_IVP_ALLOCATION();
m_pObject->recheck_collision_filter();
// UNDONE: do a RecheckContactPoints() here?
END_IVP_ALLOCATION();
m_callbacks &= ~CALLBACK_ENABLING_COLLISION;
}
void CPhysicsObject::RecheckContactPoints()
{
IVP_Environment *pEnv = m_pObject->get_environment();
IVP_Collision_Filter *coll_filter = pEnv->get_collision_filter();
IPhysicsFrictionSnapshot *pSnapshot = CreateFrictionSnapshot();
while ( pSnapshot->IsValid() )
{
CPhysicsObject *pOther = static_cast<CPhysicsObject *>(pSnapshot->GetObject(1));
if ( !coll_filter->check_objects_for_collision_detection( m_pObject, pOther->m_pObject ) )
{
pSnapshot->MarkContactForDelete();
}
pSnapshot->NextFrictionData();
}
pSnapshot->DeleteAllMarkedContacts( true );
DestroyFrictionSnapshot( pSnapshot );
}
CPhysicsEnvironment *CPhysicsObject::GetVPhysicsEnvironment()
{
return (CPhysicsEnvironment *) (m_pObject->get_environment()->client_data);
return NULL; //(CPhysicsEnvironment *) (m_pObject->get_environment()->client_data);
}
const CPhysicsEnvironment *CPhysicsObject::GetVPhysicsEnvironment() const
{
return (CPhysicsEnvironment *) (m_pObject->get_environment()->client_data);
return NULL; // (CPhysicsEnvironment *) (m_pObject->get_environment()->client_data);
}
bool CPhysicsObject::IsControlling( const IVP_Controller *pController ) const
{
IVP_Core *pCore = m_pObject->get_core();
for ( int i = 0; i < pCore->controllers_of_core.len(); i++ )
{
// already controlling this core?
if ( pCore->controllers_of_core.element_at(i) == pController )
return true;
}
return false;
}
bool CPhysicsObject::IsGravityEnabled() const
{
if ( !IsStatic() )
{
return IsControlling( m_pObject->get_core()->environment->get_gravity_controller() );
}
return false;
}
@ -389,7 +328,7 @@ bool CPhysicsObject::IsDragEnabled() const
bool CPhysicsObject::IsMotionEnabled() const
{
return m_pObject->get_core()->pinned ? false : true;
return false;
}
@ -411,16 +350,6 @@ void CPhysicsObject::EnableGravity( bool enable )
if ( enable == isEnabled )
return;
IVP_Controller *pGravity = m_pObject->get_core()->environment->get_gravity_controller();
if ( enable )
{
m_pObject->get_core()->add_core_controller( pGravity );
}
else
{
m_pObject->get_core()->rem_core_controller( pGravity );
}
}
void CPhysicsObject::EnableDrag( bool enable )
@ -432,17 +361,6 @@ void CPhysicsObject::EnableDrag( bool enable )
if ( enable == isEnabled )
return;
IVP_Controller *pDrag = GetVPhysicsEnvironment()->GetDragController();
if ( enable )
{
m_pObject->get_core()->add_core_controller( pDrag );
}
else
{
m_pObject->get_core()->rem_core_controller( pDrag );
}
}
@ -465,41 +383,6 @@ void CPhysicsObject::RecomputeDragBases()
{
if ( IsStatic() || !GetCollide() )
return;
// Basically we are computing drag as an OBB. Get OBB extents for projection
// scale those extents by appropriate mass/inertia to compute velocity directly (not force)
// in the controller
// NOTE: Compute these even if drag coefficients are zero, because the drag coefficient could change later
// Get an AABB for this object and use the area of each side as a basis for approximating cross-section area for drag
Vector dragMins, dragMaxs;
// NOTE: coordinates in/out of physcollision are in HL units, not IVP
// PERFORMANCE: Cache this? Expensive.
physcollision->CollideGetAABB( &dragMins, &dragMaxs, GetCollide(), vec3_origin, vec3_angle );
Vector areaFractions = physcollision->CollideGetOrthographicAreas( GetCollide() );
Vector delta = dragMaxs - dragMins;
ConvertPositionToIVP( delta.x, delta.y, delta.z );
delta.x = fabsf(delta.x);
delta.y = fabsf(delta.y);
delta.z = fabsf(delta.z);
// dragBasis is now the area of each side
m_dragBasis.x = delta.y * delta.z * areaFractions.x;
m_dragBasis.y = delta.x * delta.z * areaFractions.y;
m_dragBasis.z = delta.x * delta.y * areaFractions.z;
m_dragBasis *= GetInvMass();
const IVP_U_Float_Point *pInvRI = m_pObject->get_core()->get_inv_rot_inertia();
// This angular basis is the integral of each differential drag area's torque over the whole OBB
// need half lengths for this integral
delta *= 0.5;
// rotation about the x axis
m_angDragBasis.x = areaFractions.z * AngDragIntegral( pInvRI->k[0], delta.x, delta.y, delta.z ) + areaFractions.y * AngDragIntegral( pInvRI->k[0], delta.x, delta.z, delta.y );
// rotation about the y axis
m_angDragBasis.y = areaFractions.z * AngDragIntegral( pInvRI->k[1], delta.y, delta.x, delta.z ) + areaFractions.x * AngDragIntegral( pInvRI->k[1], delta.y, delta.z, delta.x );
// rotation about the z axis
m_angDragBasis.z = areaFractions.y * AngDragIntegral( pInvRI->k[2], delta.z, delta.x, delta.y ) + areaFractions.x * AngDragIntegral( pInvRI->k[2], delta.z, delta.y, delta.x );
}
@ -515,10 +398,6 @@ void CPhysicsObject::EnableMotion( bool enable )
if ( isMoveable == enable )
return;
BEGIN_IVP_ALLOCATION();
m_pObject->set_pinned( enable ? IVP_FALSE : IVP_TRUE );
END_IVP_ALLOCATION();
if ( enable && IsHinged() )
{
BecomeHinged( m_hingedAxis-1 );
@ -550,29 +429,12 @@ void CPhysicsObject::DestroyFrictionSnapshot( IPhysicsFrictionSnapshot *pSnapsho
bool CPhysicsObject::IsMassCenterAtDefault() const
{
// this is the actual mass center of the object as created
Vector massCenterHL = GetMassCenterLocalSpace();
// Get the default mass center to see if it has been changed
IVP_U_Float_Point massCenterIVPDefault;
Vector massCenterHLDefault;
GetObject()->get_surface_manager()->get_mass_center( &massCenterIVPDefault );
ConvertPositionToHL( massCenterIVPDefault, massCenterHLDefault );
float delta = (massCenterHLDefault - massCenterHL).Length();
return ( delta <= g_PhysicsUnits.collisionSweepIncrementalEpsilon ) ? true : false;
return false;
}
Vector CPhysicsObject::GetMassCenterLocalSpace() const
{
if ( m_pObject->flags.shift_core_f_object_is_zero )
return vec3_origin;
Vector out;
ConvertPositionToHL( *m_pObject->get_shift_core_f_object(), out );
// core shift is what you add to the mass center to get the origin
// so we want the negative core shift (origin relative position of the mass center)
return -out;
return Vector( 0, 0, 0 );
}
@ -599,7 +461,7 @@ void CPhysicsObject::SetMass( float mass )
Assert( mass > 0 );
mass = clamp( mass, 1.f, VPHYSICS_MAX_MASS );
m_pObject->change_mass( mass );
//m_pObject->change_mass( mass );
SetVolume( m_volume );
RecomputeDragBases();
if ( reset )
@ -610,71 +472,37 @@ void CPhysicsObject::SetMass( float mass )
float CPhysicsObject::GetMass( void ) const
{
return m_pObject->get_core()->get_mass();
return 0.f;
}
float CPhysicsObject::GetInvMass( void ) const
{
return m_pObject->get_core()->get_inv_mass();
return 1.f;
}
Vector CPhysicsObject::GetInertia( void ) const
{
const IVP_U_Float_Point *pRI = m_pObject->get_core()->get_rot_inertia();
Vector hlInertia;
ConvertDirectionToHL( *pRI, hlInertia );
VectorAbs( hlInertia, hlInertia );
return hlInertia;
return Vector(0, 0, 0);
}
Vector CPhysicsObject::GetInvInertia( void ) const
{
const IVP_U_Float_Point *pRI = m_pObject->get_core()->get_inv_rot_inertia();
Vector hlInvInertia;
ConvertDirectionToHL( *pRI, hlInvInertia );
VectorAbs( hlInvInertia, hlInvInertia );
return hlInvInertia;
return Vector(0, 0, 0);
}
void CPhysicsObject::SetInertia( const Vector &inertia )
{
IVP_U_Float_Point ri; ConvertDirectionToIVP( inertia, ri );
ri.k[0] = IVP_Inline_Math::fabsd(ri.k[0]);
ri.k[1] = IVP_Inline_Math::fabsd(ri.k[1]);
ri.k[2] = IVP_Inline_Math::fabsd(ri.k[2]);
m_pObject->get_core()->set_rotation_inertia( &ri );
}
void CPhysicsObject::GetDamping( float *speed, float *rot ) const
{
IVP_Core *pCore = m_pObject->get_core();
if ( speed )
{
*speed = pCore->speed_damp_factor;
}
if ( rot )
{
*rot = pCore->rot_speed_damp_factor.k[0];
}
}
void CPhysicsObject::SetDamping( const float *speed, const float *rot )
{
IVP_Core *pCore = m_pObject->get_core();
if ( speed )
{
pCore->speed_damp_factor = *speed;
}
if ( rot )
{
pCore->rot_speed_damp_factor.set( *rot, *rot, *rot );
}
}
void CPhysicsObject::SetVolume( float volume )
@ -756,13 +584,6 @@ void CPhysicsObject::ApplyForceCenter( const Vector &forceVector )
if ( !IsMoveable() )
return;
IVP_U_Float_Point tmp;
ConvertForceImpulseToIVP( forceVector, tmp );
IVP_Core *core = m_pObject->get_core();
tmp.mult( core->get_inv_mass() );
m_pObject->async_add_speed_object_ws( &tmp );
ClampVelocity();
}
void CPhysicsObject::ApplyForceOffset( const Vector &forceVector, const Vector &worldPosition )
@ -776,95 +597,34 @@ void CPhysicsObject::ApplyForceOffset( const Vector &forceVector, const Vector &
ConvertForceImpulseToIVP( forceVector, force );
ConvertPositionToIVP( worldPosition, pos );
IVP_Core *core = m_pObject->get_core();
core->async_push_core_ws( &pos, &force );
Wake();
ClampVelocity();
}
void CPhysicsObject::CalculateForceOffset( const Vector &forceVector, const Vector &worldPosition, Vector *centerForce, AngularImpulse *centerTorque ) const
{
IVP_U_Point pos;
IVP_U_Float_Point force;
ConvertPositionToIVP( forceVector, force );
ConvertPositionToIVP( worldPosition, pos );
IVP_Core *core = m_pObject->get_core();
const IVP_U_Matrix *m_world_f_core = core->get_m_world_f_core_PSI();
IVP_U_Float_Point point_d_ws;
point_d_ws.subtract(&pos, m_world_f_core->get_position());
IVP_U_Float_Point cross_point_dir;
cross_point_dir.calc_cross_product( &point_d_ws, &force);
m_world_f_core->inline_vimult3( &cross_point_dir, &cross_point_dir);
ConvertAngularImpulseToHL( cross_point_dir, *centerTorque );
ConvertForceImpulseToHL( force, *centerForce );
}
void CPhysicsObject::CalculateVelocityOffset( const Vector &forceVector, const Vector &worldPosition, Vector *centerVelocity, AngularImpulse *centerAngularVelocity ) const
{
IVP_U_Point pos;
IVP_U_Float_Point force;
ConvertForceImpulseToIVP( forceVector, force );
ConvertPositionToIVP( worldPosition, pos );
IVP_Core *core = m_pObject->get_core();
const IVP_U_Matrix *m_world_f_core = core->get_m_world_f_core_PSI();
IVP_U_Float_Point point_d_ws;
point_d_ws.subtract(&pos, m_world_f_core->get_position());
IVP_U_Float_Point cross_point_dir;
cross_point_dir.calc_cross_product( &point_d_ws, &force);
m_world_f_core->inline_vimult3( &cross_point_dir, &cross_point_dir);
cross_point_dir.set_pairwise_mult( &cross_point_dir, core->get_inv_rot_inertia());
ConvertAngularImpulseToHL( cross_point_dir, *centerAngularVelocity );
force.set_multiple( &force, core->get_inv_mass() );
ConvertForceImpulseToHL( force, *centerVelocity );
}
void CPhysicsObject::ApplyTorqueCenter( const AngularImpulse &torqueImpulse )
{
if ( !IsMoveable() )
return;
IVP_U_Float_Point ivpTorque;
ConvertAngularImpulseToIVP( torqueImpulse, ivpTorque );
IVP_Core *core = m_pObject->get_core();
core->async_rot_push_core_multiple_ws( &ivpTorque, 1.0 );
Wake();
ClampVelocity();
}
void CPhysicsObject::GetPosition( Vector *worldPosition, QAngle *angles ) const
{
IVP_U_Matrix matrix;
m_pObject->get_m_world_f_object_AT( &matrix );
if ( worldPosition )
{
ConvertPositionToHL( matrix.vv, *worldPosition );
}
if ( angles )
{
ConvertRotationToHL( matrix, *angles );
}
}
void CPhysicsObject::GetPositionMatrix( matrix3x4_t *positionMatrix ) const
{
IVP_U_Matrix matrix;
m_pObject->get_m_world_f_object_AT( &matrix );
ConvertMatrixToHL( matrix, *positionMatrix );
}
@ -872,38 +632,6 @@ void CPhysicsObject::GetImplicitVelocity( Vector *velocity, AngularImpulse *angu
{
if ( !velocity && !angularVelocity )
return;
IVP_Core *core = m_pObject->get_core();
if ( velocity )
{
// just convert the cached dx
ConvertPositionToHL( core->delta_world_f_core_psis, *velocity );
}
if ( angularVelocity )
{
// compute the relative transform that was actually integrated in the last psi
IVP_U_Quat q_core_f_core;
q_core_f_core.set_invert_mult( &core->q_world_f_core_last_psi, &core->q_world_f_core_next_psi);
// now convert that to an axis/angle pair
Quaternion q( q_core_f_core.x, q_core_f_core.y, q_core_f_core.z, q_core_f_core.w );
AngularImpulse axis;
float angle;
QuaternionAxisAngle( q, axis, angle );
// scale it by the timestep to get a velocity
angle *= core->i_delta_time;
// ConvertDirectionToHL() - convert this ipion direction (in HL type) to HL coords
float tmpY = axis.z;
angularVelocity->z = -axis.y;
angularVelocity->y = tmpY;
angularVelocity->x = axis.x;
// now scale the axis by the angle to return the data in the correct format
(*angularVelocity) *= angle;
}
}
void CPhysicsObject::GetVelocity( Vector *velocity, AngularImpulse *angularVelocity ) const
@ -911,45 +639,10 @@ void CPhysicsObject::GetVelocity( Vector *velocity, AngularImpulse *angularVeloc
if ( !velocity && !angularVelocity )
return;
IVP_Core *core = m_pObject->get_core();
if ( velocity )
{
IVP_U_Float_Point speed;
speed.add( &core->speed, &core->speed_change );
ConvertPositionToHL( speed, *velocity );
}
if ( angularVelocity )
{
IVP_U_Float_Point rotSpeed;
rotSpeed.add( &core->rot_speed, &core->rot_speed_change );
// xform to HL space
ConvertAngularImpulseToHL( rotSpeed, *angularVelocity );
}
}
void CPhysicsObject::GetVelocityAtPoint( const Vector &worldPosition, Vector *pVelocity ) const
{
IVP_Core *core = m_pObject->get_core();
IVP_U_Point pos;
ConvertPositionToIVP( worldPosition, pos );
IVP_U_Float_Point rotSpeed;
rotSpeed.add( &core->rot_speed, &core->rot_speed_change );
IVP_U_Float_Point av_ws;
core->get_m_world_f_core_PSI()->vmult3( &rotSpeed, &av_ws);
IVP_U_Float_Point pos_rel;
pos_rel.subtract( &pos, core->get_position_PSI());
IVP_U_Float_Point cross;
cross.inline_calc_cross_product(&av_ws,&pos_rel);
IVP_U_Float_Point speed;
speed.add(&core->speed, &cross);
speed.add(&core->speed_change);
ConvertPositionToHL( speed, *pVelocity );
}
@ -959,80 +652,18 @@ void CPhysicsObject::AddVelocity( const Vector *velocity, const AngularImpulse *
Assert(IsMoveable());
if ( !IsMoveable() )
return;
IVP_Core *core = m_pObject->get_core();
Wake();
if ( velocity )
{
IVP_U_Float_Point ivpVelocity;
ConvertPositionToIVP( *velocity, ivpVelocity );
core->speed_change.add( &ivpVelocity );
}
if ( angularVelocity )
{
IVP_U_Float_Point ivpAngularVelocity;
ConvertAngularImpulseToIVP( *angularVelocity, ivpAngularVelocity );
core->rot_speed_change.add(&ivpAngularVelocity);
}
ClampVelocity();
}
void CPhysicsObject::SetPosition( const Vector &worldPosition, const QAngle &angles, bool isTeleport )
{
IVP_U_Quat rot;
IVP_U_Point pos;
if ( m_pShadow )
{
UpdateShadow( worldPosition, angles, false, 0 );
}
ConvertPositionToIVP( worldPosition, pos );
ConvertRotationToIVP( angles, rot );
if ( m_pObject->is_collision_detection_enabled() && isTeleport )
{
EnableCollisions( false );
m_pObject->beam_object_to_new_position( &rot, &pos, IVP_FALSE );
EnableCollisions( true );
}
else
{
m_pObject->beam_object_to_new_position( &rot, &pos, IVP_FALSE );
}
}
void CPhysicsObject::SetPositionMatrix( const matrix3x4_t& matrix, bool isTeleport )
{
if ( m_pShadow )
{
Vector worldPosition;
QAngle angles;
MatrixAngles( matrix, angles );
MatrixGetColumn( matrix, 3, worldPosition );
UpdateShadow( worldPosition, angles, false, 0 );
}
IVP_U_Quat rot;
IVP_U_Matrix mat;
ConvertMatrixToIVP( matrix, mat );
rot.set_quaternion( &mat );
if ( m_pObject->is_collision_detection_enabled() && isTeleport )
{
EnableCollisions( false );
m_pObject->beam_object_to_new_position( &rot, &mat.vv, IVP_FALSE );
EnableCollisions( true );
}
else
{
m_pObject->beam_object_to_new_position( &rot, &mat.vv, IVP_FALSE );
}
}
void CPhysicsObject::SetVelocityInstantaneous( const Vector *velocity, const AngularImpulse *angularVelocity )
@ -1040,44 +671,13 @@ void CPhysicsObject::SetVelocityInstantaneous( const Vector *velocity, const Ang
Assert(IsMoveable());
if ( !IsMoveable() )
return;
IVP_Core *core = m_pObject->get_core();
WakeNow();
if ( velocity )
{
ConvertPositionToIVP( *velocity, core->speed );
core->speed_change.set_to_zero();
}
if ( angularVelocity )
{
ConvertAngularImpulseToIVP( *angularVelocity, core->rot_speed );
core->rot_speed_change.set_to_zero();
}
ClampVelocity();
}
void CPhysicsObject::SetVelocity( const Vector *velocity, const AngularImpulse *angularVelocity )
{
if ( !IsMoveable() )
return;
IVP_Core *core = m_pObject->get_core();
Wake();
if ( velocity )
{
ConvertPositionToIVP( *velocity, core->speed_change );
core->speed.set_to_zero();
}
if ( angularVelocity )
{
ConvertAngularImpulseToIVP( *angularVelocity, core->rot_speed_change );
core->rot_speed.set_to_zero();
}
ClampVelocity();
}
@ -1086,7 +686,6 @@ void CPhysicsObject::ClampVelocity()
if ( m_pShadow )
return;
m_pObject->get_core()->apply_velocity_limit();
}
void GetWorldCoordFromSynapse( IVP_Synapse_Friction *pfriction, IVP_U_Point &world )
@ -1116,21 +715,7 @@ bool CPhysicsObject::GetContactPoint( Vector *contactPoint, IPhysicsObject **con
void CPhysicsObject::SetShadow( float maxSpeed, float maxAngularSpeed, bool allowPhysicsMovement, bool allowPhysicsRotation )
{
if ( m_pShadow )
{
m_pShadow->MaxSpeed( maxSpeed, maxAngularSpeed );
}
else
{
m_shadowTempGravityDisable = false;
CPhysicsEnvironment *pVEnv = GetVPhysicsEnvironment();
m_pShadow = pVEnv->CreateShadowController( this, allowPhysicsMovement, allowPhysicsRotation );
m_pShadow->MaxSpeed( maxSpeed, maxAngularSpeed );
// This really should be in the game code, but do this here because the game may (does) use
// shadow/AI control as a collision filter indicator.
RecheckCollisionFilter();
}
return;
}
void CPhysicsObject::UpdateShadow( const Vector &targetPosition, const QAngle &targetAngles, bool tempDisableGravity, float timeOffset )
@ -1302,100 +887,32 @@ void CPhysicsObject::BecomeTrigger()
if ( IsTrigger() )
return;
if ( GetShadowController() )
{
// triggers won't have the standard collisions, so the material change is no longer necessary
// also: This will fix problems with surfaceprops if the trigger becomes a fluid.
GetShadowController()->UseShadowMaterial( false );
}
EnableDrag( false );
EnableGravity( false );
// UNDONE: Use defaults here? Do we want object sets by default?
IVP_Template_Phantom trigger;
trigger.manage_intruding_cores = IVP_TRUE; // manage a list of intruded objects
trigger.manage_sleeping_cores = IVP_TRUE; // don't untouch/touch on sleep/wake
trigger.dont_check_for_unmoveables = IVP_TRUE;
trigger.exit_policy_extra_radius = 0.1f; // relatively strict exit check [m]
bool enableCollisions = IsCollisionEnabled();
EnableCollisions( false );
BEGIN_IVP_ALLOCATION();
m_pObject->convert_to_phantom( &trigger );
END_IVP_ALLOCATION();
// hook up events
CPhysicsEnvironment *pVEnv = GetVPhysicsEnvironment();
pVEnv->PhantomAdd( this );
EnableCollisions( enableCollisions );
}
void CPhysicsObject::RemoveTrigger()
{
IVP_Controller_Phantom *pController = m_pObject->get_controller_phantom();
// NOTE: This will remove the back-link in the object
delete pController;
}
bool CPhysicsObject::IsTrigger() const
{
return m_pObject->get_controller_phantom() != NULL ? true : false;
return false;
}
bool CPhysicsObject::IsFluid() const
{
IVP_Controller_Phantom *pController = m_pObject->get_controller_phantom();
if ( pController )
{
// UNDONE: Make a base class for triggers? IPhysicsTrigger?
// and derive fluids and any other triggers from that class
// then you can ask that class what to do here.
if ( pController->client_data )
return true;
}
return false;
}
// sets the object to be hinged. Fixed it place, but able to rotate around one axis.
void CPhysicsObject::BecomeHinged( int localAxis )
{
if ( IsMoveable() )
{
float savedMass = GetMass();
IVP_U_Float_Hesse *iri = (IVP_U_Float_Hesse *)m_pObject->get_core()->get_inv_rot_inertia();
float savedRI[3];
for ( int i = 0; i < 3; i++ )
savedRI[i] = iri->k[i];
SetMass( VPHYSICS_MAX_MASS );
IVP_U_Float_Hesse tmp = *iri;
#if 0
for ( i = 0; i < 3; i++ )
tmp.k[i] = savedRI[i];
#else
int localAxisIVP = ConvertCoordinateAxisToIVP(localAxis);
tmp.k[localAxisIVP] = savedRI[localAxisIVP];
#endif
SetMass( savedMass );
*iri = tmp;
}
m_hingedAxis = localAxis+1;
}
void CPhysicsObject::RemoveHinged()
{
m_hingedAxis = 0;
m_pObject->get_core()->calc_calc();
}
// dumps info about the object to Msg()
@ -1453,18 +970,6 @@ void CPhysicsObject::OutputDebugInfo() const
bool CPhysicsObject::IsAttachedToConstraint( bool bExternalOnly ) const
{
if ( m_pObject )
{
for (int k = m_pObject->get_core()->controllers_of_core.len()-1; k>=0;k--)
{
IVP_Controller *pController = m_pObject->get_core()->controllers_of_core.element_at(k);
if ( pController->get_controller_priority() == IVP_CP_CONSTRAINTS )
{
if ( !bExternalOnly || IsExternalConstraint(pController, GetGameData()) )
return true;
}
}
}
return false;
}
@ -1565,9 +1070,9 @@ CPhysicsObject *CreatePhysicsObject( CPhysicsEnvironment *pEnvironment, const CP
BEGIN_IVP_ALLOCATION();
IVP_Polygon *realObject = pEnvironment->GetIVPEnvironment()->create_polygon(pSurman, &objectTemplate, &rotation, &pos);
// IVP_Polygon *realObject = pEnvironment->GetIVPEnvironment()->create_polygon(pSurman, &objectTemplate, &rotation, &pos);
pObject->Init( pCollisionModel, realObject, materialIndex, pParams->volume, pParams->dragCoefficient, pParams->dragCoefficient );
pObject->Init( pCollisionModel, NULL, materialIndex, pParams->volume, pParams->dragCoefficient, pParams->dragCoefficient );
pObject->SetGameData( pParams->pGameData );
if ( pParams->enableCollisions )
@ -1708,7 +1213,7 @@ END_DATADESC()
bool CPhysicsObject::IsCollisionEnabled() const
{
return GetObject()->is_collision_detection_enabled() ? true : false;
return false;
}
void CPhysicsObject::WriteToTemplate( vphysics_save_cphysicsobject_t &objectTemplate )

View File

@ -288,29 +288,12 @@ void CPlayerController::AttachObject( void )
{
m_pObject->EnableDrag( false );
IVP_Real_Object *pivp = m_pObject->GetObject();
IVP_Core *pCore = pivp->get_core();
m_saveRot = pCore->rot_speed_damp_factor;
pCore->rot_speed_damp_factor = IVP_U_Float_Point( 100, 100, 100 );
pCore->calc_calc();
BEGIN_IVP_ALLOCATION();
pivp->get_environment()->get_controller_manager()->add_controller_to_core( this, pCore );
END_IVP_ALLOCATION();
m_pObject->AddCallbackFlags( CALLBACK_IS_PLAYER_CONTROLLER );
}
void CPlayerController::DetachObject( void )
{
if ( !m_pObject )
return;
IVP_Real_Object *pivp = m_pObject->GetObject();
IVP_Core *pCore = pivp->get_core();
pCore->rot_speed_damp_factor = m_saveRot;
pCore->calc_calc();
m_pObject->RemoveCallbackFlags( CALLBACK_IS_PLAYER_CONTROLLER );
m_pObject = NULL;
pivp->get_environment()->get_controller_manager()->remove_controller_from_core( this, pCore );
SetGround(NULL);
}
void CPlayerController::SetObject( IPhysicsObject *pObject )
@ -360,14 +343,14 @@ void CPlayerController::StepUp( float height )
return;
Vector step( 0, 0, height );
/*
IVP_Real_Object *pIVP = m_pObject->GetObject();
IVP_U_Quat world_f_object;
IVP_U_Point positionIVP, deltaIVP;
ConvertPositionToIVP( step, deltaIVP );
pIVP->get_quat_world_f_object_AT( &world_f_object, &positionIVP );
positionIVP.add( &deltaIVP );
pIVP->beam_object_to_new_position( &world_f_object, &positionIVP, IVP_TRUE );
pIVP->beam_object_to_new_position( &world_f_object, &positionIVP, IVP_TRUE );*/
}
void CPlayerController::Jump()
@ -632,34 +615,6 @@ void CPlayerController::Update( const Vector& position, const Vector& velocity,
#endif
m_currentSpeed.set( &targetSpeedIVP );
IVP_Real_Object *pivp = m_pObject->GetObject();
IVP_Core *pCore = pivp->get_core();
IVP_Environment *pEnv = pivp->get_environment();
pEnv->get_controller_manager()->ensure_core_in_simulation(pCore);
m_enable = true;
// m_onground makes this object anti-grav
// UNDONE: Re-evaluate this
m_onground = false;//onground;
if ( velocity.LengthSqr() <= 0.1f )
{
// no input velocity, just go where physics takes you.
m_enable = false;
ground = NULL;
}
else
{
MaxSpeed( velocity );
}
CPhysicsObject *pGroundObject = static_cast<CPhysicsObject *>(ground);
SetGround( pGroundObject );
if ( m_pGround )
{
const IVP_U_Matrix *pMatrix = m_pGround->GetObject()->get_core()->get_m_world_f_core_PSI();
pMatrix->vimult4( &m_targetPosition, &m_groundPosition );
}
}
void CPlayerController::MaxSpeed( const Vector &velocity )

View File

@ -413,6 +413,8 @@ public:
bool SetSingleConvex( void )
{
return false;
const IVP_Compact_Ledgetree_Node *node = m_pSurface->get_compact_ledge_tree_root();
if ( node->is_terminal() == IVP_TRUE )
{
@ -477,6 +479,9 @@ FORCEINLINE fltx4 ConvertDirectionToIVP( const fltx4 & a )
CTraceIVP::CTraceIVP( const CPhysCollide *pCollide, const Vector &origin, const QAngle &angles )
{
if( !pCollide )
return;
#if USE_COLLIDE_MAP
m_pCollideMap = pCollide->GetCollideMap();
#else
@ -1301,13 +1306,6 @@ void CTraceSolverSweptObject::DoSweep( void )
{
VPROF("TraceSolver::DoSweep");
InitOSRay();
// iterate ledge tree of obstacle
const IVP_Compact_Surface *pSurface = m_obstacleIVP->m_pSurface;
const IVP_Compact_Ledgetree_Node *lt_node_root;
lt_node_root = pSurface->get_compact_ledge_tree_root();
SweepLedgeTree_r( lt_node_root );
}
void CPhysicsTrace::SweepBoxIVP( const Vector &start, const Vector &end, const Vector &mins, const Vector &maxs, const CPhysCollide *pCollide, const Vector &surfaceOrigin, const QAngle &surfaceAngles, trace_t *ptr )
@ -2362,6 +2360,8 @@ void TraceGetAABB_r( Vector *pMins, Vector *pMaxs, const IVP_Compact_Ledgetree_N
void CPhysicsTrace::GetAABB( Vector *pMins, Vector *pMaxs, const CPhysCollide *pCollide, const Vector &collideOrigin, const QAngle &collideAngles )
{
return;
CTraceIVP ivp( pCollide, collideOrigin, collideAngles );
if ( ivp.SetSingleConvex() )

View File

@ -17,6 +17,19 @@ def configure(conf):
'HAVANA_CONSTRAINTS',
'HAVOK_MOPP'
])
conf.env.append_unique('LINKFLAGS', [
# "-L/home/nillerusr/projects/PhysX/physx/install/linux/PhysX/bin/linux.clang/release/"
"-L/home/nillerusr/projects/PhysX/physx/install/linux/PhysX/bin/linux.clang/debug/"
])
conf.check(lib='PhysX_static_64', uselib_store='PHYSX')
conf.check(lib='PhysXFoundation_static_64', uselib_store='PHYSX_FOUNDATION')
conf.check(lib='PhysXCommon_static_64', uselib_store='PHYSX_COMMON')
conf.check(lib='PhysXPvdSDK_static_64', uselib_store='PHYSX_PVD')
conf.check(lib='PhysXExtensions_static_64', uselib_store='PHYSX_EXT')
conf.check(lib='PhysXCooking_static_64', uselib_store='PHYSX_COOKING')
def build(bld):
source = [
'convert.cpp',
@ -56,12 +69,14 @@ def build(bld):
'../ivp/ivp_controller',
'../ivp/ivp_compact_builder',
'../ivp/havana/havok',
'../ivp/havana'
'../ivp/havana',
'/home/nillerusr/projects/PhysX/physx/install/linux/PhysX/include',
'/home/nillerusr/projects/PhysX/physx/install/linux/PxShared/include'
]
defines = []
libs = ['tier0','havana_constraints','hk_math','hk_base','ivp_compactbuilder','ivp_physics','tier1','tier2','vstdlib','mathlib']
libs = ['tier0','havana_constraints','hk_math','hk_base','ivp_compactbuilder','ivp_physics','tier1','tier2','vstdlib','mathlib', 'PHYSX', 'PHYSX_PVD', 'PHYSX_EXT', 'PHYSX_COOKING', 'PHYSX_FOUNDATION', 'PHYSX_COMMON']
install_path = bld.env.LIBDIR