You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
242 lines
6.9 KiB
242 lines
6.9 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
// $NoKeywords: $ |
|
// |
|
//=============================================================================// |
|
#include "cbase.h" |
|
#include "interface.h" |
|
#include "vphysics/object_hash.h" |
|
#include "vphysics/collision_set.h" |
|
#include "tier1/tier1.h" |
|
#include "ivu_vhash.hxx" |
|
|
|
|
|
|
|
#if defined(_WIN32) && !defined(_X360) |
|
#define WIN32_LEAN_AND_MEAN |
|
#include <windows.h> |
|
#endif // _WIN32 && !_X360 |
|
|
|
#include "vphysics_interfaceV30.h" |
|
|
|
// memdbgon must be the last include file in a .cpp file!!! |
|
#include "tier0/memdbgon.h" |
|
|
|
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 ) |
|
{ |
|
if ( fdwReason == DLL_PROCESS_ATTACH ) |
|
{ |
|
// 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; |
|
} |
|
|
|
#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 |
|
|
|
|
|
// simple 32x32 bit array |
|
class CPhysicsCollisionSet : public IPhysicsCollisionSet |
|
{ |
|
public: |
|
~CPhysicsCollisionSet() {} |
|
CPhysicsCollisionSet() |
|
{ |
|
memset( m_bits, 0, sizeof(m_bits) ); |
|
} |
|
void EnableCollisions( int index0, int index1 ) |
|
{ |
|
Assert(index0<32&&index1<32); |
|
m_bits[index0] |= 1<<index1; |
|
m_bits[index1] |= 1<<index0; |
|
} |
|
void DisableCollisions( int index0, int index1 ) |
|
{ |
|
Assert(index0<32&&index1<32); |
|
m_bits[index0] &= ~(1<<index1); |
|
m_bits[index1] &= ~(1<<index0); |
|
} |
|
|
|
bool ShouldCollide( int index0, int index1 ) |
|
{ |
|
Assert(index0<32&&index1<32); |
|
return (m_bits[index0] & (1<<index1)) ? true : false; |
|
} |
|
private: |
|
unsigned int m_bits[32]; |
|
}; |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Main physics interface |
|
//----------------------------------------------------------------------------- |
|
class CPhysicsInterface : public CTier1AppSystem<IPhysics> |
|
{ |
|
public: |
|
CPhysicsInterface() : m_pCollisionSetHash(NULL) {} |
|
virtual void *QueryInterface( const char *pInterfaceName ); |
|
virtual IPhysicsEnvironment *CreateEnvironment( void ); |
|
virtual void DestroyEnvironment( IPhysicsEnvironment *pEnvironment ); |
|
virtual IPhysicsEnvironment *GetActiveEnvironmentByIndex( int index ); |
|
virtual IPhysicsObjectPairHash *CreateObjectPairHash(); |
|
virtual void DestroyObjectPairHash( IPhysicsObjectPairHash *pHash ); |
|
virtual IPhysicsCollisionSet *FindOrCreateCollisionSet( unsigned int id, int maxElementCount ); |
|
virtual IPhysicsCollisionSet *FindCollisionSet( unsigned int id ); |
|
virtual void DestroyAllCollisionSets(); |
|
|
|
private: |
|
CUtlVector<IPhysicsEnvironment *> m_envList; |
|
CUtlVector<CPhysicsCollisionSet> m_collisionSets; |
|
IVP_VHash_Store *m_pCollisionSetHash; |
|
}; |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Expose singleton |
|
//----------------------------------------------------------------------------- |
|
static CPhysicsInterface g_MainDLLInterface; |
|
IPhysics *g_PhysicsInternal = &g_MainDLLInterface; |
|
EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CPhysicsInterface, IPhysics, VPHYSICS_INTERFACE_VERSION, g_MainDLLInterface ); |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Query interface |
|
//----------------------------------------------------------------------------- |
|
void *CPhysicsInterface::QueryInterface( const char *pInterfaceName ) |
|
{ |
|
// Loading the datacache DLL mounts *all* interfaces |
|
// This includes the backward-compatible interfaces + other vphysics interfaces |
|
CreateInterfaceFn factory = Sys_GetFactoryThis(); // This silly construction is necessary |
|
return factory( pInterfaceName, NULL ); // to prevent the LTCG compiler from crashing. |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Implementation of IPhysics |
|
//----------------------------------------------------------------------------- |
|
IPhysicsEnvironment *CPhysicsInterface::CreateEnvironment( void ) |
|
{ |
|
IPhysicsEnvironment *pEnvironment = CreatePhysicsEnvironment(); |
|
m_envList.AddToTail( pEnvironment ); |
|
return pEnvironment; |
|
} |
|
|
|
void CPhysicsInterface::DestroyEnvironment( IPhysicsEnvironment *pEnvironment ) |
|
{ |
|
m_envList.FindAndRemove( pEnvironment ); |
|
delete pEnvironment; |
|
} |
|
|
|
IPhysicsEnvironment *CPhysicsInterface::GetActiveEnvironmentByIndex( int index ) |
|
{ |
|
if ( index < 0 || index >= m_envList.Count() ) |
|
return NULL; |
|
|
|
return m_envList[index]; |
|
} |
|
|
|
IPhysicsObjectPairHash *CPhysicsInterface::CreateObjectPairHash() |
|
{ |
|
return ::CreateObjectPairHash(); |
|
} |
|
|
|
void CPhysicsInterface::DestroyObjectPairHash( IPhysicsObjectPairHash *pHash ) |
|
{ |
|
delete pHash; |
|
} |
|
// holds a cache of these by id. |
|
// NOTE: This is stuffed into vphysics.dll as a sneaky way of sharing the memory between |
|
// client and server in single player. So you can't have different client/server rules. |
|
IPhysicsCollisionSet *CPhysicsInterface::FindOrCreateCollisionSet( unsigned int id, int maxElementCount ) |
|
{ |
|
if ( !m_pCollisionSetHash ) |
|
{ |
|
m_pCollisionSetHash = new IVP_VHash_Store(256); |
|
} |
|
Assert( id != 0 ); |
|
Assert( maxElementCount <= 32 ); |
|
if ( maxElementCount > 32 ) |
|
return NULL; |
|
|
|
IPhysicsCollisionSet *pSet = FindCollisionSet( id ); |
|
if ( pSet ) |
|
return pSet; |
|
int index = m_collisionSets.AddToTail(); |
|
m_pCollisionSetHash->add_elem( (void *)id, (void *)(index+1) ); |
|
return &m_collisionSets[index]; |
|
} |
|
|
|
IPhysicsCollisionSet *CPhysicsInterface::FindCollisionSet( unsigned int id ) |
|
{ |
|
if ( m_pCollisionSetHash ) |
|
{ |
|
int index = (int)m_pCollisionSetHash->find_elem( (void *)id ); |
|
if ( index > 0 ) |
|
{ |
|
Assert( index <= m_collisionSets.Count() ); |
|
if ( index <= m_collisionSets.Count() ) |
|
{ |
|
return &m_collisionSets[index-1]; |
|
} |
|
} |
|
} |
|
return NULL; |
|
} |
|
|
|
void CPhysicsInterface::DestroyAllCollisionSets() |
|
{ |
|
m_collisionSets.Purge(); |
|
delete m_pCollisionSetHash; |
|
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 |
|
|
|
|