BVB Source Codes

CRYENGINE Show VehiclePartAnimated.cpp Source code

Return Download CRYENGINE: download VehiclePartAnimated.cpp Source code - Download CRYENGINE Source code - Type:.cpp
  1. // Copyright 2001-2016 Crytek GmbH / Crytek Group. All rights reserved.
  2.  
  3. /*************************************************************************
  4.    -------------------------------------------------------------------------
  5.    $Id$
  6.    $DateTime$
  7.    Description: Implements a part for vehicles which uses animated characters
  8.  
  9.    -------------------------------------------------------------------------
  10.    History:
  11.    - 24:08:2005: Created by Mathieu Pinard
  12.  
  13. *************************************************************************/
  14. #include "StdAfx.h"
  15.  
  16. #include <CryAnimation/ICryAnimation.h>
  17. #include "IVehicleSystem.h"
  18.  
  19. #include "CryAction.h"
  20. #include "Vehicle.h"
  21. #include "VehiclePartBase.h"
  22. #include "VehiclePartAnimated.h"
  23. #include "VehiclePartAnimatedJoint.h"
  24. #include "VehicleUtils.h"
  25.  
  26. //#pragma optimize("", off)
  27. //#pragma inline_depth(0)
  28.  
  29. //------------------------------------------------------------------------
  30. CVehiclePartAnimated::CVehiclePartAnimated()
  31.         : m_pCharInstanceDestroyed(NULL)
  32.         , m_pCharInstance(NULL)
  33.         , m_ignoreDestroyedState(false)
  34. {
  35.         m_hullMatId[0] = m_hullMatId[1] = -1;
  36.         m_lastAnimLayerAssigned = 0;
  37.         m_iRotChangedFrameId = 0;
  38.         m_serializeForceRotationUpdate = false;
  39.         m_initialiseOnChangeState = true;
  40. }
  41.  
  42. //------------------------------------------------------------------------
  43. CVehiclePartAnimated::~CVehiclePartAnimated()
  44. {
  45.         if (m_pCharInstanceDestroyed)
  46.         {
  47.                 m_pCharInstanceDestroyed->Release();
  48.                 m_pCharInstanceDestroyed = 0;
  49.         }
  50. }
  51.  
  52. //------------------------------------------------------------------------
  53. bool CVehiclePartAnimated::Init(IVehicle* pVehicle, const CVehicleParams& table, IVehiclePart* parent, CVehicle::SPartInitInfo& initInfo, int partType)
  54. {
  55.         if (!CVehiclePartBase::Init(pVehicle, table, parent, initInfo, eVPT_Animated))
  56.                 return false;
  57.  
  58.         if (CVehicleParams animatedTable = table.findChild("Animated"))
  59.         {
  60.                 animatedTable.getAttr("ignoreDestroyedState", m_ignoreDestroyedState);
  61.         }
  62.  
  63.         InitGeometry();
  64.  
  65.         m_state = eVGS_Default;
  66.  
  67.         m_pVehicle->SetObjectUpdate(this, IVehicle::eVOU_AlwaysUpdate);
  68.  
  69.         return true;
  70. }
  71.  
  72. //------------------------------------------------------------------------
  73. void CVehiclePartAnimated::Release()
  74. {
  75.         if (m_pCharInstance)
  76.         {
  77.                 if (ISkeletonPose* pSkeletonPose = m_pCharInstance->GetISkeletonPose())
  78.                         pSkeletonPose->SetPostProcessCallback(NULL, NULL);
  79.  
  80.                 m_pCharInstance = 0;
  81.         }
  82.  
  83.         if (m_pCharInstanceDestroyed)
  84.         {
  85.                 m_pCharInstanceDestroyed->Release();
  86.                 m_pCharInstanceDestroyed = 0;
  87.         }
  88.  
  89.         if (m_slot != -1)
  90.                 m_pVehicle->GetEntity()->FreeSlot(m_slot);
  91.  
  92.         CVehiclePartBase::Release();
  93. }
  94.  
  95. //------------------------------------------------------------------------
  96. void CVehiclePartAnimated::Reset()
  97. {
  98.         CVehiclePartBase::Reset();
  99.  
  100.         SetDrivingProxy(false);
  101.  
  102.         if (m_slot > -1 && m_pCharInstance)
  103.         {
  104.                 ISkeletonAnim* pSkeletonAnim = m_pCharInstance->GetISkeletonAnim();
  105.                 CRY_ASSERT(pSkeletonAnim);
  106.                 ISkeletonPose* pSkeletonPose = m_pCharInstance->GetISkeletonPose();
  107.                 CRY_ASSERT(pSkeletonPose);
  108.                 IDefaultSkeleton& rIDefaultSkeleton = m_pCharInstance->GetIDefaultSkeleton();
  109.                 pSkeletonAnim->StopAnimationsAllLayers();
  110.                 pSkeletonPose->SetDefaultPose();
  111.                 pSkeletonPose->SetForceSkeletonUpdate(0);
  112.  
  113.                 for (int i = 0; i < rIDefaultSkeleton.GetJointCount(); ++i)
  114.                         pSkeletonPose->SetMaterialOnJoint(i, NULL);
  115.         }
  116.  
  117.         m_iRotChangedFrameId = 0;
  118. }
  119.  
  120. //------------------------------------------------------------------------
  121. void CVehiclePartAnimated::OnEvent(const SVehiclePartEvent& event)
  122. {
  123.         CVehiclePartBase::OnEvent(event);
  124.  
  125.         switch (event.type)
  126.         {
  127.         case eVPE_DriverEntered:
  128.                 {
  129.                         if (!m_pVehicle->IsFlipped())
  130.                                 SetDrivingProxy(true);
  131.                 }
  132.                 break;
  133.         case eVPE_DriverLeft:
  134.                 {
  135.                         SetDrivingProxy(false);
  136.                 }
  137.                 break;
  138.         case eVPE_FlippedOver:
  139.                 {
  140.                         if (event.bparam)
  141.                                 SetDrivingProxy(false);
  142.                         else if (m_pVehicle->GetDriver())
  143.                                 SetDrivingProxy(true);
  144.                 }
  145.                 break;
  146.         }
  147. }
  148.  
  149. //------------------------------------------------------------------------
  150. IVehiclePart::EVehiclePartState CVehiclePartAnimated::GetStateForDamageRatio(float ratio)
  151. {
  152.         if (ratio >= 1.f && m_pVehicle->IsDestroyable())
  153.                 return eVGS_Destroyed;
  154.  
  155.         return eVGS_Default;
  156. }
  157.  
  158. //------------------------------------------------------------------------
  159. void CVehiclePartAnimated::SetMaterial(IMaterial* pMaterial)
  160. {
  161.         if (m_pClonedMaterial)
  162.                 m_pClonedMaterial = NULL;
  163.  
  164.         GetEntity()->SetMaterial(pMaterial);
  165. }
  166.  
  167. //------------------------------------------------------------------------
  168. void CVehiclePartAnimated::InitGeometry()
  169. {
  170.         if (!m_pSharedParameters->m_filename.empty())
  171.         {
  172.                 m_slot = GetEntity()->LoadCharacter(m_slot, m_pSharedParameters->m_filename.c_str());
  173.                 m_pCharInstance = GetEntity()->GetCharacter(m_slot);
  174.  
  175.                 if (m_pCharInstance)
  176.                 {
  177.                         if (m_pCharInstance->GetIMaterial() && !GetEntity()->GetMaterial())
  178.                         {
  179.                                 SetMaterial(m_pCharInstance->GetIMaterial());
  180.                         }
  181.  
  182.                         ISkeletonAnim* pSkeletonAnim = m_pCharInstance->GetISkeletonAnim();
  183.                         ISkeletonPose* pSkeletonPose = m_pCharInstance->GetISkeletonPose();
  184.                         IDefaultSkeleton& rIDefaultSkeleton = m_pCharInstance->GetIDefaultSkeleton();
  185.  
  186.                         if (pSkeletonAnim)
  187.                                 pSkeletonAnim->StopAnimationsAllLayers();
  188.  
  189.                         if (m_hideCount == 0)
  190.                                 GetEntity()->SetSlotFlags(m_slot, GetEntity()->GetSlotFlags(m_slot) | ENTITY_SLOT_RENDER);
  191.                         else
  192.                                 GetEntity()->SetSlotFlags(m_slot, GetEntity()->GetSlotFlags(m_slot) & ~(ENTITY_SLOT_RENDER | ENTITY_SLOT_RENDER_NEAREST));
  193.  
  194. #if ENABLE_VEHICLE_DEBUG
  195.                         if (IsDebugParts())
  196.                         {
  197.                                 CryLog("joint transformations for %s", m_pCharInstance->GetFilePath());
  198.  
  199.                                 for (int i = 0; i < rIDefaultSkeleton.GetJointCount(); ++i)
  200.                                         VehicleUtils::LogMatrix(rIDefaultSkeleton.GetJointNameByID(i), Matrix34(pSkeletonPose->GetRelJointByID(i)));
  201.                         }
  202. #endif
  203.                 }
  204.  
  205.                 if (!m_pCharInstanceDestroyed && !m_pSharedParameters->m_filenameDestroyed.empty())
  206.                         m_pCharInstanceDestroyed = gEnv->pCharacterManager->CreateInstance(m_pSharedParameters->m_filenameDestroyed.c_str());
  207.  
  208.                 if (m_pCharInstanceDestroyed)
  209.                 {
  210.                         m_pCharInstanceDestroyed->AddRef();
  211.  
  212. #if ENABLE_VEHICLE_DEBUG
  213.                         if (IsDebugParts())
  214.                         {
  215.                                 CryLog("joint transformations for %s", m_pCharInstanceDestroyed->GetFilePath());
  216.  
  217.                                 ISkeletonPose* pSkeletonDestroyed = m_pCharInstanceDestroyed->GetISkeletonPose();
  218.                                 IDefaultSkeleton& rIDefaultSkeleton = m_pCharInstanceDestroyed->GetIDefaultSkeleton();
  219.                                 for (int i = 0; i < rIDefaultSkeleton.GetJointCount(); ++i)
  220.                                         VehicleUtils::LogMatrix(rIDefaultSkeleton.GetJointNameByID(i), Matrix34(pSkeletonDestroyed->GetRelJointByID(i)));
  221.                         }
  222. #endif
  223.                 }
  224.         }
  225.  
  226.         if (m_pSharedParameters->m_isPhysicalized && m_slot > -1)
  227.                 GetEntity()->UnphysicalizeSlot(m_slot);
  228.  
  229.         if (m_pCharInstance)
  230.         {
  231.                 m_pCharInstance->GetISkeletonAnim()->StopAnimationsAllLayers();
  232.  
  233.                 if (m_hideCount == 0)
  234.                         GetEntity()->SetSlotFlags(m_slot, GetEntity()->GetSlotFlags(m_slot) | ENTITY_SLOT_RENDER);
  235.                 else
  236.                         GetEntity()->SetSlotFlags(m_slot, GetEntity()->GetSlotFlags(m_slot) & ~(ENTITY_SLOT_RENDER | ENTITY_SLOT_RENDER_NEAREST));
  237.         }
  238.  
  239.         // Disable hand-placed (static) decals on vehicles
  240.         GetEntity()->SetFlags(GetEntity()->GetFlags() | ENTITY_FLAG_NO_DECALNODE_DECALS);
  241. }
  242.  
  243. //------------------------------------------------------------------------
  244. IStatObj* CVehiclePartAnimated::GetGeometryForState(CVehiclePartAnimatedJoint* pPart, EVehiclePartState state)
  245. {
  246.         string name;
  247.         pPart->GetGeometryName(state, name);
  248.  
  249.         IStatObj* pStatObj = 0;
  250.  
  251.         if (state > eVGS_Default)
  252.         {
  253.                 if (pPart->m_pDestroyedGeometry)
  254.                 {
  255.                         pStatObj = pPart->m_pDestroyedGeometry;
  256.                 }
  257.                 else
  258.                 {
  259.                         IDefaultSkeleton* pIDefaultSkeleton = m_pCharInstanceDestroyed ? &m_pCharInstanceDestroyed->GetIDefaultSkeleton() : 0;
  260.                         if (pIDefaultSkeleton)
  261.                         {
  262.                                 int jointId = pIDefaultSkeleton->GetJointIDByName(name.c_str());
  263.  
  264.                                 ISkeletonPose* pSkeletonPose = m_pCharInstanceDestroyed->GetISkeletonPose();
  265.                                 if (jointId != -1)
  266.                                         pStatObj = pSkeletonPose->GetStatObjOnJoint(jointId);
  267.                         }
  268.                 }
  269.         }
  270.         else
  271.         {
  272.                 TStringStatObjMap::const_iterator it = m_intactStatObjs.find(name.c_str());
  273.                 if (it != m_intactStatObjs.end())
  274.                         pStatObj = it->second;
  275.         }
  276.  
  277.         return pStatObj;
  278. }
  279.  
  280. //------------------------------------------------------------------------
  281. IStatObj* CVehiclePartAnimated::GetDestroyedGeometry(const char* pJointName, unsigned int index)
  282. {
  283.         if (pJointName[0] && m_pCharInstanceDestroyed)
  284.         {
  285.                 IDefaultSkeleton& rICharacterModelSkeletonDestroyed = m_pCharInstanceDestroyed->GetIDefaultSkeleton();
  286.                 ISkeletonPose* pSkeletonDestroyed = m_pCharInstanceDestroyed->GetISkeletonPose();
  287.                 CRY_ASSERT(pSkeletonDestroyed);
  288.  
  289.                 char buffer[256];
  290.  
  291.                 const char* pSuffix = !m_pSharedParameters->m_destroyedSuffix.empty() ? m_pSharedParameters->m_destroyedSuffix.c_str() : GetDestroyedGeometrySuffix(eVGS_Destroyed);
  292.  
  293.                 if (index == 0)
  294.                 {
  295.                         cry_sprintf(buffer, "%s%s", pJointName, pSuffix);
  296.                 }
  297.                 else
  298.                 {
  299.                         cry_sprintf(buffer, "%s_debris_%u", pJointName, index);
  300.                 }
  301.  
  302.                 buffer[sizeof(buffer) - 1] = '\0';
  303.  
  304.                 int16 jointIdForDestroyed = rICharacterModelSkeletonDestroyed.GetJointIDByName(buffer);
  305.                 if (jointIdForDestroyed > -1)
  306.                 {
  307.                         return pSkeletonDestroyed->GetStatObjOnJoint(jointIdForDestroyed);
  308.                 }
  309.         }
  310.  
  311.         return NULL;
  312. }
  313.  
  314. //------------------------------------------------------------------------
  315. Matrix34 CVehiclePartAnimated::GetDestroyedGeometryTM(const char* pJointName, unsigned int index)
  316. {
  317.         if (pJointName[0] && m_pCharInstanceDestroyed)
  318.         {
  319.                 IDefaultSkeleton& rICharacterModelSkeletonDestroyed = m_pCharInstanceDestroyed->GetIDefaultSkeleton();
  320.                 ISkeletonPose* pSkeletonDestroyed = m_pCharInstanceDestroyed->GetISkeletonPose();
  321.                 CRY_ASSERT(pSkeletonDestroyed);
  322.  
  323.                 char buffer[256];
  324.  
  325.                 const char* pSuffix = !m_pSharedParameters->m_destroyedSuffix.empty() ? m_pSharedParameters->m_destroyedSuffix.c_str() : GetDestroyedGeometrySuffix(eVGS_Destroyed);
  326.  
  327.                 if (index == 0)
  328.                 {
  329.                         cry_sprintf(buffer, "%s%s", pJointName, pSuffix);
  330.                 }
  331.                 else
  332.                 {
  333.                         cry_sprintf(buffer, "%s_debris_%u", pJointName, index);
  334.                 }
  335.  
  336.                 buffer[sizeof(buffer) - 1] = '\0';
  337.  
  338.                 int16 jointIdForDestroyed = rICharacterModelSkeletonDestroyed.GetJointIDByName(buffer);
  339.                 if (jointIdForDestroyed > -1)
  340.                         return Matrix34(pSkeletonDestroyed->GetAbsJointByID(jointIdForDestroyed));
  341.         }
  342.  
  343.         Matrix34 identTM;
  344.         identTM.SetIdentity();
  345.         return identTM;
  346. }
  347.  
  348. //------------------------------------------------------------------------
  349. bool CVehiclePartAnimated::ChangeState(EVehiclePartState state, int flags)
  350. {
  351.         if ((state == eVGS_Default) && m_initialiseOnChangeState)
  352.         {
  353.                 // Initialise!
  354.                 // Having to do this because of the way the glass code
  355.                 // swaps a cstatobj. The way the vehicle code stores its
  356.                 // statobj in m_intactStatObjs is going to need reviewing
  357.                 if (m_pCharInstance)
  358.                 {
  359.                         ISkeletonPose* pSkeletonPose = m_pCharInstance->GetISkeletonPose();
  360.                         IDefaultSkeleton& rIDefaultSkeleton = m_pCharInstance->GetIDefaultSkeleton();
  361.                         ISkeletonPose* pSkeletonPoseDestroyed = m_pCharInstanceDestroyed ? m_pCharInstanceDestroyed->GetISkeletonPose() : NULL;
  362.                         IDefaultSkeleton* pICharacterModelSkeletonDestroyed = m_pCharInstanceDestroyed ? &m_pCharInstanceDestroyed->GetIDefaultSkeleton() : NULL;
  363.                         if (pSkeletonPose)
  364.                         {
  365.                                 const bool bDestroyedSkelExists = pSkeletonPoseDestroyed && pICharacterModelSkeletonDestroyed;
  366.                                 for (uint32 i = 0; i < rIDefaultSkeleton.GetJointCount(); i++)
  367.                                 {
  368.                                         if (IStatObj* pStatObjIntact = pSkeletonPose->GetStatObjOnJoint(i))
  369.                                         {
  370.                                                 const char* jointName = rIDefaultSkeleton.GetJointNameByID(i);
  371.  
  372.                                                 if (m_intactStatObjs.find(CONST_TEMP_STRING(jointName)) == m_intactStatObjs.end())
  373.                                                 {
  374.                                                         m_intactStatObjs.insert(TStringStatObjMap::value_type(jointName, pStatObjIntact));
  375.                                                 }
  376.  
  377.                                                 // tell the streaming engine to stream destroyed version together with non destroyed
  378.                                                 if (bDestroyedSkelExists && i < pICharacterModelSkeletonDestroyed->GetJointCount())
  379.                                                 {
  380.                                                         if (IStatObj* pStatObjIntactDestroyed = pSkeletonPoseDestroyed->GetStatObjOnJoint(i))
  381.                                                         {
  382.                                                                 pStatObjIntact->SetStreamingDependencyFilePath(pStatObjIntactDestroyed->GetFilePath());
  383.                                                         }
  384.                                                 }
  385.                                         }
  386.                                 }
  387.                         }
  388.                 }
  389.                 m_initialiseOnChangeState = false;
  390.         }
  391.  
  392.         bool change = CVehiclePartBase::ChangeState(state, flags);
  393.  
  394.         if (state == eVGS_Default && !change)
  395.         {
  396.                 // need to restore state if one of the children is in higher state
  397.                 EVehiclePartState maxState = GetMaxState();
  398.  
  399.                 if (maxState > m_state)
  400.                         change = true;
  401.         }
  402.  
  403.         if (!change)
  404.         {
  405.                 return false;
  406.         }
  407.  
  408.         if (state == eVGS_Destroyed)
  409.         {
  410.                 if (m_ignoreDestroyedState)
  411.                         return false;
  412.  
  413.                 if (m_pCharInstance && m_pCharInstanceDestroyed)
  414.                 {
  415.                         ISkeletonPose* pSkeletonPose = m_pCharInstance->GetISkeletonPose();
  416.                         IDefaultSkeleton& rIDefaultSkeleton = m_pCharInstance->GetIDefaultSkeleton();
  417.                         if (pSkeletonPose)
  418.                         {
  419.                                 IMaterial* pDestroyedMaterial = m_pVehicle->GetDestroyedMaterial();
  420.  
  421.                                 for (uint32 i = 0; i < rIDefaultSkeleton.GetJointCount(); i++)
  422.                                 {
  423.                                         if (IStatObj* pStatObjIntact = pSkeletonPose->GetStatObjOnJoint(i))
  424.                                         {
  425.                                                 const char* jointName = rIDefaultSkeleton.GetJointNameByID(i);
  426.                                                 IStatObj* pStatObj = GetDestroyedGeometry(jointName);
  427.  
  428.                                                 // sets new StatObj to joint, if null, removes it.
  429.                                                 // object whose name includes "proxy" are not removed.
  430.                                                 if (pStatObj || !strstr(jointName, "proxy"))
  431.                                                 {
  432.                                                         SetCGASlot(i, pStatObj);
  433.  
  434.                                                         if (pStatObj && !pDestroyedMaterial)
  435.                                                         {
  436.                                                                 if (IMaterial* pMaterial = pStatObj->GetMaterial())
  437.                                                                         SetMaterial(pMaterial);
  438.                                                         }
  439.  
  440. #if ENABLE_VEHICLE_DEBUG
  441.                                                         if (IsDebugParts())
  442.                                                         {
  443.                                                                 CryLog("swapping StatObj on joint %u (%s) -> %s", i, jointName, pStatObj ? pStatObj->GetGeoName() : "<NULL>");
  444.                                                         }
  445. #endif
  446.                                                 }
  447.                                         }
  448.                                 }
  449.  
  450.                                 FlagSkeleton(pSkeletonPose, rIDefaultSkeleton);
  451.  
  452.                                 for (TStringVehiclePartMap::iterator ite = m_jointParts.begin(); ite != m_jointParts.end(); ++ite)
  453.                                 {
  454.                                         IVehiclePart* pPart = ite->second;
  455.                                         pPart->ChangeState(state, flags | eVPSF_Physicalize);
  456.                                 }
  457.  
  458.                                 CryCharAnimationParams animParams;
  459.                                 animParams.m_nFlags |= CA_LOOP_ANIMATION;
  460.                                 // pSkeleton->SetRedirectToLayer0(1);
  461.                                 // pSkeleton->StartAnimation("Default",0,  0,0, animParams);  // [MR: commented out on Ivos request]
  462.  
  463.                                 if (pDestroyedMaterial)
  464.                                 {
  465.                                         SetMaterial(pDestroyedMaterial);
  466.                                 }
  467.                         }
  468.                 }
  469.         }
  470.         else if (state == eVGS_Default)
  471.         {
  472.                 if (m_pCharInstance && m_pCharInstanceDestroyed)
  473.                 {
  474.                         // reset material (in case we replaced it with the destroyed material)
  475.                         IMaterial* pMaterial = m_pVehicle->GetPaintMaterial();
  476.                         if (!pMaterial)
  477.                         {
  478.                                 // no paint, so revert to the material already set on the character
  479.                                 pMaterial = m_pCharInstance->GetIMaterial();
  480.                         }
  481.                         if (pMaterial)
  482.                         {
  483.                                 SetMaterial(pMaterial);
  484.                         }
  485.  
  486.                         IDefaultSkeleton& rIDefaultSkeleton = m_pCharInstance->GetIDefaultSkeleton();
  487.                         {
  488.                                 for (TStringStatObjMap::iterator ite = m_intactStatObjs.begin(); ite != m_intactStatObjs.end(); ++ite)
  489.                                 {
  490.                                         const string& jointName = ite->first;
  491.                                         IStatObj* pStatObj = ite->second;
  492.  
  493.                                         int16 jointId = rIDefaultSkeleton.GetJointIDByName(jointName.c_str());
  494.                                         if (jointId > -1)
  495.                                         {
  496.                                                 // if compound StatObj (from deformation), use first SubObj for restoring
  497.                                                 if (pStatObj != NULL)
  498.                                                 {
  499.                                                         if (!pStatObj->GetRenderMesh() && pStatObj->GetSubObjectCount() > 0)
  500.                                                         {
  501.                                                                 pStatObj = pStatObj->GetSubObject(0)->pStatObj;
  502.                                                         }
  503.  
  504.                                                         SetCGASlot(jointId, pStatObj);
  505.  
  506. #if ENABLE_VEHICLE_DEBUG
  507.                                                         if (IsDebugParts())
  508.                                                                 CryLog("restoring StatObj on joint %i (%s) -> %s", jointId, jointName.c_str(), pStatObj ? pStatObj->GetGeoName() : "<NULL>");
  509. #endif
  510.                                                 }
  511.  
  512.                                                 TStringVehiclePartMap::iterator it = m_jointParts.find(jointName);
  513.                                                 if (it != m_jointParts.end())
  514.                                                 {
  515.                                                         it->second->ChangeState(state, flags & ~eVPSF_Physicalize | eVPSF_Force);
  516.                                                 }
  517.                                         }
  518.                                 }
  519.                                 flags |= eVPSF_Physicalize;
  520.                         }
  521.                 }
  522.         }
  523.  
  524.         m_state = state;
  525.  
  526.         // physicalize after all parts have been restored
  527.         if (flags & eVPSF_Physicalize && GetEntity()->GetPhysics())
  528.         {
  529.                 Physicalize();
  530.                 for (TStringVehiclePartMap::iterator it = m_jointParts.begin(); it != m_jointParts.end(); ++it)
  531.                 {
  532.                         it->second->Physicalize();
  533.                 }
  534.         }
  535.  
  536.         return true;
  537. }
  538.  
  539. //------------------------------------------------------------------------
  540. bool CVehiclePartAnimated::ChangeChildState(CVehiclePartAnimatedJoint* pPart, EVehiclePartState state, int flags)
  541. {
  542.         // only handle range between intact and destroyed
  543.         if (state > pPart->GetState() && (state < eVGS_Damaged1 || state >= eVGS_Destroyed))
  544.                 return false;
  545.  
  546.         if (state < pPart->GetState() && pPart->GetState() >= eVGS_Destroyed)
  547.                 return false;
  548.  
  549.         int jointId = pPart->GetJointId();
  550.  
  551.         if (pPart->GetState() == eVGS_Default)
  552.         {
  553.                 ISkeletonPose* pSkeletonPose = m_pCharInstance ? m_pCharInstance->GetISkeletonPose() : NULL;
  554.  
  555.                 if (IStatObj* pStatObjIntact = pSkeletonPose ? pSkeletonPose->GetStatObjOnJoint(jointId) : NULL)
  556.                 {
  557.                         IDefaultSkeleton& rIDefaultSkeleton = m_pCharInstance->GetIDefaultSkeleton();
  558.                         const char* jointName = rIDefaultSkeleton.GetJointNameByID(jointId);
  559.  
  560.                         if (m_intactStatObjs.find(CONST_TEMP_STRING(jointName)) == m_intactStatObjs.end())
  561.                                 m_intactStatObjs.insert(TStringStatObjMap::value_type(jointName, pStatObjIntact));
  562.                 }
  563.         }
  564.  
  565.         if (m_jointParts.find(pPart->GetName()) == m_jointParts.end())
  566.                 m_jointParts.insert(TStringVehiclePartMap::value_type(pPart->GetName(), pPart));
  567.  
  568.         IStatObj* pStatObj = GetGeometryForState(pPart, state);
  569.  
  570.         if (pStatObj)
  571.                 SetCGASlot(jointId, pStatObj, (flags & eVPSF_Physicalize) != 0);
  572.  
  573.         return true;
  574. }
  575.  
  576. //------------------------------------------------------------------------
  577. IStatObj* CVehiclePartAnimated::GetSubGeometry(CVehiclePartBase* pPart, EVehiclePartState state, Matrix34& localTM, bool removeFromParent)
  578. {
  579.         ICharacterInstance* pCharInstance = 0;
  580.         string jointName;
  581.         pPart->GetGeometryName(state, jointName);
  582.         int jointId = -1;
  583.  
  584.         if (state == eVGS_Destroyed)
  585.         {
  586.                 pCharInstance = m_pCharInstanceDestroyed;
  587.  
  588.                 if (pCharInstance)
  589.                         jointId = pCharInstance->GetIDefaultSkeleton().GetJointIDByName(jointName.c_str());
  590.         }
  591.         else
  592.         {
  593.                 // lookup first on intact, then on destroyed model
  594.                 pCharInstance = m_pCharInstance;
  595.  
  596.                 if (pCharInstance)
  597.                         jointId = pCharInstance->GetIDefaultSkeleton().GetJointIDByName(jointName.c_str());
  598.  
  599.                 if (jointId == -1)
  600.                 {
  601.                         pCharInstance = m_pCharInstanceDestroyed;
  602.  
  603.                         if (pCharInstance)
  604.                                 jointId = pCharInstance->GetIDefaultSkeleton().GetJointIDByName(jointName.c_str());
  605.                 }
  606.         }
  607.  
  608.         if (jointId != -1)
  609.         {
  610.                 if (ISkeletonPose* pSkeletonPose = pCharInstance->GetISkeletonPose())
  611.                 {
  612.                         localTM = Matrix34(pCharInstance->GetISkeletonPose()->GetAbsJointByID(jointId));
  613.  
  614.                         if (IStatObj* pStatObj = pSkeletonPose->GetStatObjOnJoint(jointId))
  615.                         {
  616.                                 if (removeFromParent && (pCharInstance != m_pCharInstanceDestroyed))
  617.                                 {
  618.                                         if (m_intactStatObjs.find(pPart->GetName()) == m_intactStatObjs.end())
  619.                                         {
  620.                                                 m_intactStatObjs.insert(TStringStatObjMap::value_type(pPart->GetName(), pStatObj));
  621.                                         }
  622.  
  623.                                         SetCGASlot(jointId, NULL);
  624.                                 }
  625.  
  626.                                 if (pPart)
  627.                                 {
  628.                                         m_jointParts.insert(TStringVehiclePartMap::value_type(pPart->GetName(), pPart));
  629.                                 }
  630.  
  631.                                 return pStatObj;
  632.                         }
  633.                         else if ((state == eVGS_Default) && (pPart->GetState() != eVGS_Default))
  634.                         {
  635.                                 TStringStatObjMap::const_iterator it = m_intactStatObjs.find(pPart->GetName());
  636.  
  637.                                 if (it != m_intactStatObjs.end())
  638.                                 {
  639.                                         return it->second;
  640.                                 }
  641.                         }
  642.                 }
  643.         }
  644.  
  645.         return NULL;
  646. }
  647.  
  648. //------------------------------------------------------------------------
  649. void CVehiclePartAnimated::Physicalize()
  650. {
  651.         if (m_pSharedParameters->m_isPhysicalized && GetEntity()->GetPhysics())
  652.         {
  653.                 if (m_slot != -1)
  654.                         GetEntity()->UnphysicalizeSlot(m_slot);
  655.  
  656.                 SEntityPhysicalizeParams params;
  657.                 params.mass = m_pSharedParameters->m_mass;
  658.                 params.density = m_pSharedParameters->m_density;
  659.                 params.nSlot = m_slot;
  660.                 GetEntity()->PhysicalizeSlot(m_slot, params); // always returns -1 for chars
  661.  
  662.                 if (m_pCharInstance)
  663.                 {
  664.                         FlagSkeleton(m_pCharInstance->GetISkeletonPose(), m_pCharInstance->GetIDefaultSkeleton());
  665.                 }
  666.  
  667.                 m_pVehicle->RequestPhysicalization(this, false);
  668.         }
  669.  
  670.         GetEntity()->SetSlotFlags(m_slot, GetEntity()->GetSlotFlags(m_slot) | ENTITY_SLOT_IGNORE_PHYSICS);
  671. }
  672.  
  673. //------------------------------------------------------------------------
  674. void CVehiclePartAnimated::FlagSkeleton(ISkeletonPose* pSkeletonPose, IDefaultSkeleton& rIDefaultSkeleton)
  675. {
  676.         if (!pSkeletonPose)
  677.                 return;
  678.  
  679.         IPhysicalEntity* pPhysics = GetEntity()->GetPhysics();
  680.         if (!pPhysics)
  681.                 return;
  682.  
  683.         string name;
  684.         int idWater = rIDefaultSkeleton.GetJointIDByName("proxy_water");
  685.         uint32 buoyancyParts = (idWater != -1) ? 1 : 0;
  686.  
  687.         uint32 jointCount = rIDefaultSkeleton.GetJointCount();
  688.         for (uint32 i = 0; i < jointCount; ++i)
  689.         {
  690.                 int physId = pSkeletonPose->GetPhysIdOnJoint(i);
  691.  
  692.                 if (physId >= 0)
  693.                 {
  694.                         CheckColltypeHeavy(physId);
  695.                         name = rIDefaultSkeleton.GetJointNameByID(i);
  696.  
  697.                         // when water proxy available, remove float from all others
  698.                         // if no water proxy, we leave only "proxy" parts floating
  699.                         if (idWater != -1)
  700.                         {
  701.                                 if (i == idWater)
  702.                                 {
  703.                                         SetFlags(physId, geom_collides, false);
  704.                                         SetFlagsCollider(physId, 0);
  705.                                 }
  706.                                 else
  707.                                         SetFlags(physId, geom_floats, false);
  708.                         }
  709.                         else
  710.                         {
  711.                                 if (name.find("proxy") != string::npos)
  712.                                         ++buoyancyParts;
  713.                                 else
  714.                                         SetFlags(physId, geom_floats, false);
  715.                         }
  716.  
  717.                         // all objects which have a corresponding *_proxy on the skeleton
  718.                         // are set to ray collision only
  719.                         if (name.find("_proxy") == string::npos)
  720.                         {
  721.                                 name.append("_proxy");
  722.                                 int proxyId = rIDefaultSkeleton.GetJointIDByName(name.c_str());
  723.  
  724.                                 if (proxyId != -1)
  725.                                 {
  726.                                         // remove ray collision from hull proxy(s)
  727.                                         SetFlags(pSkeletonPose->GetPhysIdOnJoint(proxyId), geom_colltype_ray | geom_colltype13, false);
  728.  
  729.                                         // get StatObj from main part, to connect proxies foreignData with it
  730.                                         IStatObj* pStatObj = pSkeletonPose->GetStatObjOnJoint(i);
  731.  
  732.                                         if (pStatObj)
  733.                                         {
  734.                                                 pe_params_part params;
  735.                                                 params.partid = proxyId;
  736.                                                 if (pPhysics->GetParams(&params))
  737.                                                 {
  738.                                                         if (params.pPhysGeom && params.pPhysGeom->pGeom)
  739.                                                                 params.pPhysGeom->pGeom->SetForeignData(pStatObj, 0);
  740.                                                 }
  741.                                         }
  742.  
  743.                                         for (int p = 2; p < 6; ++p)
  744.                                         {
  745.                                                 // check additional proxies, by naming convention _02, .. _05
  746.                                                 char buf[64];
  747.                                                 cry_sprintf(buf, "%s_%02i", name.c_str(), p);
  748.  
  749.                                                 proxyId = rIDefaultSkeleton.GetJointIDByName(buf);
  750.                                                 if (proxyId == -1)
  751.                                                         break;
  752.  
  753.                                                 int proxyPhysId = pSkeletonPose->GetPhysIdOnJoint(proxyId);
  754.                                                 if (proxyPhysId == -1)
  755.                                                         continue;
  756.  
  757.                                                 SetFlags(proxyPhysId, geom_colltype_ray | geom_colltype13, false);
  758.  
  759.                                                 // connect proxies to main StatObj (needed for bullet tests, decals)
  760.                                                 if (pStatObj)
  761.                                                 {
  762.                                                         pe_params_part params;
  763.                                                         params.partid = proxyPhysId;
  764.                                                         if (pPhysics->GetParams(&params))
  765.                                                         {
  766.                                                                 if (params.pPhysGeom && params.pPhysGeom->pGeom)
  767.                                                                         params.pPhysGeom->pGeom->SetForeignData(pStatObj, 0);
  768.                                                         }
  769.                                                 }
  770.                                         }
  771.  
  772.                                         // set ray-collision only on the part
  773.                                         SetFlags(physId, geom_collides | geom_floats, false);
  774.                                         SetFlags(physId, geom_colltype_ray | geom_colltype13, true);
  775.                                         SetFlagsCollider(physId, 0);
  776.                                 }
  777.                         }
  778.                 }
  779.         }
  780.  
  781.         if (buoyancyParts == 0)
  782.         {
  783.                 // as fallback, use part with largest volume for buoyancy
  784.                 int partId = -1;
  785.                 float maxV = 0.f;
  786.  
  787.                 pe_status_nparts nparts;
  788.                 int numParts = pPhysics->GetStatus(&nparts);
  789.  
  790.                 for (int i = 0; i < numParts; ++i)
  791.                 {
  792.                         pe_params_part params;
  793.                         params.ipart = i;
  794.                         if (pPhysics->GetParams(&params))
  795.                         {
  796.                                 float v = (params.pPhysGeomProxy) ? params.pPhysGeomProxy->V : params.pPhysGeom->V;
  797.                                 if (v > maxV)
  798.                                 {
  799.                                         partId = params.partid;
  800.                                         maxV = v;
  801.                                 }
  802.                         }
  803.                 }
  804.  
  805.                 if (partId != -1)
  806.                         SetFlags(partId, geom_floats, true);
  807.                 else
  808.                         GameWarning("[CVehiclePartAnimated]: <%s> has no buoyancy parts! (Check material for correct physicalization setup properties)", GetEntity()->GetName());
  809.         }
  810.  
  811.         int jointId, physId;
  812.         if ((jointId = rIDefaultSkeleton.GetJointIDByName("proxy_skirt")) != -1)
  813.         {
  814.                 if ((physId = pSkeletonPose->GetPhysIdOnJoint(jointId)) != -1)
  815.                 {
  816.                         SetFlags(physId, geom_collides | geom_floats, false);
  817.                         SetFlags(physId, geom_colltype_ray | geom_colltype13 | geom_colltype_player | geom_colltype_foliage, true);
  818.                         SetFlagsCollider(physId, 0);
  819.                 }
  820.         }
  821.  
  822.         // remove collision flags from all _proxy geoms by debug cvar
  823.         // useful for seeing through, testing ray proxies etc
  824.         if (VehicleCVars().v_disable_hull > 0)
  825.         {
  826.                 for (uint32 i = 0; i < rIDefaultSkeleton.GetJointCount(); ++i)
  827.                 {
  828.                         if (strstr(rIDefaultSkeleton.GetJointNameByID(i), "_proxy"))
  829.                         {
  830.                                 SetFlags(pSkeletonPose->GetPhysIdOnJoint(i), geom_collides | geom_floats, false);
  831.                                 SetFlagsCollider(pSkeletonPose->GetPhysIdOnJoint(i), 0);
  832.                         }
  833.                 }
  834.         }
  835. }
  836.  
  837. //------------------------------------------------------------------------
  838. void CVehiclePartAnimated::RotationChanged(CVehiclePartAnimatedJoint* pJoint)
  839. {
  840.         // craig: cannot drop these changes if the vehicle is on a server
  841.         bool cull = false;
  842.         if (gEnv->IsClient())
  843.                 cull = m_pVehicle->IsProbablyDistant();
  844.  
  845.         if (m_iRotChangedFrameId != gEnv->nMainFrameID && !cull)
  846.         {
  847.                 // force skeleton update for this frame (this is intended, contact Ivo)
  848.                 if (m_pCharInstance)
  849.                         m_pCharInstance->GetISkeletonPose()->SetForceSkeletonUpdate(1);
  850.  
  851.                 m_iRotChangedFrameId = gEnv->nMainFrameID;
  852.  
  853.                 // require update for the next frame to reset skeleton update
  854.                 m_pVehicle->NeedsUpdate();
  855.         }
  856. }
  857.  
  858. //------------------------------------------------------------------------
  859. void CVehiclePartAnimated::Update(const float frameTime)
  860. {
  861.         CVehiclePartBase::Update(frameTime);
  862.  
  863.         if (m_iRotChangedFrameId)
  864.         {
  865.                 if (m_iRotChangedFrameId < gEnv->nMainFrameID)
  866.                 {
  867.                         if (m_pCharInstance)
  868.                                 m_pCharInstance->GetISkeletonPose()->SetForceSkeletonUpdate(0);
  869.  
  870.                         m_iRotChangedFrameId = 0;
  871.                 }
  872.                 else
  873.                         m_pVehicle->NeedsUpdate();
  874.         }
  875.         else if (m_serializeForceRotationUpdate)
  876.         {
  877.                 m_serializeForceRotationUpdate = false;
  878.                 if (m_pCharInstance)
  879.                         m_pCharInstance->GetISkeletonPose()->SetForceSkeletonUpdate(1);
  880.                 m_iRotChangedFrameId = gEnv->nMainFrameID;
  881.                 m_pVehicle->NeedsUpdate();
  882.         }
  883. }
  884.  
  885. //------------------------------------------------------------------------
  886. void CVehiclePartAnimated::SetDrivingProxy(bool bDrive)
  887. {
  888.         IVehicleMovement* pMovement = m_pVehicle->GetMovement();
  889.         if (!(pMovement && pMovement->UseDrivingProxy()))
  890.                 return;
  891.  
  892.         if (0 == m_hullMatId[bDrive]) // 0 means, nothin to do
  893.                 return;
  894.  
  895.         if (!m_pCharInstance)
  896.                 return;
  897.  
  898.         ISkeletonPose* pSkeletonPose = m_pCharInstance->GetISkeletonPose();
  899.         if (!pSkeletonPose)
  900.                 return;
  901.         IDefaultSkeleton& rIDefaultSkeleton = m_pCharInstance->GetIDefaultSkeleton();
  902.         IPhysicalEntity* pPhysics = m_pVehicle->GetEntity()->GetPhysics();
  903.         if (!pPhysics)
  904.                 return;
  905.  
  906.         int id = rIDefaultSkeleton.GetJointIDByName("hull_proxy");
  907.  
  908.         if (id < 0)
  909.         {
  910.                 m_hullMatId[0] = m_hullMatId[1] = 0;
  911.                 return;
  912.         }
  913.  
  914.         int partid = pSkeletonPose->GetPhysIdOnJoint(id);
  915.  
  916.         if (partid == -1)
  917.                 return;
  918.  
  919.         pe_params_part params;
  920.         params.partid = partid;
  921.         params.ipart = -1;
  922.         if (!pPhysics->GetParams(&params) || !params.nMats)
  923.                 return;
  924.  
  925.         phys_geometry* pGeom = params.pPhysGeom;
  926.         if (pGeom && pGeom->surface_idx < pGeom->nMats)
  927.         {
  928.                 ISurfaceTypeManager* pSurfaceMan = gEnv->p3DEngine->GetMaterialManager()->GetSurfaceTypeManager();
  929.  
  930.                 // initialize once
  931.                 if (m_hullMatId[0] < 0)
  932.                 {
  933.                         int idDriving = 0;
  934.                         int idOrig = pGeom->pMatMapping[pGeom->surface_idx];
  935.                         const char* matOrig = pSurfaceMan->GetSurfaceType(idOrig)->GetName();
  936.  
  937.                         if (strstr(matOrig, "mat_metal"))
  938.                                 idDriving = pSurfaceMan->GetSurfaceTypeByName("mat_metal_nofric")->GetId();
  939.                         else
  940.                         {
  941.                                 string mat(matOrig);
  942.                                 mat.append("_nofric");
  943.  
  944.                                 idDriving = pSurfaceMan->GetSurfaceTypeByName(mat.c_str(), NULL, false)->GetId();
  945.                         }
  946.  
  947.                         //if (pDebug->GetIVal())
  948.                         //CryLog("%s looking up driving surface replacement for %s (id %i) -> got id %i", m_pVehicle->GetEntity()->GetName(), matOrig, idOrig, idDriving);
  949.  
  950.                         if (idDriving > 0)
  951.                         {
  952.                                 // store old and new id
  953.                                 m_hullMatId[0] = idOrig;
  954.                                 m_hullMatId[1] = idDriving;
  955.  
  956.                                 /*if (pDebug->GetIVal())
  957.                                    {
  958.                                    const char* matDriving = pSurfaceMan->GetSurfaceType(idDriving)->GetName();
  959.                                    CryLog("%s storing hull matId for swapping: %i (%s) -> %i (%s)", m_pVehicle->GetEntity()->GetName(), m_hullMatId[0], matOrig, m_hullMatId[1], matDriving);
  960.                                    }*/
  961.                         }
  962.                         else
  963.                                 m_hullMatId[0] = m_hullMatId[1] = 0;
  964.                 }
  965.  
  966.                 // only swap if materials available
  967.                 if (m_hullMatId[bDrive] > 0)
  968.                 {
  969. #if ENABLE_VEHICLE_DEBUG
  970.                         if (VehicleCVars().v_debugdraw == eVDB_Parts)
  971.                                 CryLog("%s swapping hull proxy from %i (%s) to matId %i (%s)", m_pVehicle->GetEntity()->GetName(), m_hullMatId[bDrive ^ 1], pSurfaceMan->GetSurfaceType(m_hullMatId[bDrive ^ 1])->GetName(), m_hullMatId[bDrive], pSurfaceMan->GetSurfaceType(m_hullMatId[bDrive])->GetName());
  972. #endif
  973.  
  974.                         for (int n = 0; n < pGeom->nMats; ++n)
  975.                                 pGeom->pMatMapping[n] = m_hullMatId[bDrive];
  976.                 }
  977.         }
  978. }
  979.  
  980. //------------------------------------------------------------------------
  981. void CVehiclePartAnimated::Serialize(TSerialize ser, EEntityAspects aspects)
  982. {
  983.         CVehiclePartBase::Serialize(ser, aspects);
  984. }
  985.  
  986. //------------------------------------------------------------------------
  987. void CVehiclePartAnimated::PostSerialize()
  988. {
  989.         if (m_iRotChangedFrameId)
  990.         {
  991.                 // if necessary, make sure skeleton gets updated in 1st frame
  992.                 m_iRotChangedFrameId = 0;
  993.                 RotationChanged(0);
  994.         }
  995.         else if (gEnv->pSystem->IsSerializingFile() == 2 && m_pVehicle->IsDestroyed())
  996.                 m_serializeForceRotationUpdate = true;
  997. }
  998.  
  999. #if ENABLE_VEHICLE_DEBUG
  1000. void DumpSkeleton(IDefaultSkeleton& rIDefaultSkeleton)
  1001. {
  1002.         for (int i = 0; i < rIDefaultSkeleton.GetJointCount(); ++i)
  1003.         {
  1004.                 const char* name = rIDefaultSkeleton.GetJointNameByID(i);
  1005.                 int parentid = rIDefaultSkeleton.GetJointParentIDByID(i);
  1006.  
  1007.                 if (parentid != -1)
  1008.                         CryLog("joint %i: %s (parent %i)", i, name, parentid);
  1009.                 else
  1010.                         CryLog("joint %i: %s", i, name);
  1011.         }
  1012. }
  1013.  
  1014. //------------------------------------------------------------------------
  1015. void CVehiclePartAnimated::Dump()
  1016. {
  1017.         if (m_pCharInstance)
  1018.         {
  1019.                 CryLog("<%s> pCharInstance:", GetName());
  1020.                 DumpSkeleton(m_pCharInstance->GetIDefaultSkeleton());
  1021.         }
  1022.  
  1023.         if (m_pCharInstanceDestroyed)
  1024.         {
  1025.                 CryLog("<%s> pCharInstanceDestroyed:", GetName());
  1026.                 DumpSkeleton(m_pCharInstanceDestroyed->GetIDefaultSkeleton());
  1027.         }
  1028. }
  1029. #endif
  1030.  
  1031. //------------------------------------------------------------------------
  1032. int CVehiclePartAnimated::GetNextFreeLayer()
  1033. {
  1034.         if (ICharacterInstance* pCharInstance = GetEntity()->GetCharacter(m_slot))
  1035.         {
  1036.                 ISkeletonAnim* pSkeletonAnim = pCharInstance->GetISkeletonAnim();
  1037.                 CRY_ASSERT(pSkeletonAnim);
  1038.  
  1039.                 for (int i = 1; i < ISkeletonAnim::LayerCount; i++)
  1040.                 {
  1041.                         if (pSkeletonAnim->GetNumAnimsInFIFO(i) == 0)
  1042.                                 return i;
  1043.                 }
  1044.         }
  1045.  
  1046.         return -1;
  1047. }
  1048.  
  1049. void CVehiclePartAnimated::GetMemoryUsage(ICrySizer* s) const
  1050. {
  1051.         s->AddObject(this, sizeof(*this));
  1052.         s->AddObject(m_intactStatObjs);
  1053.         s->AddObject(m_jointParts);
  1054.         CVehiclePartBase::GetMemoryUsage(s);
  1055. }
  1056.  
  1057. DEFINE_VEHICLEOBJECT(CVehiclePartAnimated);
  1058.  
downloadVehiclePartAnimated.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