-
Notifications
You must be signed in to change notification settings - Fork 93
Expand file tree
/
Copy pathvjolt_interface.cpp
More file actions
213 lines (164 loc) · 6.47 KB
/
vjolt_interface.cpp
File metadata and controls
213 lines (164 loc) · 6.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
//=================================================================================================
//
// 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 );
}
//-------------------------------------------------------------------------------------------------
static std::vector<JoltPhysicsEnvironment *> g_pPhysicsEnvironments;
IPhysicsEnvironment *JoltPhysicsInterface::CreateEnvironment()
{
JoltPhysicsEnvironment *pEnvironment = new JoltPhysicsEnvironment();
g_pPhysicsEnvironments.push_back(pEnvironment);
return pEnvironment;
}
void JoltPhysicsInterface::DestroyEnvironment( IPhysicsEnvironment *pEnvironment )
{
JoltPhysicsEnvironment *pJoltEnvironment = static_cast<JoltPhysicsEnvironment *>( pEnvironment );
auto it = std::find(g_pPhysicsEnvironments.begin(), g_pPhysicsEnvironments.end(), pJoltEnvironment);
if (it != g_pPhysicsEnvironments.end())
{
g_pPhysicsEnvironments.erase(it);
}
delete pJoltEnvironment;
}
IPhysicsEnvironment *JoltPhysicsInterface::GetActiveEnvironmentByIndex( int index )
{
if ( index < 0 || index >= (int)g_pPhysicsEnvironments.size() )
return NULL;
return g_pPhysicsEnvironments[index];
}
//-------------------------------------------------------------------------------------------------
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;
}