BVB Source Codes

CRYENGINE Show VehicleDamageBehaviorSpawnDebris.cpp Source code

Return Download CRYENGINE: download VehicleDamageBehaviorSpawnDebris.cpp Source code - Download CRYENGINE Source code - Type:.cpp
  1. // Copyright 2001-2016 Crytek GmbH / Crytek Group. All rights reserved.
  2.  
  3. #include "StdAfx.h"
  4. #include "VehicleDamageBehaviorSpawnDebris.h"
  5.  
  6. #include "IVehicleSystem.h"
  7. #include "Vehicle.h"
  8. #include "VehiclePartAnimated.h"
  9.  
  10. //------------------------------------------------------------------------
  11. CVehicleDamageBehaviorSpawnDebris::CVehicleDamageBehaviorSpawnDebris()
  12.         : m_pVehicle(nullptr)
  13.         , m_pickableDebris(false)
  14. {
  15. }
  16.  
  17. //------------------------------------------------------------------------
  18. CVehicleDamageBehaviorSpawnDebris::~CVehicleDamageBehaviorSpawnDebris()
  19. {
  20.         Reset();
  21. }
  22.  
  23. //------------------------------------------------------------------------
  24. bool CVehicleDamageBehaviorSpawnDebris::Init(IVehicle* pVehicle, const CVehicleParams& table)
  25. {
  26.         m_pVehicle = pVehicle;
  27.  
  28.         if (CVehicleParams debrisParams = table.findChild("SpawnDebris"))
  29.         {
  30.                 debrisParams.getAttr("pickable", m_pickableDebris);
  31.                 m_particleEffect = debrisParams.getAttr("effect");
  32.         }
  33.  
  34.         int partCount = m_pVehicle->GetPartCount();
  35.         for (int k = 0; k < partCount; k++)
  36.         {
  37.                 IVehiclePart* pPart = m_pVehicle->GetPart(k);
  38.                 CRY_ASSERT(pPart);
  39.                 PREFAST_ASSUME(pPart);
  40.  
  41.                 if (CVehiclePartAnimated* pAnimPart = CAST_VEHICLEOBJECT(CVehiclePartAnimated, pPart))
  42.                 {
  43.                         ICharacterInstance* pCharInstance = pAnimPart->GetEntity()->GetCharacter(pAnimPart->GetSlot());
  44.                         if (pCharInstance)
  45.                         {
  46.                                 IDefaultSkeleton& rIDefaultSkeleton = pCharInstance->GetIDefaultSkeleton();
  47.                                 int jointCount = rIDefaultSkeleton.GetJointCount();
  48.                                 for (int jointId = 0; jointId < jointCount; jointId++)
  49.                                 {
  50.                                         int i = 1;
  51.                                         IStatObj* pStatObj = NULL;
  52.                                         const char* pJointName = rIDefaultSkeleton.GetJointNameByID(jointId);
  53.  
  54.                                         while (i < 25)
  55.                                         {
  56.                                                 pStatObj = pAnimPart->GetDestroyedGeometry(pJointName, i);
  57.                                                 if (pStatObj)
  58.                                                 {
  59.                                                         m_debris.resize(m_debris.size() + 1);
  60.                                                         SDebrisInfo& debrisInfo = m_debris.back();
  61.  
  62.                                                         debrisInfo.pAnimatedPart = pAnimPart;
  63.                                                         debrisInfo.jointId = jointId;
  64.                                                         debrisInfo.slot = -1;
  65.                                                         debrisInfo.index = i;
  66.                                                         debrisInfo.entityId = 0;
  67.                                                         debrisInfo.time = 0.0f;
  68.  
  69. #if ENABLE_VEHICLE_DEBUG
  70.                                                         if (VehicleCVars().v_debugdraw == eVDB_Parts)
  71.                                                         {
  72.                                                                 CryLog("VehicleDamageBehaviorSpawnDebris[%s]: adding debris part %s", m_pVehicle->GetEntity()->GetName(), pStatObj->GetGeoName());
  73.                                                         }
  74. #endif
  75.                                                 }
  76.                                                 else
  77.                                                         break;
  78.  
  79.                                                 i++;
  80.                                         }
  81.                                 }
  82.                         }
  83.                 }
  84.         }
  85.  
  86.         return (m_debris.empty() == false);
  87. }
  88.  
  89. //------------------------------------------------------------------------
  90. void CVehicleDamageBehaviorSpawnDebris::Reset()
  91. {
  92.         m_pVehicle->SetObjectUpdate(this, IVehicle::eVOU_NoUpdate);
  93.  
  94.         TDebrisInfoList::iterator debrisIte = m_debris.begin();
  95.         TDebrisInfoList::iterator debrisEnd = m_debris.end();
  96.  
  97.         for (; debrisIte != debrisEnd; ++debrisIte)
  98.         {
  99.                 SDebrisInfo& debrisInfo = *debrisIte;
  100.                 debrisInfo.time = 0.0f;
  101.  
  102.                 if (debrisInfo.entityId)
  103.                 {
  104.                         if (GetISystem()->IsSerializingFile() != 1)
  105.                                 gEnv->pEntitySystem->RemoveEntity(debrisInfo.entityId);
  106.                         debrisInfo.entityId = 0;
  107.                 }
  108.         }
  109. }
  110.  
  111. //------------------------------------------------------------------------
  112. void CVehicleDamageBehaviorSpawnDebris::OnDamageEvent(EVehicleDamageBehaviorEvent event, const SVehicleDamageBehaviorEventParams& params)
  113. {
  114.         if (event != eVDBE_Hit && params.hitValue < 1.0f)
  115.                 return;
  116.  
  117.         bool isUpdateNeeded = false;
  118.  
  119.         TDebrisInfoList::iterator debrisIte = m_debris.begin();
  120.         TDebrisInfoList::iterator debrisEnd = m_debris.end();
  121.  
  122.         for (; debrisIte != debrisEnd; ++debrisIte)
  123.         {
  124.                 SDebrisInfo& debrisInfo = *debrisIte;
  125.  
  126.                 if (!debrisInfo.entityId)
  127.                 {
  128.                         debrisInfo.time = cry_random(0.0f, 1.0f) * (4.0f - min(3.0f, params.hitValue));
  129.                         debrisInfo.force = params.componentDamageRatio;
  130.                         isUpdateNeeded = true;
  131.  
  132.                         IEntity* pEntity = debrisInfo.pAnimatedPart->GetEntity();
  133.                         CRY_ASSERT(pEntity);
  134.  
  135.                         ICharacterInstance* pCharInstance = debrisInfo.pAnimatedPart->GetEntity()->GetCharacter(
  136.                           debrisInfo.pAnimatedPart->GetSlot());
  137.  
  138.                         if (!pCharInstance)
  139.                                 return;
  140.  
  141.                         ISkeletonPose* pSkeletonPose = pCharInstance->GetISkeletonPose();
  142.                         IDefaultSkeleton& rIDefaultSkeleton = pCharInstance->GetIDefaultSkeleton();
  143.                         const char* pJointName = rIDefaultSkeleton.GetJointNameByID(debrisInfo.jointId);
  144.  
  145.                         IStatObj* pDebrisObj = debrisInfo.pAnimatedPart->GetDestroyedGeometry(pJointName, debrisInfo.index);
  146.                         if (pDebrisObj)
  147.                         {
  148.                                 Matrix34 vehicleTM = debrisInfo.pAnimatedPart->GetDestroyedGeometryTM(pJointName, debrisInfo.index);
  149.                                 Matrix34 intactTM = Matrix34((pSkeletonPose->GetAbsJointByID(debrisInfo.jointId)));
  150.  
  151.                                 if (IEntity* pDebrisEntity = SpawnDebris(pDebrisObj, vehicleTM * Matrix33(intactTM), debrisInfo.force))
  152.                                 {
  153.                                         debrisInfo.entityId = pDebrisEntity->GetId();
  154.                                         float force = cry_random(0.0f, 2.0f);
  155.                                         GiveImpulse(pDebrisEntity, force);
  156.                                         AttachParticleEffect(pEntity);
  157.                                 }
  158.                                 else
  159.                                         debrisInfo.entityId = 0;
  160.                         }
  161.                 }
  162.         }
  163.  
  164.         if (isUpdateNeeded)
  165.                 m_pVehicle->SetObjectUpdate(this, IVehicle::eVOU_AlwaysUpdate);
  166. }
  167.  
  168. //------------------------------------------------------------------------
  169. void CVehicleDamageBehaviorSpawnDebris::OnVehicleEvent(EVehicleEvent event, const SVehicleEventParams& params)
  170. {
  171.         if (event == eVE_Collision)
  172.         {
  173.                 TDebrisInfoList::iterator debrisIte = m_debris.begin();
  174.                 TDebrisInfoList::iterator debrisEnd = m_debris.end();
  175.  
  176.                 for (; debrisIte != debrisEnd; ++debrisIte)
  177.                 {
  178.                         SDebrisInfo& debrisInfo = *debrisIte;
  179.                         if (debrisInfo.time > 0.0f)
  180.                         {
  181.                                 if (IEntity* pEntity = gEnv->pEntitySystem->GetEntity(debrisInfo.entityId))
  182.                                 {
  183.                                         pEntity->DetachThis();
  184.                                         AttachParticleEffect(pEntity);
  185.                                         GiveImpulse(pEntity, 1.0f);
  186.                                 }
  187.  
  188.                                 debrisInfo.time = 0.0f;
  189.                         }
  190.                 }
  191.         }
  192. }
  193.  
  194. //------------------------------------------------------------------------
  195. void CVehicleDamageBehaviorSpawnDebris::Update(const float deltaTime)
  196. {
  197.         const Matrix34& worldTM = m_pVehicle->GetEntity()->GetWorldTM();
  198.  
  199.         TDebrisInfoList::iterator debrisIte = m_debris.begin();
  200.         TDebrisInfoList::iterator debrisEnd = m_debris.end();
  201.  
  202.         for (; debrisIte != debrisEnd; ++debrisIte)
  203.         {
  204.                 SDebrisInfo& debrisInfo = *debrisIte;
  205.  
  206.                 if (debrisInfo.time > 0.0f)
  207.                 {
  208.                         debrisInfo.time -= deltaTime;
  209.  
  210.                         if (debrisInfo.time <= 0.0f)
  211.                         {
  212.                                 if (IEntity* pEntity = gEnv->pEntitySystem->GetEntity(debrisInfo.entityId))
  213.                                 {
  214.                                         pEntity->DetachThis();
  215.                                         AttachParticleEffect(pEntity);
  216.                                         GiveImpulse(pEntity, 2.0f);
  217.                                 }
  218.                                 debrisInfo.time = 0.0f;
  219.                         }
  220.                 }
  221.         }
  222. }
  223.  
  224. //------------------------------------------------------------------------
  225. IEntity* CVehicleDamageBehaviorSpawnDebris::SpawnDebris(IStatObj* pStatObj, Matrix34 vehicleTM, float force)
  226. {
  227.         IEntity* pVehicleEntity = m_pVehicle->GetEntity();
  228.         CRY_ASSERT(pVehicleEntity);
  229.  
  230.         // spawn the detached entity
  231.  
  232.         char buffer[128];
  233.         cry_sprintf(buffer, "%s_DetachedPart_%s", m_pVehicle->GetEntity()->GetName(), pStatObj->GetGeoName());
  234.  
  235.         SEntitySpawnParams spawnParams;
  236.         spawnParams.sName = buffer;
  237.         spawnParams.nFlags = ENTITY_FLAG_CLIENT_ONLY;
  238.         if (!m_pickableDebris)
  239.                 spawnParams.nFlags |= ENTITY_FLAG_NO_PROXIMITY;
  240.         spawnParams.pClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass("VehiclePartDetached");
  241.         if (!spawnParams.pClass)
  242.                 return NULL;
  243.  
  244.         IEntity* pSpawnedDebris = gEnv->pEntitySystem->SpawnEntity(spawnParams, true);
  245.  
  246.         if (!pSpawnedDebris)
  247.                 return NULL;
  248.  
  249.         // place the geometry on the new entity
  250.         int slot = pSpawnedDebris->SetStatObj(pStatObj, -1, true, 200.0f);
  251.  
  252.         pSpawnedDebris->SetWorldTM(m_pVehicle->GetEntity()->GetWorldTM() * vehicleTM);
  253.  
  254. #if ENABLE_VEHICLE_DEBUG
  255.         if (VehicleCVars().v_debugdraw == eVDB_Parts)
  256.         {
  257.                 CryLog("VehicleDamageBehaviorSpawnDebris[%s]: spawned debris part %s (offfset %i %i %i)", m_pVehicle->GetEntity()->GetName(), pStatObj->GetGeoName(), (int)vehicleTM.GetTranslation().x, (int)vehicleTM.GetTranslation().y, (int)vehicleTM.GetTranslation().z);
  258.         }
  259. #endif
  260.  
  261.         SEntityPhysicalizeParams physicsParams;
  262.  
  263.         if (!pStatObj->GetPhysicalProperties(physicsParams.mass, physicsParams.density))
  264.                 physicsParams.mass = 200.0f;
  265.  
  266.         physicsParams.type = PE_RIGID;
  267.         physicsParams.nFlagsOR &= pef_log_collisions;
  268.         physicsParams.nSlot = 0;
  269.         pSpawnedDebris->Physicalize(physicsParams);
  270.  
  271.         if (IPhysicalEntity* pPhysEntity = pSpawnedDebris->GetPhysics())
  272.         {
  273.                 pe_params_buoyancy buoyancy;
  274.                 buoyancy.waterDensity = 0.15f;
  275.                 buoyancy.waterResistance = 30.0f;
  276.                 pPhysEntity->SetParams(&buoyancy);
  277.  
  278.                 m_spawnedDebris.push_back(pSpawnedDebris->GetId());
  279.                 return pSpawnedDebris;
  280.         }
  281.         else
  282.         {
  283.                 return NULL;
  284.         }
  285. }
  286.  
  287. //------------------------------------------------------------------------
  288. void CVehicleDamageBehaviorSpawnDebris::AttachParticleEffect(IEntity* pDetachedEntity)
  289. {
  290.         if (m_particleEffect.empty())
  291.                 return;
  292.  
  293.         if (IParticleEffect* pEffect = gEnv->pParticleManager->FindEffect(m_particleEffect.c_str(), "VehicleDamageBehaviorEffect"))
  294.         {
  295.                 int slot = pDetachedEntity->LoadParticleEmitter(-1, pEffect, NULL, false, true);
  296.  
  297.                 if (IParticleEmitter* pParticleEmitter = pDetachedEntity->GetParticleEmitter(slot))
  298.                 {
  299.                         SpawnParams spawnParams;
  300.                         spawnParams.fSizeScale = cry_random(0.5f, 1.0f);
  301.  
  302.                         pParticleEmitter->SetSpawnParams(spawnParams);
  303.                 }
  304.         }
  305. }
  306.  
  307. //------------------------------------------------------------------------
  308. void CVehicleDamageBehaviorSpawnDebris::GiveImpulse(IEntity* pDetachedEntity, float force)
  309. {
  310.         IPhysicalEntity* pDebrisPhysEntity = pDetachedEntity->GetPhysics();
  311.         IPhysicalEntity* pVehiclePhysEntity = m_pVehicle->GetEntity()->GetPhysics();
  312.         if (!pDebrisPhysEntity || !pVehiclePhysEntity)
  313.                 return;
  314.  
  315.         pe_action_impulse imp;
  316.         Vec3 randomVel;
  317.  
  318.         pe_status_dynamics debrisDyn;
  319.         pe_status_dynamics vehicleDyn;
  320.         pDebrisPhysEntity->GetStatus(&debrisDyn);
  321.         pVehiclePhysEntity->GetStatus(&vehicleDyn);
  322.  
  323.         randomVel.x = cry_random(0.0f, 1.0f);
  324.         randomVel.y = cry_random(0.0f, 1.0f);
  325.         randomVel.z = cry_random(0.0f, 1.0f);
  326.  
  327.         imp.impulse = Vec3(vehicleDyn.v.x * randomVel.x, vehicleDyn.v.y * randomVel.y, vehicleDyn.v.z * randomVel.z);
  328.         imp.impulse *= debrisDyn.mass * force;
  329.  
  330.         randomVel.x = cry_random(0.0f, 1.0f);
  331.         randomVel.y = cry_random(0.0f, 1.0f);
  332.         randomVel.z = cry_random(0.0f, 1.0f);
  333.  
  334.         imp.angImpulse = Vec3(vehicleDyn.w.x * randomVel.x, vehicleDyn.w.y * randomVel.y, vehicleDyn.w.z * randomVel.z);
  335.         imp.angImpulse *= debrisDyn.mass * force;
  336.  
  337.         pDebrisPhysEntity->Action(&imp);
  338. }
  339.  
  340. void CVehicleDamageBehaviorSpawnDebris::GetMemoryUsage(ICrySizer* s) const
  341. {
  342.         s->Add(*this);
  343.         s->AddObject(m_spawnedDebris);
  344.         s->AddObject(m_debris);
  345. }
  346.  
  347. DEFINE_VEHICLEOBJECT(CVehicleDamageBehaviorSpawnDebris);
  348.  
downloadVehicleDamageBehaviorSpawnDebris.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