Team Fortress 2 Source Code as on 22/4/2020
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

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //=============================================================================//
  8. #include "cbase.h"
  9. #include "interface.h"
  10. #include "vphysics/object_hash.h"
  11. #include "vphysics/collision_set.h"
  12. #include "tier1/tier1.h"
  13. #include "ivu_vhash.hxx"
  14. #if defined(_WIN32) && !defined(_X360)
  15. #define WIN32_LEAN_AND_MEAN
  16. #include <windows.h>
  17. #endif // _WIN32 && !_X360
  18. #include "vphysics_interfaceV30.h"
  19. // memdbgon must be the last include file in a .cpp file!!!
  20. #include "tier0/memdbgon.h"
  21. static void ivu_string_print_function( const char *str )
  22. {
  23. Msg("%s", str);
  24. }
  25. #if defined(_WIN32) && !defined(_XBOX)
  26. //HMODULE gPhysicsDLLHandle;
  27. #pragma warning (disable:4100)
  28. BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved )
  29. {
  30. if ( fdwReason == DLL_PROCESS_ATTACH )
  31. {
  32. ivp_set_message_print_function( ivu_string_print_function );
  33. MathLib_Init( 2.2f, 2.2f, 0.0f, 2.0f, false, false, false, false );
  34. // store out module handle
  35. //gPhysicsDLLHandle = (HMODULE)hinstDLL;
  36. }
  37. else if ( fdwReason == DLL_PROCESS_DETACH )
  38. {
  39. }
  40. return TRUE;
  41. }
  42. #endif // _WIN32
  43. #ifdef POSIX
  44. void __attribute__ ((constructor)) vphysics_init(void);
  45. void vphysics_init(void)
  46. {
  47. ivp_set_message_print_function( ivu_string_print_function );
  48. MathLib_Init( 2.2f, 2.2f, 0.0f, 2.0f, false, false, false, false );
  49. }
  50. #endif
  51. // simple 32x32 bit array
  52. class CPhysicsCollisionSet : public IPhysicsCollisionSet
  53. {
  54. public:
  55. ~CPhysicsCollisionSet() {}
  56. CPhysicsCollisionSet()
  57. {
  58. memset( m_bits, 0, sizeof(m_bits) );
  59. }
  60. void EnableCollisions( int index0, int index1 )
  61. {
  62. Assert(index0<32&&index1<32);
  63. m_bits[index0] |= 1<<index1;
  64. m_bits[index1] |= 1<<index0;
  65. }
  66. void DisableCollisions( int index0, int index1 )
  67. {
  68. Assert(index0<32&&index1<32);
  69. m_bits[index0] &= ~(1<<index1);
  70. m_bits[index1] &= ~(1<<index0);
  71. }
  72. bool ShouldCollide( int index0, int index1 )
  73. {
  74. Assert(index0<32&&index1<32);
  75. return (m_bits[index0] & (1<<index1)) ? true : false;
  76. }
  77. private:
  78. unsigned int m_bits[32];
  79. };
  80. //-----------------------------------------------------------------------------
  81. // Main physics interface
  82. //-----------------------------------------------------------------------------
  83. class CPhysicsInterface : public CTier1AppSystem<IPhysics>
  84. {
  85. public:
  86. CPhysicsInterface() : m_pCollisionSetHash(NULL) {}
  87. virtual void *QueryInterface( const char *pInterfaceName );
  88. virtual IPhysicsEnvironment *CreateEnvironment( void );
  89. virtual void DestroyEnvironment( IPhysicsEnvironment *pEnvironment );
  90. virtual IPhysicsEnvironment *GetActiveEnvironmentByIndex( int index );
  91. virtual IPhysicsObjectPairHash *CreateObjectPairHash();
  92. virtual void DestroyObjectPairHash( IPhysicsObjectPairHash *pHash );
  93. virtual IPhysicsCollisionSet *FindOrCreateCollisionSet( unsigned int id, int maxElementCount );
  94. virtual IPhysicsCollisionSet *FindCollisionSet( unsigned int id );
  95. virtual void DestroyAllCollisionSets();
  96. private:
  97. CUtlVector<IPhysicsEnvironment *> m_envList;
  98. CUtlVector<CPhysicsCollisionSet> m_collisionSets;
  99. IVP_VHash_Store *m_pCollisionSetHash;
  100. };
  101. //-----------------------------------------------------------------------------
  102. // Expose singleton
  103. //-----------------------------------------------------------------------------
  104. static CPhysicsInterface g_MainDLLInterface;
  105. IPhysics *g_PhysicsInternal = &g_MainDLLInterface;
  106. EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CPhysicsInterface, IPhysics, VPHYSICS_INTERFACE_VERSION, g_MainDLLInterface );
  107. //-----------------------------------------------------------------------------
  108. // Query interface
  109. //-----------------------------------------------------------------------------
  110. void *CPhysicsInterface::QueryInterface( const char *pInterfaceName )
  111. {
  112. // Loading the datacache DLL mounts *all* interfaces
  113. // This includes the backward-compatible interfaces + other vphysics interfaces
  114. CreateInterfaceFn factory = Sys_GetFactoryThis(); // This silly construction is necessary
  115. return factory( pInterfaceName, NULL ); // to prevent the LTCG compiler from crashing.
  116. }
  117. //-----------------------------------------------------------------------------
  118. // Implementation of IPhysics
  119. //-----------------------------------------------------------------------------
  120. IPhysicsEnvironment *CPhysicsInterface::CreateEnvironment( void )
  121. {
  122. IPhysicsEnvironment *pEnvironment = CreatePhysicsEnvironment();
  123. m_envList.AddToTail( pEnvironment );
  124. return pEnvironment;
  125. }
  126. void CPhysicsInterface::DestroyEnvironment( IPhysicsEnvironment *pEnvironment )
  127. {
  128. m_envList.FindAndRemove( pEnvironment );
  129. delete pEnvironment;
  130. }
  131. IPhysicsEnvironment *CPhysicsInterface::GetActiveEnvironmentByIndex( int index )
  132. {
  133. if ( index < 0 || index >= m_envList.Count() )
  134. return NULL;
  135. return m_envList[index];
  136. }
  137. IPhysicsObjectPairHash *CPhysicsInterface::CreateObjectPairHash()
  138. {
  139. return ::CreateObjectPairHash();
  140. }
  141. void CPhysicsInterface::DestroyObjectPairHash( IPhysicsObjectPairHash *pHash )
  142. {
  143. delete pHash;
  144. }
  145. // holds a cache of these by id.
  146. // NOTE: This is stuffed into vphysics.dll as a sneaky way of sharing the memory between
  147. // client and server in single player. So you can't have different client/server rules.
  148. IPhysicsCollisionSet *CPhysicsInterface::FindOrCreateCollisionSet( unsigned int id, int maxElementCount )
  149. {
  150. if ( !m_pCollisionSetHash )
  151. {
  152. m_pCollisionSetHash = new IVP_VHash_Store(256);
  153. }
  154. Assert( id != 0 );
  155. Assert( maxElementCount <= 32 );
  156. if ( maxElementCount > 32 )
  157. return NULL;
  158. IPhysicsCollisionSet *pSet = FindCollisionSet( id );
  159. if ( pSet )
  160. return pSet;
  161. int index = m_collisionSets.AddToTail();
  162. m_pCollisionSetHash->add_elem( (void *)id, (void *)(index+1) );
  163. return &m_collisionSets[index];
  164. }
  165. IPhysicsCollisionSet *CPhysicsInterface::FindCollisionSet( unsigned int id )
  166. {
  167. if ( m_pCollisionSetHash )
  168. {
  169. int index = (int)m_pCollisionSetHash->find_elem( (void *)id );
  170. if ( index > 0 )
  171. {
  172. Assert( index <= m_collisionSets.Count() );
  173. if ( index <= m_collisionSets.Count() )
  174. {
  175. return &m_collisionSets[index-1];
  176. }
  177. }
  178. }
  179. return NULL;
  180. }
  181. void CPhysicsInterface::DestroyAllCollisionSets()
  182. {
  183. m_collisionSets.Purge();
  184. delete m_pCollisionSetHash;
  185. m_pCollisionSetHash = NULL;
  186. }
  187. // In release build, each of these libraries must contain a symbol that indicates it is also a release build
  188. // You MUST disable this in order to run a release vphysics.dll with a debug library.
  189. // This should not usually be necessary
  190. #if !defined(_DEBUG) && defined(_WIN32)
  191. extern int ivp_physics_lib_is_a_release_build;
  192. extern int ivp_compactbuilder_lib_is_a_release_build;
  193. extern int hk_base_lib_is_a_release_build;
  194. extern int hk_math_lib_is_a_release_build;
  195. extern int havana_constraints_lib_is_a_release_build;
  196. void DebugTestFunction()
  197. {
  198. ivp_physics_lib_is_a_release_build = 0;
  199. ivp_compactbuilder_lib_is_a_release_build = 0;
  200. hk_base_lib_is_a_release_build = 0;
  201. hk_math_lib_is_a_release_build = 0;
  202. havana_constraints_lib_is_a_release_build = 0;
  203. }
  204. #endif