202 lines
6.0 KiB
C++
202 lines
6.0 KiB
C++
//=================================================================================================
|
|
//
|
|
// The base physics DLL interface
|
|
//
|
|
//=================================================================================================
|
|
|
|
#include "cbase.h"
|
|
|
|
#include "vjolt_environment.h"
|
|
#include "vjolt_collide.h"
|
|
#include "vjolt_surfaceprops.h"
|
|
#include "vjolt_objectpairhash.h"
|
|
|
|
#include "vjolt_interface.h"
|
|
|
|
// memdbgon must be the last include file in a .cpp file!!!
|
|
#include "tier0/memdbgon.h"
|
|
|
|
//-------------------------------------------------------------------------------------------------
|
|
|
|
// Slart:
|
|
// Pre-allocate 64 megabytes for physics allocations.
|
|
// I don't think we've tuned this value. It's just a big number that we probably won't ever hit.
|
|
static constexpr uint kTempAllocSize = 64 * 1024 * 1024;
|
|
|
|
// Josh:
|
|
// We cannot support more than 64 threads doing physics work because
|
|
// of the code I wrote in vjolt_listener_contact to dispatch events.
|
|
// It uses a single uint64_t bitmask that is iterated on for the thread-local
|
|
// event vectors.
|
|
// This isn't an issue, the benefits of more threads tends to trail off between
|
|
// 8-16 threads anyway.
|
|
static constexpr uint kMaxPhysicsThreads = 64;
|
|
|
|
DEFINE_LOGGING_CHANNEL_NO_TAGS( LOG_VJolt, "VJolt", 0, LS_MESSAGE, Color( 205, 142, 212, 255 ) );
|
|
DEFINE_LOGGING_CHANNEL_NO_TAGS( LOG_JoltInternal, "Jolt" );
|
|
|
|
JoltPhysicsInterface JoltPhysicsInterface::s_PhysicsInterface;
|
|
EXPOSE_SINGLE_INTERFACE_GLOBALVAR( JoltPhysicsInterface, IPhysics, VPHYSICS_INTERFACE_VERSION, JoltPhysicsInterface::GetInstance() );
|
|
|
|
//-------------------------------------------------------------------------------------------------
|
|
|
|
// Slart:
|
|
// Instead of using Jolt's allocator override functionality, we disable it and just define the
|
|
// functions here, all of Jolt's memory allocation goes through here, besides new and delete
|
|
// which use the Valve overrides in memoverride.cpp.
|
|
// For Desolation we use mi-malloc rather than dlmalloc, that also gets built into the statically
|
|
// linked releases for gmod (along with all of tier0 and vstdlib).
|
|
namespace JPH {
|
|
|
|
void *Allocate( size_t inSize )
|
|
{
|
|
return MemAlloc_Alloc( inSize );
|
|
}
|
|
|
|
void Free( void *inBlock )
|
|
{
|
|
MemAlloc_Free( inBlock );
|
|
}
|
|
|
|
void *AlignedAllocate( size_t inSize, size_t inAlignment )
|
|
{
|
|
return MemAlloc_AllocAligned( inSize, inAlignment );
|
|
}
|
|
|
|
void AlignedFree( void *inBlock )
|
|
{
|
|
MemAlloc_FreeAligned( inBlock );
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------------------
|
|
|
|
InitReturnVal_t JoltPhysicsInterface::Init()
|
|
{
|
|
const InitReturnVal_t nRetVal = BaseClass::Init();
|
|
if ( nRetVal != INIT_OK )
|
|
{
|
|
return nRetVal;
|
|
}
|
|
|
|
MathLib_Init();
|
|
|
|
// Install callbacks
|
|
JPH::Trace = JoltPhysicsInterface::OnTrace;
|
|
JPH_IF_ENABLE_ASSERTS( JPH::AssertFailed = JoltPhysicsInterface::OnAssert; )
|
|
|
|
// Create a factory
|
|
JPH::Factory::sInstance = new JPH::Factory();
|
|
|
|
// Register all Jolt physics types
|
|
JPH::RegisterTypes();
|
|
|
|
// Create an allocator for temporary allocations during physics simulations
|
|
m_pTempAllocator = new JPH::TempAllocatorImpl( kTempAllocSize );
|
|
|
|
// Josh:
|
|
// We may want to replace this with a better heuristic, or add a launch arg for this in future.
|
|
// Right now, this does what -1 does in Jolt, but limits it to 64 threads, as we cannot support
|
|
// more than this (see above).
|
|
const uint32 threadCount = Min( std::thread::hardware_concurrency() - 1, kMaxPhysicsThreads );
|
|
m_pJobSystem = new JPH::JobSystemThreadPool( JPH::cMaxPhysicsJobs, JPH::cMaxPhysicsBarriers, threadCount );
|
|
|
|
return INIT_OK;
|
|
}
|
|
|
|
void JoltPhysicsInterface::Shutdown()
|
|
{
|
|
delete m_pJobSystem;
|
|
delete m_pTempAllocator;
|
|
delete JPH::Factory::sInstance;
|
|
|
|
BaseClass::Shutdown();
|
|
}
|
|
|
|
void *JoltPhysicsInterface::QueryInterface( const char *pInterfaceName )
|
|
{
|
|
CreateInterfaceFn factory = Sys_GetFactoryThis();
|
|
return factory( pInterfaceName, NULL );
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------------------
|
|
|
|
IPhysicsEnvironment *JoltPhysicsInterface::CreateEnvironment()
|
|
{
|
|
return new JoltPhysicsEnvironment();
|
|
}
|
|
|
|
void JoltPhysicsInterface::DestroyEnvironment( IPhysicsEnvironment *pEnvironment )
|
|
{
|
|
delete static_cast<JoltPhysicsEnvironment *>( pEnvironment );
|
|
}
|
|
|
|
IPhysicsEnvironment *JoltPhysicsInterface::GetActiveEnvironmentByIndex( int index )
|
|
{
|
|
// Josh: Nothing uses this... ever.
|
|
Log_Stub( LOG_VJolt );
|
|
return nullptr;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------------------
|
|
|
|
IPhysicsObjectPairHash *JoltPhysicsInterface::CreateObjectPairHash()
|
|
{
|
|
return new JoltPhysicsObjectPairHash;
|
|
}
|
|
|
|
void JoltPhysicsInterface::DestroyObjectPairHash( IPhysicsObjectPairHash *pHash )
|
|
{
|
|
delete static_cast<JoltPhysicsObjectPairHash *>( pHash );
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------------------
|
|
|
|
IPhysicsCollisionSet *JoltPhysicsInterface::FindOrCreateCollisionSet( unsigned int id, int maxElementCount )
|
|
{
|
|
if ( maxElementCount > 32 )
|
|
return nullptr;
|
|
|
|
if ( IPhysicsCollisionSet *pSet = FindCollisionSet( id ) )
|
|
return pSet;
|
|
|
|
auto result = m_CollisionSets.emplace( id, JoltPhysicsCollisionSet{} );
|
|
return &result.first->second;
|
|
}
|
|
|
|
IPhysicsCollisionSet *JoltPhysicsInterface::FindCollisionSet( unsigned int id )
|
|
{
|
|
auto iter = m_CollisionSets.find( id );
|
|
if ( iter != m_CollisionSets.end() )
|
|
return &iter->second;
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
void JoltPhysicsInterface::DestroyAllCollisionSets()
|
|
{
|
|
m_CollisionSets.clear();
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------------------
|
|
|
|
void JoltPhysicsInterface::OnTrace( const char *fmt, ... )
|
|
{
|
|
va_list args;
|
|
char msg[MAX_LOGGING_MESSAGE_LENGTH];
|
|
|
|
va_start( args, fmt );
|
|
V_vsnprintf( msg, sizeof( msg ), fmt, args );
|
|
va_end( args );
|
|
|
|
Log_Msg( LOG_JoltInternal, "%s\n", msg );
|
|
}
|
|
|
|
bool JoltPhysicsInterface::OnAssert( const char *inExpression, const char *inMessage, const char *inFile, uint inLine )
|
|
{
|
|
const char *message = inMessage ? inMessage : inExpression;
|
|
(void) message;
|
|
AssertMsg_Internal( false, inLine, inFile, message );
|
|
return false;
|
|
}
|