Counter Strike : Global Offensive Source Code
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.

684 lines
24 KiB

  1. //========= Copyright � 1996-2006, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Provides structures and classes necessary to simulate a portal.
  4. //
  5. // $NoKeywords: $
  6. //=====================================================================================//
  7. #ifndef PORTALSIMULATION_H
  8. #define PORTALSIMULATION_H
  9. #ifdef _WIN32
  10. #pragma once
  11. #endif
  12. #include "mathlib/polyhedron.h"
  13. #include "const.h"
  14. #include "tier1/utlmap.h"
  15. #include "tier1/utlvector.h"
  16. #define PORTAL_SIMULATORS_EMBED_GUID //define this to embed a unique integer with each portal simulator for debugging purposes
  17. struct PropPolyhedronGroup_t //each static prop is made up of a group of polyhedrons, these help us pull those groups from an array
  18. {
  19. int iStartIndex;
  20. int iNumPolyhedrons;
  21. };
  22. enum PortalSimulationEntityFlags_t
  23. {
  24. PSEF_OWNS_ENTITY = (1 << 0), //this environment is responsible for the entity's physics objects
  25. PSEF_OWNS_PHYSICS = (1 << 1),
  26. PSEF_IS_IN_PORTAL_HOLE = (1 << 2), //updated per-phyframe
  27. PSEF_CLONES_ENTITY_FROM_MAIN = (1 << 3), //entity is close enough to the portal to affect objects intersecting the portal
  28. PSEF_CLONES_ENTITY_ACROSS_PORTAL_FROM_MAIN = (1 << 4), //the entity is not "owned" by the portal, but creates a physics clone across the portal anyway
  29. //PSEF_HAS_LINKED_CLONE = (1 << 1), //this environment has a clone of the entity which is transformed from its linked portal
  30. };
  31. enum PS_PhysicsObjectSourceType_t
  32. {
  33. PSPOST_LOCAL_BRUSHES,
  34. PSPOST_REMOTE_BRUSHES,
  35. PSPOST_LOCAL_STATICPROPS,
  36. PSPOST_REMOTE_STATICPROPS,
  37. PSPOST_HOLYWALL_TUBE,
  38. PSPOST_LOCAL_DISPLACEMENT,
  39. };
  40. enum RayInPortalHoleResult_t
  41. {
  42. RIPHR_NOT_TOUCHING_HOLE = 0,
  43. RIPHR_TOUCHING_HOLE_NOT_WALL, //only the hole
  44. RIPHR_TOUCHING_HOLE_AND_WALL, //both hole and surrounding wall
  45. };
  46. struct PortalTransformAsAngledPosition_t //a matrix transformation from this portal to the linked portal, stored as vector and angle transforms
  47. {
  48. Vector ptOriginTransform;
  49. QAngle qAngleTransform;
  50. Vector ptShrinkAlignedOrigin; //when there's a discrepancy between visual surface and collision surface, this is adjusted to compensate in traces
  51. };
  52. inline bool LessFunc_Integer( const int &a, const int &b ) { return a < b; };
  53. class CPortalSimulatorEventCallbacks //sends out notifications of events to game specific code
  54. {
  55. public:
  56. virtual void PortalSimulator_TookOwnershipOfEntity( CBaseEntity *pEntity ) { };
  57. virtual void PortalSimulator_ReleasedOwnershipOfEntity( CBaseEntity *pEntity ) { };
  58. virtual void PortalSimulator_TookPhysicsOwnershipOfEntity( CBaseEntity *pEntity ) { };
  59. virtual void PortalSimulator_ReleasedPhysicsOwnershipOfEntity( CBaseEntity *pEntity ) { };
  60. };
  61. //====================================================================================
  62. // To any coder trying to understand the following nested structures....
  63. //
  64. // You may be wondering... why? wtf?
  65. //
  66. // The answer. The previous incarnation of server side portal simulation suffered
  67. // terribly from evolving variables with increasingly cryptic names with no clear
  68. // definition of what part of the system the variable was involved with.
  69. //
  70. // It's my hope that a nested structure with clear boundaries will eliminate that
  71. // horrible, awful, nasty, frustrating confusion. (It was really really bad). This
  72. // system has the added benefit of pseudo-forcing a naming structure.
  73. //
  74. // Lastly, if it all roots in one struct, we can const reference it out to allow
  75. // easy reads without writes
  76. //
  77. // It's broken out like this to solve a few problems....
  78. // 1. It cleans up intellisense when you don't actually define a structure
  79. // within a structure.
  80. // 2. Shorter typenames when you want to have a pointer/reference deep within
  81. // the nested structure.
  82. // 3. Needed at least one level removed from CPortalSimulator so
  83. // pointers/references could be made while the primary instance of the
  84. // data was private/protected.
  85. //
  86. // It may be slightly difficult to understand in it's broken out structure, but
  87. // intellisense brings all the data together in a very cohesive manner for
  88. // working with.
  89. //====================================================================================
  90. struct PS_PlacementData_t //stuff useful for geometric operations
  91. {
  92. Vector ptCenter;
  93. QAngle qAngles;
  94. Vector vForward;
  95. Vector vUp;
  96. Vector vRight;
  97. float fHalfWidth, fHalfHeight;
  98. VPlane PortalPlane;
  99. VMatrix matThisToLinked;
  100. VMatrix matLinkedToThis;
  101. PortalTransformAsAngledPosition_t ptaap_ThisToLinked;
  102. PortalTransformAsAngledPosition_t ptaap_LinkedToThis;
  103. CPhysCollide *pHoleShapeCollideable; //used to test if a collideable is in the hole, should NOT be collided against in general
  104. CPhysCollide *pInvHoleShapeCollideable; //A very thin, but wide wall with the portal hole cut out in the middle. Used to test if traces are fully encapsulated in a portal hole
  105. CPhysCollide *pAABBAngleTransformCollideable; //used for player traces so we can slide into the portal gracefully if there's an angular difference such that our transformed AABB is in solid until the center reaches the plane
  106. Vector vecCurAABBMins;
  107. Vector vecCurAABBMaxs;
  108. Vector vCollisionCloneExtents; //how far in each direction (in front of the portal) we clone collision data from the real world.
  109. EHANDLE hPortalPlacementParent;
  110. bool bParentIsVPhysicsSolidBrush; //VPhysics solid brushes present an interesting collision challenge where their visuals are separated 0.5 inches from their collision
  111. PS_PlacementData_t( void )
  112. {
  113. memset( this, 0, sizeof( PS_PlacementData_t ) );
  114. ptCenter.Invalidate();
  115. }
  116. };
  117. struct PS_SD_Static_CarvedBrushCollection_t
  118. {
  119. CUtlVector<CPolyhedron *> Polyhedrons; //the building blocks of more complex collision
  120. CPhysCollide *pCollideable;
  121. #ifndef CLIENT_DLL
  122. IPhysicsObject *pPhysicsObject;
  123. PS_SD_Static_CarvedBrushCollection_t() : pCollideable(NULL), pPhysicsObject(NULL) {};
  124. #else
  125. PS_SD_Static_CarvedBrushCollection_t() : pCollideable(NULL) {};
  126. #endif
  127. };
  128. struct PS_SD_Static_BrushSet_t : public PS_SD_Static_CarvedBrushCollection_t
  129. {
  130. PS_SD_Static_BrushSet_t() : iSolidMask(0) {};
  131. int iSolidMask;
  132. };
  133. struct PS_SD_Static_World_Brushes_t
  134. {
  135. PS_SD_Static_BrushSet_t BrushSets[4];
  136. PS_SD_Static_World_Brushes_t()
  137. {
  138. BrushSets[0].iSolidMask = MASK_SOLID_BRUSHONLY & ~CONTENTS_GRATE;
  139. BrushSets[1].iSolidMask = CONTENTS_GRATE;
  140. BrushSets[2].iSolidMask = CONTENTS_PLAYERCLIP;
  141. BrushSets[3].iSolidMask = CONTENTS_MONSTERCLIP;
  142. }
  143. };
  144. struct PS_SD_Static_World_Displacements_t
  145. {
  146. CPhysCollide *pCollideable;
  147. #ifndef CLIENT_DLL
  148. IPhysicsObject *pPhysicsObject;
  149. PS_SD_Static_World_Displacements_t() : pCollideable(NULL), pPhysicsObject(NULL) {};
  150. #else
  151. PS_SD_Static_World_Displacements_t() : pCollideable(NULL) {};
  152. #endif
  153. };
  154. struct PS_SD_Static_World_StaticProps_ClippedProp_t
  155. {
  156. PropPolyhedronGroup_t PolyhedronGroup;
  157. CPhysCollide * pCollide;
  158. #ifndef CLIENT_DLL
  159. IPhysicsObject * pPhysicsObject;
  160. #endif
  161. IHandleEntity * pSourceProp;
  162. int iTraceContents;
  163. short iTraceSurfaceProps;
  164. static CBaseEntity * pTraceEntity;
  165. static const char * szTraceSurfaceName; //same for all static props, here just for easy reference
  166. static const int iTraceSurfaceFlags; //same for all static props, here just for easy reference
  167. };
  168. struct PS_SD_Static_World_StaticProps_t
  169. {
  170. CUtlVector<CPolyhedron *> Polyhedrons; //the building blocks of more complex collision
  171. CUtlVector<PS_SD_Static_World_StaticProps_ClippedProp_t> ClippedRepresentations;
  172. bool bCollisionExists; //the shortcut to know if collideables exist for each prop
  173. #ifndef CLIENT_DLL
  174. bool bPhysicsExists; //the shortcut to know if physics obects exist for each prop
  175. #endif
  176. PS_SD_Static_World_StaticProps_t( void ) : bCollisionExists( false )
  177. #ifndef CLIENT_DLL
  178. , bPhysicsExists( false )
  179. #endif
  180. { };
  181. };
  182. struct PS_SD_Static_World_t //stuff in front of the portal
  183. {
  184. PS_SD_Static_World_Brushes_t Brushes;
  185. PS_SD_Static_World_Displacements_t Displacements;
  186. PS_SD_Static_World_StaticProps_t StaticProps;
  187. };
  188. struct PS_SD_Static_Wall_Local_Tube_t //a minimal tube, an object must fit inside this to be eligible for portaling
  189. {
  190. CUtlVector<CPolyhedron *> Polyhedrons; //the building blocks of more complex collision
  191. CPhysCollide *pCollideable;
  192. #ifndef CLIENT_DLL
  193. IPhysicsObject *pPhysicsObject;
  194. PS_SD_Static_Wall_Local_Tube_t() : pCollideable(NULL), pPhysicsObject(NULL) {};
  195. #else
  196. PS_SD_Static_Wall_Local_Tube_t() : pCollideable(NULL) {};
  197. #endif
  198. };
  199. struct PS_SD_Static_Wall_Local_Brushes_t
  200. {
  201. PS_SD_Static_BrushSet_t BrushSets[4];
  202. #if defined( GAME_DLL )
  203. PS_SD_Static_CarvedBrushCollection_t Carved_func_clip_vphysics; //physics only, no tracing
  204. #endif
  205. PS_SD_Static_Wall_Local_Brushes_t()
  206. {
  207. BrushSets[0].iSolidMask = MASK_SOLID_BRUSHONLY & ~CONTENTS_GRATE;
  208. BrushSets[1].iSolidMask = CONTENTS_GRATE;
  209. BrushSets[2].iSolidMask = CONTENTS_PLAYERCLIP;
  210. BrushSets[3].iSolidMask = CONTENTS_MONSTERCLIP;
  211. }
  212. };
  213. struct PS_SD_Static_Wall_Local_t //things in the wall that are completely independant of having a linked portal
  214. {
  215. PS_SD_Static_Wall_Local_Tube_t Tube;
  216. PS_SD_Static_Wall_Local_Brushes_t Brushes;
  217. };
  218. struct PS_SD_Static_Wall_RemoteTransformedToLocal_Brushes_t
  219. {
  220. IPhysicsObject *pPhysicsObjects[ARRAYSIZE(((PS_SD_Static_World_Brushes_t *)NULL)->BrushSets)];
  221. PS_SD_Static_Wall_RemoteTransformedToLocal_Brushes_t()
  222. {
  223. for( int i = 0; i != ARRAYSIZE(pPhysicsObjects); ++i )
  224. {
  225. pPhysicsObjects[i] = NULL;
  226. }
  227. };
  228. };
  229. struct PS_SD_Static_Wall_RemoteTransformedToLocal_StaticProps_t
  230. {
  231. CUtlVector<IPhysicsObject *> PhysicsObjects;
  232. };
  233. struct PS_SD_Static_Wall_RemoteTransformedToLocal_t //things taken from the linked portal's "World" collision and transformed into local space
  234. {
  235. PS_SD_Static_Wall_RemoteTransformedToLocal_Brushes_t Brushes;
  236. PS_SD_Static_Wall_RemoteTransformedToLocal_StaticProps_t StaticProps;
  237. };
  238. struct PS_SD_Static_Wall_t //stuff behind the portal
  239. {
  240. PS_SD_Static_Wall_Local_t Local;
  241. #ifndef CLIENT_DLL
  242. PS_SD_Static_Wall_RemoteTransformedToLocal_t RemoteTransformedToLocal;
  243. #endif
  244. };
  245. struct PS_SD_Static_SurfaceProperties_t //surface properties to pretend every collideable here is using
  246. {
  247. int contents;
  248. csurface_t surface;
  249. CBaseEntity *pEntity;
  250. };
  251. struct PS_SD_Static_t //stuff that doesn't move around
  252. {
  253. PS_SD_Static_World_t World;
  254. PS_SD_Static_Wall_t Wall;
  255. PS_SD_Static_SurfaceProperties_t SurfaceProperties;
  256. };
  257. class CPhysicsShadowClone;
  258. struct PS_SD_Dynamic_PhysicsShadowClones_t
  259. {
  260. CUtlVector<CBaseEntity *> ShouldCloneFromMain; //a list of entities that should be cloned from main if physics simulation is enabled
  261. //in single-environment mode, this helps us track who should collide with who
  262. CUtlVector<CPhysicsShadowClone *> FromLinkedPortal;
  263. CUtlVector<CBaseEntity *> ShouldCloneToRemotePortal; //non-owned entities that we should push a clone for
  264. };
  265. struct PS_SD_Dynamic_CarvedEntities_CarvedEntity_t
  266. {
  267. PropPolyhedronGroup_t UncarvedPolyhedronGroup;
  268. PropPolyhedronGroup_t CarvedPolyhedronGroup;
  269. CPhysCollide * pCollide;
  270. #ifndef CLIENT_DLL
  271. IPhysicsObject * pPhysicsObject;
  272. #endif
  273. CBaseEntity * pSourceEntity;
  274. };
  275. struct PS_SD_Dynamic_CarvedEntities_t
  276. {
  277. bool bCollisionExists; //the shortcut to know if collideables exist for each entity
  278. #ifndef CLIENT_DLL
  279. bool bPhysicsExists; //the shortcut to know if physics obects exist for each entity
  280. #endif
  281. CUtlVector<CPolyhedron *> Polyhedrons;
  282. CUtlVector<PS_SD_Dynamic_CarvedEntities_CarvedEntity_t> CarvedRepresentations;
  283. PS_SD_Dynamic_CarvedEntities_t( void ) : bCollisionExists( false )
  284. #ifndef CLIENT_DLL
  285. , bPhysicsExists( false )
  286. #endif
  287. { };
  288. };
  289. struct PS_SD_Dynamic_t //stuff that moves around
  290. {
  291. unsigned int EntFlags[MAX_EDICTS]; //flags maintained for every entity in the world based on its index
  292. CUtlVector<CBaseEntity *> OwnedEntities;
  293. #ifndef CLIENT_DLL
  294. PS_SD_Dynamic_PhysicsShadowClones_t ShadowClones;
  295. #endif
  296. uint32 HasCarvedVersionOfEntity[(MAX_EDICTS + (sizeof(uint32) * 8) - 1)/(sizeof(uint32) * 8)]; //a bit for every possible ent index rounded up to the next integer, not stored as a PortalSimulationEntityFlags_t because those are all serverside at the moment
  297. PS_SD_Dynamic_CarvedEntities_t CarvedEntities;
  298. PS_SD_Dynamic_t()
  299. {
  300. memset( EntFlags, 0, sizeof( EntFlags ) );
  301. memset( HasCarvedVersionOfEntity, 0, sizeof( HasCarvedVersionOfEntity ) );
  302. }
  303. };
  304. class CPortalSimulator;
  305. class CPSCollisionEntity : public CBaseEntity
  306. {
  307. DECLARE_CLASS( CPSCollisionEntity, CBaseEntity );
  308. #ifdef GAME_DLL
  309. DECLARE_SERVERCLASS();
  310. #else
  311. DECLARE_CLIENTCLASS();
  312. #endif
  313. #ifdef GAME_DLL
  314. private:
  315. CPortalSimulator *m_pOwningSimulator;
  316. #endif
  317. public:
  318. CPSCollisionEntity( void );
  319. virtual ~CPSCollisionEntity( void );
  320. virtual void Spawn( void );
  321. virtual void Activate( void );
  322. virtual int ObjectCaps( void );
  323. virtual int VPhysicsGetObjectList( IPhysicsObject **pList, int listMax );
  324. virtual void UpdateOnRemove( void );
  325. virtual bool ShouldCollide( int collisionGroup, int contentsMask ) const;
  326. #ifdef GAME_DLL
  327. virtual void VPhysicsCollision( int index, gamevcollisionevent_t *pEvent ) {}
  328. virtual void VPhysicsFriction( IPhysicsObject *pObject, float energy, int surfaceProps, int surfacePropsHit ) {}
  329. virtual int UpdateTransmitState( void ) { return SetTransmitState( FL_EDICT_ALWAYS ); }
  330. #else
  331. virtual void UpdatePartitionListEntry(); //make this trigger touchable on the client
  332. #endif
  333. static bool IsPortalSimulatorCollisionEntity( const CBaseEntity *pEntity );
  334. friend class CPortalSimulator;
  335. };
  336. struct PS_SimulationData_t //compartmentalized data for coherent management
  337. {
  338. DECLARE_CLASS_NOBASE( PS_SimulationData_t );
  339. DECLARE_EMBEDDED_NETWORKVAR();
  340. PS_SD_Static_t Static;
  341. PS_SD_Dynamic_t Dynamic;
  342. #ifndef CLIENT_DLL
  343. IPhysicsEnvironment *pPhysicsEnvironment;
  344. CNetworkHandle( CPSCollisionEntity, hCollisionEntity );
  345. PS_SimulationData_t() : pPhysicsEnvironment(NULL){ hCollisionEntity = NULL; }
  346. #else
  347. typedef CHandle<CPSCollisionEntity> CollisionEntityHandle_t;
  348. CollisionEntityHandle_t hCollisionEntity; //the entity we'll be tying physics objects to for collision
  349. PS_SimulationData_t() : hCollisionEntity(NULL) {}
  350. #endif
  351. };
  352. struct PS_DebuggingData_t
  353. {
  354. Color overlayColor; //a good base color to use when showing overlays
  355. };
  356. #ifdef GAME_DLL
  357. EXTERN_SEND_TABLE( DT_PS_SimulationData_t );
  358. #else
  359. EXTERN_RECV_TABLE( DT_PS_SimulationData_t );
  360. #endif
  361. struct PS_InternalData_t
  362. {
  363. DECLARE_CLASS_NOBASE( PS_InternalData_t );
  364. DECLARE_EMBEDDED_NETWORKVAR();
  365. PS_PlacementData_t Placement;
  366. #ifdef GAME_DLL
  367. CNetworkVarEmbedded( PS_SimulationData_t, Simulation);
  368. #else
  369. PS_SimulationData_t Simulation;
  370. #endif
  371. PS_DebuggingData_t Debugging;
  372. };
  373. #ifdef GAME_DLL
  374. EXTERN_SEND_TABLE( DT_PS_InternalData_t );
  375. #else
  376. EXTERN_RECV_TABLE( DT_PS_InternalData_t );
  377. #endif
  378. class CPortalSimulator
  379. {
  380. public:
  381. DECLARE_CLASS_NOBASE( CPortalSimulator );
  382. DECLARE_EMBEDDED_NETWORKVAR();
  383. public:
  384. CPortalSimulator( void );
  385. ~CPortalSimulator( void );
  386. void SetSize( float fHalfWidth, float fHalfHeight );
  387. void MoveTo( const Vector &ptCenter, const QAngle &angles );
  388. void ClearEverything( void );
  389. void AttachTo( CPortalSimulator *pLinkedPortalSimulator );
  390. void DetachFromLinked( void ); //detach portals to sever the connection, saves work when planning on moving both portals
  391. CPortalSimulator *GetLinkedPortalSimulator( void ) const;
  392. void SetPortalSimulatorCallbacks( CPortalSimulatorEventCallbacks *pCallbacks );
  393. bool IsReadyToSimulate( void ) const; //is active and linked to another portal
  394. void SetCollisionGenerationEnabled( bool bEnabled ); //enable/disable collision generation for the hole in the wall, needed for proper vphysics simulation
  395. bool IsCollisionGenerationEnabled( void ) const;
  396. #ifndef CLIENT_DLL
  397. void SetVPhysicsSimulationEnabled( bool bEnabled ); //enable/disable vphysics simulation. Will automatically update the linked portal to be the same
  398. bool IsSimulatingVPhysics( void ) const; //this portal is setup to handle any physically simulated object, false means the portal is handling player movement only
  399. #endif
  400. bool EntityIsInPortalHole( CBaseEntity *pEntity ) const; //true if the entity is within the portal cutout bounds and crossing the plane. Not just *near* the portal
  401. bool EntityHitBoxExtentIsInPortalHole( CBaseAnimating *pBaseAnimating, bool bUseCollisionAABB ) const; //true if the entity is within the portal cutout bounds and crossing the plane. Not just *near* the portal
  402. void RemoveEntityFromPortalHole( CBaseEntity *pEntity ); //if the entity is in the portal hole, this forcibly moves it out by any means possible
  403. RayInPortalHoleResult_t IsRayInPortalHole( const Ray_t &ray ) const; //traces a ray against the same detector for EntityIsInPortalHole(), bias is towards false positives
  404. #ifndef CLIENT_DLL
  405. int GetMoveableOwnedEntities( CBaseEntity **pEntsOut, int iEntOutLimit ); //gets owned entities that aren't either world or static props. Excludes fake portal ents such as physics clones
  406. static CPortalSimulator *GetSimulatorThatCreatedPhysicsObject( const IPhysicsObject *pObject, PS_PhysicsObjectSourceType_t *pOut_SourceType = NULL );
  407. static void Pre_UTIL_Remove( CBaseEntity *pEntity );
  408. static void Post_UTIL_Remove( CBaseEntity *pEntity );
  409. //void TeleportEntityToLinkedPortal( CBaseEntity *pEntity );
  410. void StartCloningEntityFromMain( CBaseEntity *pEntity );
  411. void StopCloningEntityFromMain( CBaseEntity *pEntity );
  412. //these 2 only apply for entities that this simulator will not take ownership of
  413. void StartCloningEntityAcrossPortals( CBaseEntity *pEntity );
  414. void StopCloningEntityAcrossPortals( CBaseEntity *pEntity );
  415. bool OwnsPhysicsForEntity( const CBaseEntity *pEntity ) const;
  416. bool CreatedPhysicsObject( const IPhysicsObject *pObject, PS_PhysicsObjectSourceType_t *pOut_SourceType = NULL ) const; //true if the physics object was generated by this portal simulator
  417. static void PrePhysFrame( void );
  418. static void PostPhysFrame( void );
  419. #endif //#ifndef CLIENT_DLL
  420. //these three really should be made internal and the public interface changed to a "watch this entity" setup
  421. void TakeOwnershipOfEntity( CBaseEntity *pEntity ); //general ownership, not necessarily physics ownership
  422. void ReleaseOwnershipOfEntity( CBaseEntity *pEntity, bool bMovingToLinkedSimulator = false ); //if bMovingToLinkedSimulator is true, the code skips some steps that are going to be repeated when the entity is added to the other simulator
  423. void ReleaseAllEntityOwnership( void ); //go back to not owning any entities
  424. bool OwnsEntity( const CBaseEntity *pEntity ) const;
  425. static CPortalSimulator *GetSimulatorThatOwnsEntity( const CBaseEntity *pEntity ); //fairly cheap to call
  426. bool IsEntityCarvedByPortal( int iEntIndex ) const;
  427. inline bool IsEntityCarvedByPortal( CBaseEntity *pEntity ) const { return IsEntityCarvedByPortal( pEntity->entindex() ); };
  428. CPhysCollide * GetCollideForCarvedEntity( CBaseEntity *pEntity ) const;
  429. #ifdef PORTAL_SIMULATORS_EMBED_GUID
  430. int GetPortalSimulatorGUID( void ) const { return m_iPortalSimulatorGUID; };
  431. #endif
  432. void SetCarvedParent( CBaseEntity *pPortalPlacementParent ); //sometimes you have to carve up a func brush the portal was placed on
  433. void DebugCollisionOverlay( bool noDepthTest, float flDuration ) const;
  434. protected:
  435. void MovedOrResized( const Vector &ptCenter, const QAngle &qAngles, float fHalfWidth, float fHalfHeight ); //MoveTo() and SetSize() funnel here to create geometry
  436. void AddCarvedEntity( CBaseEntity *pEntity ); //finds/adds an entity that we should carve with the portal hole
  437. void ReleaseCarvedEntity( CBaseEntity *pEntity ); //finds and removes a carved entity
  438. bool m_bLocalDataIsReady; //this side of the portal is properly setup, no guarantees as to linkage to another portal
  439. bool m_bSimulateVPhysics;
  440. bool m_bGenerateCollision;
  441. bool m_bSharedCollisionConfiguration; //when portals are in certain configurations, they need to cross-clip and share some collision data and things get nasty. For the love of all that is holy, pray that this is false.
  442. CPortalSimulator *m_pLinkedPortal;
  443. bool m_bInCrossLinkedFunction; //A flag to mark that we're already in a linked function and that the linked portal shouldn't call our side
  444. CPortalSimulatorEventCallbacks *m_pCallbacks;
  445. #ifdef PORTAL_SIMULATORS_EMBED_GUID
  446. int m_iPortalSimulatorGUID;
  447. #endif
  448. struct
  449. {
  450. bool bPolyhedronsGenerated;
  451. bool bLocalCollisionGenerated;
  452. bool bLinkedCollisionGenerated;
  453. bool bLocalPhysicsGenerated;
  454. bool bLinkedPhysicsGenerated;
  455. } m_CreationChecklist;
  456. friend class CPSCollisionEntity;
  457. #ifndef CLIENT_DLL //physics handled purely by server side
  458. void TakePhysicsOwnership( CBaseEntity *pEntity );
  459. void ReleasePhysicsOwnership( CBaseEntity *pEntity, bool bContinuePhysicsCloning = true, bool bMovingToLinkedSimulator = false );
  460. void CreateAllPhysics( void );
  461. void CreateMinimumPhysics( void ); //stuff needed by any part of physics simulations
  462. void CreateLocalPhysics( void );
  463. void CreateLinkedPhysics( void );
  464. void ClearAllPhysics( void );
  465. void ClearMinimumPhysics( void );
  466. void ClearLocalPhysics( void );
  467. void ClearLinkedPhysics( void );
  468. void ClearLinkedEntities( void ); //gets rid of transformed shadow clones
  469. #endif
  470. void CreateAllCollision( void );
  471. void CreateLocalCollision( void );
  472. void CreateLinkedCollision( void );
  473. void ClearAllCollision( void );
  474. void ClearLinkedCollision( void );
  475. void ClearLocalCollision( void );
  476. void CreatePolyhedrons( void ); //carves up the world around the portal's position into sets of polyhedrons
  477. void ClearPolyhedrons( void );
  478. void CreateTubePolyhedrons( void ); //Sometimes we have to shift the portal tube helper collideable around a bit
  479. void UpdateLinkMatrix( void );
  480. void MarkAsOwned( CBaseEntity *pEntity );
  481. void MarkAsReleased( CBaseEntity *pEntity );
  482. #ifdef GAME_DLL
  483. CNetworkVarEmbedded( PS_InternalData_t, m_InternalData );
  484. #else
  485. PS_InternalData_t m_InternalData;
  486. #endif
  487. public:
  488. inline const PS_InternalData_t &GetInternalData() const;
  489. PS_DebuggingData_t &EditDebuggingData();
  490. friend class CPS_AutoGameSys_EntityListener;
  491. };
  492. #ifdef GAME_DLL
  493. EXTERN_SEND_TABLE( DT_PortalSimulator );
  494. #else
  495. EXTERN_RECV_TABLE( DT_PortalSimulator );
  496. #endif
  497. extern CUtlVector<CPortalSimulator *> const &g_PortalSimulators;
  498. inline bool CPortalSimulator::OwnsEntity( const CBaseEntity *pEntity ) const
  499. {
  500. return ((m_InternalData.Simulation.Dynamic.EntFlags[pEntity->entindex()] & PSEF_OWNS_ENTITY) != 0);
  501. }
  502. #ifndef CLIENT_DLL
  503. inline bool CPortalSimulator::OwnsPhysicsForEntity( const CBaseEntity *pEntity ) const
  504. {
  505. return ((m_InternalData.Simulation.Dynamic.EntFlags[pEntity->entindex()] & PSEF_OWNS_PHYSICS) != 0);
  506. }
  507. #endif
  508. inline bool CPortalSimulator::IsReadyToSimulate( void ) const
  509. {
  510. return m_bLocalDataIsReady && m_pLinkedPortal && m_pLinkedPortal->m_bLocalDataIsReady;
  511. }
  512. #ifndef CLIENT_DLL
  513. inline bool CPortalSimulator::IsSimulatingVPhysics( void ) const
  514. {
  515. return m_bSimulateVPhysics && m_bGenerateCollision;
  516. }
  517. #endif
  518. inline bool CPortalSimulator::IsCollisionGenerationEnabled( void ) const
  519. {
  520. return m_bGenerateCollision;
  521. }
  522. inline CPortalSimulator *CPortalSimulator::GetLinkedPortalSimulator( void ) const
  523. {
  524. return m_pLinkedPortal;
  525. }
  526. inline const PS_InternalData_t &CPortalSimulator::GetInternalData() const
  527. {
  528. return m_InternalData;
  529. }
  530. inline PS_DebuggingData_t &CPortalSimulator::EditDebuggingData()
  531. {
  532. return m_InternalData.Debugging;
  533. }
  534. #if defined ( GAME_DLL )
  535. struct VPhysicsClipEntry_t
  536. {
  537. EHANDLE hEnt;
  538. Vector vAABBMins;
  539. Vector vAABBMaxs;
  540. };
  541. CUtlVector<VPhysicsClipEntry_t>& GetVPhysicsClipList ( void );
  542. #endif // GAME_DLL
  543. #endif //#ifndef PORTALSIMULATION_H