BVB Source Codes

CRYENGINE Show DeferredCollisionEvent.cpp Source code

Return Download CRYENGINE: download DeferredCollisionEvent.cpp Source code - Download CRYENGINE Source code - Type:.cpp
  1. // Copyright 2001-2016 Crytek GmbH / Crytek Group. All rights reserved.
  2.  
  3. // -------------------------------------------------------------------------
  4. //  File name:   DeferredCollisionEvent.h
  5. //  Version:     v1.00
  6. //  Created:     12/08/2010 by Christopher Bolte
  7. //  Compilers:   Visual Studio.NET
  8. // -------------------------------------------------------------------------
  9. //  History:
  10. ////////////////////////////////////////////////////////////////////////////
  11.  
  12. #include "StdAfx.h"
  13. #include "DeferredCollisionEvent.h"
  14. #include <CryThreading/IJobManager_JobDelegator.h>
  15. #include <CryEntitySystem/IEntitySystem.h>
  16.  
  17. void CDeferredPhysicsEventManager::DispatchDeferredEvent(IDeferredPhysicsEvent* pEvent)
  18. {
  19.         assert(pEvent);
  20.         // execute immediately if we don't use deferred physics events
  21.         if (GetCVars()->e_DeferredPhysicsEvents == 0 || gEnv->IsEditor() || gEnv->IsDedicated())
  22.         {
  23.                 pEvent->Execute();
  24.                 return;
  25.         }
  26.  
  27.         // Push onto the job queue
  28.         pEvent->ExecuteAsJob();
  29. }
  30.  
  31. void ApplyCollisionImpulse(EventPhysCollision* pCollision)
  32. {
  33.         if (pCollision->normImpulse && pCollision->pEntity[1] &&
  34.             pCollision->pEntity[0] && pCollision->pEntity[0]->GetType() == PE_PARTICLE &&
  35.             pCollision->pEntity[0]->GetForeignData(pCollision->pEntity[0]->GetiForeignData()))  // no foreign data mean it's likely scheduled for deletion
  36.         {
  37.                 pe_action_impulse ai;
  38.                 ai.point = pCollision->pt;
  39.                 ai.partid = pCollision->partid[1];
  40.                 ai.impulse = (pCollision->vloc[0] - pCollision->vloc[1]) * pCollision->normImpulse;
  41.                 pCollision->pEntity[1]->Action(&ai);
  42.         }
  43. }
  44.  
  45. int CDeferredPhysicsEventManager::HandleEvent(const EventPhys* pEvent, IDeferredPhysicsEventManager::CreateEventFunc pCreateFunc, IDeferredPhysicsEvent::DeferredEventType type)
  46. {
  47.         EventPhysCollision* pCollision = (EventPhysCollision*)pEvent;
  48.         assert(pCollision);
  49.  
  50.         if (pCollision->deferredState == EPC_DEFERRED_FINISHED)
  51.         {
  52.                 ApplyCollisionImpulse(pCollision);
  53.                 return pCollision->deferredResult;
  54.         }
  55.  
  56.         // == create new deferred event object, and do some housekeeping(ensuring entities not deleted, remebering event for cleanup) == //
  57.         IDeferredPhysicsEvent* pDeferredEvent = pCreateFunc(pEvent);
  58.  
  59.         // == start executing == //
  60.         pDeferredEvent->Start();
  61.  
  62.         // == check if we really needed to deferred this event(early outs, not deferred code paths) == //
  63.         if (GetCVars()->e_DeferredPhysicsEvents == 0 || pDeferredEvent->HasFinished())
  64.         {
  65.                 int nResult = pDeferredEvent->Result((EventPhys*)pEvent);
  66.                 SAFE_DELETE(pDeferredEvent);
  67.                 ApplyCollisionImpulse(pCollision);
  68.                 return nResult;
  69.         }
  70.  
  71.         // make sure the referenced entities are not deleted when running async
  72.         if (pCollision->iForeignData[0] == PHYS_FOREIGN_ID_ENTITY)
  73.         {
  74.                 IEntity* pSrcEntity = (IEntity*)pCollision->pForeignData[0];
  75.                 if (pSrcEntity) pSrcEntity->IncKeepAliveCounter();
  76.         }
  77.  
  78.         if (pCollision->iForeignData[1] == PHYS_FOREIGN_ID_ENTITY)
  79.         {
  80.                 IEntity* pTrgEntity = (IEntity*)pCollision->pForeignData[1];
  81.                 if (pTrgEntity) pTrgEntity->IncKeepAliveCounter();
  82.         }
  83.  
  84.         if (pCollision->pEntity[0]) pCollision->pEntity[0]->AddRef();
  85.         if (pCollision->pEntity[1]) pCollision->pEntity[1]->AddRef();
  86.  
  87.         // == re-queue event for the next frame, to keep the physical entity alive == //
  88.         RegisterDeferredEvent(pDeferredEvent);
  89.  
  90.         return 0;
  91. }
  92.  
  93. void CDeferredPhysicsEventManager::RegisterDeferredEvent(IDeferredPhysicsEvent* pDeferredEvent)
  94. {
  95.         assert(pDeferredEvent);
  96.         m_activeDeferredEvents.push_back(pDeferredEvent);
  97. }
  98.  
  99. void CDeferredPhysicsEventManager::UnRegisterDeferredEvent(IDeferredPhysicsEvent* pDeferredEvent)
  100. {
  101.  
  102.         std::vector<IDeferredPhysicsEvent*>::iterator it = std::find(m_activeDeferredEvents.begin(), m_activeDeferredEvents.end(), pDeferredEvent);
  103.         if (it == m_activeDeferredEvents.end())
  104.                 return;
  105.  
  106.         // == remove from active list == //
  107.         m_activeDeferredEvents.erase(it);
  108.  
  109.         if (m_bEntitySystemReset)
  110.                 return;
  111.  
  112.         // == decrement keep alive counter on entity == //
  113.         EventPhysCollision* pCollision = (EventPhysCollision*)pDeferredEvent->PhysicsEvent();
  114.  
  115.         if (pCollision->iForeignData[0] == PHYS_FOREIGN_ID_ENTITY)
  116.         {
  117.                 IEntity* pSrcEntity = (IEntity*)pCollision->pForeignData[0];
  118.                 if (pSrcEntity)  pSrcEntity->DecKeepAliveCounter();
  119.         }
  120.  
  121.         if (pCollision->iForeignData[1] == PHYS_FOREIGN_ID_ENTITY)
  122.         {
  123.                 IEntity* pTrgEntity = (IEntity*)pCollision->pForeignData[1];
  124.                 if (pTrgEntity)  pTrgEntity->DecKeepAliveCounter();
  125.         }
  126.  
  127.         if (pCollision->pEntity[0]) pCollision->pEntity[0]->Release();
  128.         if (pCollision->pEntity[1]) pCollision->pEntity[1]->Release();
  129. }
  130.  
  131. void CDeferredPhysicsEventManager::ClearDeferredEvents()
  132. {
  133.         // move content of the active deferred events array to a tmp one to prevent problems with UnRegisterDeferredEvent called by destructors
  134.         std::vector<IDeferredPhysicsEvent*> tmp = m_activeDeferredEvents;
  135.         m_bEntitySystemReset = !gEnv->pEntitySystem || !gEnv->pEntitySystem->GetNumEntities();
  136.  
  137.         for (std::vector<IDeferredPhysicsEvent*>::iterator it = tmp.begin(); it != tmp.end(); ++it)
  138.         {
  139.                 (*it)->Sync();
  140.                 delete *it;
  141.         }
  142.         stl::free_container(m_activeDeferredEvents);
  143.         m_bEntitySystemReset = false;
  144. }
  145.  
  146. void CDeferredPhysicsEventManager::Update()
  147. {
  148.         std::vector<IDeferredPhysicsEvent*> tmp = m_activeDeferredEvents;
  149.  
  150.         for (std::vector<IDeferredPhysicsEvent*>::iterator it = tmp.begin(), end = tmp.end(); it != end; ++it)
  151.         {
  152.                 IDeferredPhysicsEvent* collisionEvent = *it;
  153.                 assert(collisionEvent);
  154.                 PREFAST_ASSUME(collisionEvent);
  155.                 EventPhysCollision* epc = (EventPhysCollision*) collisionEvent->PhysicsEvent();
  156.  
  157.                 if (collisionEvent->HasFinished() == false)
  158.                 {
  159.                         continue;
  160.                 }
  161.  
  162.                 epc->deferredResult = collisionEvent->Result();
  163.  
  164.                 if (epc->deferredState != EPC_DEFERRED_FINISHED)
  165.                 {
  166.                         epc->deferredState = EPC_DEFERRED_FINISHED;
  167.                         gEnv->pPhysicalWorld->AddDeferredEvent(EventPhysCollision::id, epc);
  168.                 }
  169.                 else
  170.                         SAFE_DELETE(collisionEvent);
  171.         }
  172. }
  173.  
  174. IDeferredPhysicsEvent* CDeferredPhysicsEventManager::GetLastCollisionEventForEntity(IPhysicalEntity* pPhysEnt)
  175. {
  176.         EventPhysCollision* pLastPhysEvent;
  177.         for (int i = m_activeDeferredEvents.size() - 1; i >= 0; i--)
  178.                 if ((pLastPhysEvent = (EventPhysCollision*)m_activeDeferredEvents[i]->PhysicsEvent()) && pLastPhysEvent->idval == EventPhysCollision::id && pLastPhysEvent->pEntity[0] == pPhysEnt)
  179.                         return m_activeDeferredEvents[i];
  180.         return 0;
  181. }
  182.  
downloadDeferredCollisionEvent.cpp Source code - Download CRYENGINE Source code
Related Source Codes/Software:
postal - 2017-06-11
reactide - Reactide is the first dedicated IDE for React web ... 2017-06-11
rkt - rkt is a pod-native container engine for Linux. It... 2017-06-11
uWebSockets - Tiny WebSockets https://for... 2017-06-11
realworld - TodoMVC for the RealWorld - Exemplary fullstack Me... 2017-06-11
CRYENGINE - CRYENGINE is a powerful real-time game development... 2017-06-11
goreplay - GoReplay is an open-source tool for capturing and ... 2017-06-10
pyenv - Simple Python version management 2017-06-10
redux-saga - An alternative side effect model for Redux apps ... 2017-06-10
angular-starter - 2017-06-10

 Back to top