-
Notifications
You must be signed in to change notification settings - Fork 82
/
Copy pathmain.cpp
242 lines (204 loc) · 6.89 KB
/
main.cpp
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
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
//========= 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