BVB Source Codes

CRYENGINE Show GroundEffect.cpp Source code

Return Download CRYENGINE: download GroundEffect.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 "GroundEffect.h"
  5. #include <CryAction/IMaterialEffects.h>
  6. #include "CryAction.h"
  7.  
  8. const float InvalidRayWorldIntersectDistance = -1.0f;
  9.  
  10. CGroundEffect::CGroundEffect(IEntity* pEntity) :
  11.         m_pEntity(pEntity),
  12.         m_pParticleEffect(NULL),
  13.         m_flags(eGEF_AlignToGround | eGEF_AlignToOcean), m_slot(-1), m_surfaceIdx(0), m_rayWorldIntersectSurfaceIdx(0),
  14.         m_raycastID(0),
  15.         m_active(false),
  16.         m_stopped(false),
  17.         m_validRayWorldIntersect(false),
  18.         m_height(10.0f), m_rayWorldIntersectHeight(0.0f), m_ratio(1.0f),
  19.         m_sizeScale(1.0f), m_sizeGoal(1.0f),
  20.         m_countScale(1.0f),
  21.         m_speedScale(1.0f), m_speedGoal(1.0f),
  22.         m_interpSpeed(5.0f),
  23.         m_maxHeightCountScale(1.0f), m_maxHeightSizeScale(1.0f)
  24. {
  25. }
  26.  
  27. CGroundEffect::~CGroundEffect()
  28. {
  29.         Reset();
  30.  
  31.         if (m_raycastID != 0)
  32.         {
  33.                 CCryAction::GetCryAction()->GetPhysicQueues().GetRayCaster().Cancel(m_raycastID);
  34.                 m_raycastID = 0;
  35.         }
  36. }
  37.  
  38. void CGroundEffect::SetHeight(float height)
  39. {
  40.         m_height = height;
  41.  
  42.         Reset();
  43. }
  44.  
  45. void CGroundEffect::SetHeightScale(float countScale, float sizeScale)
  46. {
  47.         m_maxHeightCountScale = countScale;
  48.         m_maxHeightSizeScale = sizeScale;
  49. }
  50.  
  51. void CGroundEffect::SetBaseScale(float sizeScale, float countScale, float speedScale)
  52. {
  53.         m_sizeGoal = sizeScale;
  54.         m_countScale = countScale;
  55.         m_speedGoal = speedScale;
  56. }
  57.  
  58. void CGroundEffect::SetInterpolation(float speed)
  59. {
  60.         CRY_ASSERT(speed >= 0.f);
  61.  
  62.         m_interpSpeed = speed;
  63. }
  64.  
  65. void CGroundEffect::SetFlags(int flags)
  66. {
  67.         m_flags = flags;
  68.         m_active = false;
  69. }
  70.  
  71. int CGroundEffect::GetFlags() const
  72. {
  73.         return m_flags;
  74. }
  75.  
  76. bool CGroundEffect::SetParticleEffect(const char* pName)
  77. {
  78.         if (pName)
  79.         {
  80.                 m_pParticleEffect = gEnv->pParticleManager->FindEffect(pName);
  81.         }
  82.         else
  83.         {
  84.                 m_pParticleEffect = NULL;
  85.         }
  86.  
  87.         if (m_active)
  88.         {
  89.                 Reset();
  90.         }
  91.  
  92.         m_stopped = false;
  93.  
  94.         if (!m_pParticleEffect || !m_pEntity)
  95.         {
  96.                 return false;
  97.         }
  98.  
  99.         if (DebugOutput())
  100.         {
  101.                 CryLog("[GroundEffect] <%s> set particle effect to (%s)", m_pEntity->GetName(), m_pParticleEffect->GetName());
  102.         }
  103.  
  104.         return true;
  105. }
  106.  
  107. void CGroundEffect::SetInteraction(const char* pName)
  108. {
  109.         m_interaction = pName;
  110. }
  111.  
  112. void CGroundEffect::Update()
  113. {
  114.         if (!m_stopped)
  115.         {
  116.                 bool prevActive = m_active;
  117.  
  118.                 int objTypes = ent_static | ent_terrain | ent_rigid | ent_sleeping_rigid;
  119.  
  120.                 int flags = rwi_colltype_any | rwi_ignore_noncolliding | rwi_stop_at_pierceable;
  121.  
  122.                 Vec3 entityPos(m_pEntity->GetWorldPos());
  123.  
  124.                 float refHeight = (m_flags & eGEF_AlignToGround) ? gEnv->p3DEngine->GetTerrainElevation(entityPos.x, entityPos.y) : 0.0f;
  125.  
  126.                 if (m_flags & eGEF_AlignToOcean)
  127.                 {
  128.                         objTypes |= ent_water;
  129.  
  130.                         refHeight = max(refHeight, gEnv->p3DEngine->GetWaterLevel(&entityPos));
  131.                 }
  132.  
  133.                 if (m_interpSpeed > 0.0f)
  134.                 {
  135.                         float dt = gEnv->pTimer->GetFrameTime();
  136.  
  137.                         Interpolate(m_sizeScale, m_sizeGoal, m_interpSpeed, dt);
  138.  
  139.                         Interpolate(m_speedScale, m_speedGoal, m_interpSpeed, dt);
  140.                 }
  141.                 else
  142.                 {
  143.                         m_sizeScale = m_sizeGoal;
  144.                         m_speedScale = m_speedGoal;
  145.                 }
  146.  
  147.                 Vec3 rayPos(entityPos.x, entityPos.y, entityPos.z + max(0.f, refHeight - entityPos.z + 0.01f));
  148.  
  149.                 if (DeferredRayCasts())
  150.                 {
  151.                         if (m_raycastID == 0)
  152.                         {
  153.                                 PhysSkipList skipList;
  154.  
  155.                                 if (IPhysicalEntity* pPhysics = m_pEntity->GetPhysics())
  156.                                 {
  157.                                         skipList.push_back(pPhysics);
  158.                                 }
  159.  
  160.                                 m_raycastID = CCryAction::GetCryAction()->GetPhysicQueues().GetRayCaster().Queue(RayCastRequest::HighPriority, RayCastRequest(rayPos, Vec3(0.0f, 0.0f, -m_height), objTypes, flags, &skipList[0], skipList.size()), functor(*this, &CGroundEffect::OnRayCastDataReceived));
  161.                         }
  162.                 }
  163.                 else
  164.                 {
  165.                         ray_hit rayhit;
  166.  
  167.                         if (gEnv->pPhysicalWorld->RayWorldIntersection(rayPos, Vec3(0, 0, -m_height), objTypes, flags, &rayhit, 1, m_pEntity->GetPhysics()))
  168.                         {
  169.                                 m_validRayWorldIntersect = true;
  170.                                 m_rayWorldIntersectHeight = rayhit.pt.z;
  171.                                 m_rayWorldIntersectSurfaceIdx = rayhit.surface_idx;
  172.                         }
  173.                         else
  174.                         {
  175.                                 m_validRayWorldIntersect = false;
  176.                         }
  177.                 }
  178.  
  179.                 m_active = m_validRayWorldIntersect;
  180.                 m_ratio = (rayPos.z - m_rayWorldIntersectHeight) / m_height;
  181.  
  182.                 // Has surface changed?
  183.  
  184.                 bool newEffect = false;
  185.  
  186.                 if ((m_rayWorldIntersectSurfaceIdx != m_surfaceIdx) && !m_interaction.empty())
  187.                 {
  188.                         const char* pEffectName = NULL;
  189.  
  190.                         IMaterialEffects* pMaterialEffects = CCryAction::GetCryAction()->GetIMaterialEffects();
  191.  
  192.                         TMFXEffectId effectId = pMaterialEffects->GetEffectId(m_interaction.c_str(), m_rayWorldIntersectSurfaceIdx);
  193.  
  194.                         if (effectId != InvalidEffectId)
  195.                         {
  196.                                 SMFXResourceListPtr pList = pMaterialEffects->GetResources(effectId);
  197.  
  198.                                 if (pList && pList->m_particleList)
  199.                                 {
  200.                                         pEffectName = pList->m_particleList->m_particleParams.name;
  201.                                 }
  202.                         }
  203.  
  204.                         if (DebugOutput())
  205.                         {
  206.                                 const char* pMaterialName = gEnv->p3DEngine->GetMaterialManager()->GetSurfaceType(m_rayWorldIntersectSurfaceIdx)->GetName();
  207.  
  208.                                 CryLog("[GroundEffect] <%s> GetEffectString for matId %i (%s) returned <%s>", m_pEntity->GetName(), m_rayWorldIntersectSurfaceIdx, pMaterialName, pEffectName ? pEffectName : "null");
  209.                         }
  210.  
  211.                         newEffect = SetParticleEffect(pEffectName);
  212.                         m_surfaceIdx = m_rayWorldIntersectSurfaceIdx;
  213.                 }
  214.  
  215.                 // Has status changed?
  216.  
  217.                 if ((m_active != prevActive) || newEffect)
  218.                 {
  219.                         if (m_active && m_pParticleEffect)
  220.                         {
  221.                                 bool prime = (m_flags & eGEF_PrimeEffect) != 0;
  222.  
  223.                                 m_slot = m_pEntity->LoadParticleEmitter(m_slot, m_pParticleEffect, 0, prime);
  224.  
  225.                                 if (DebugOutput())
  226.                                 {
  227.                                         CryLog("[GroundEffect] <%s> effect %s loaded to slot %i", m_pEntity->GetName(), m_pParticleEffect->GetName(), m_slot);
  228.                                 }
  229.                         }
  230.                         else
  231.                         {
  232.                                 if (DebugOutput())
  233.                                 {
  234.                                         CryLog("[GroundEffect] <%s> slot %i freed", m_pEntity->GetName(), m_slot);
  235.                                 }
  236.  
  237.                                 Reset();
  238.                         }
  239.                 }
  240.  
  241.                 if (m_active && (m_flags & eGEF_StickOnGround))
  242.                 {
  243.                         Matrix34 effectTM(Matrix33(IDENTITY), Vec3(entityPos.x, entityPos.y, m_rayWorldIntersectHeight));
  244.  
  245.                         m_pEntity->SetSlotLocalTM(m_slot, m_pEntity->GetWorldTM().GetInverted() * effectTM);
  246.                 }
  247.  
  248.                 if (m_active && m_pParticleEffect)
  249.                 {
  250.                         SpawnParams spawnParams;
  251.  
  252.                         spawnParams.fSizeScale = m_sizeScale;
  253.                         spawnParams.fCountScale = m_countScale;
  254.                         spawnParams.fSpeedScale = m_speedScale;
  255.  
  256.                         spawnParams.fSizeScale *= (1.0f - m_maxHeightSizeScale) * (1.0f - m_ratio) + m_maxHeightSizeScale;
  257.                         spawnParams.fCountScale *= (1.0f - m_maxHeightCountScale) * (1.0f - m_ratio) + m_maxHeightCountScale;
  258.  
  259.                         SetSpawnParams(spawnParams);
  260.                 }
  261.  
  262.                 if (DebugOutput())
  263.                 {
  264.                         Vec3 pos = (m_slot != -1) ? m_pEntity->GetSlotWorldTM(m_slot).GetTranslation() : entityPos;
  265.  
  266.                         const char* pEffectName = m_pParticleEffect ? m_pParticleEffect->GetName() : "";
  267.  
  268.                         IRenderAuxText::DrawLabelF(pos + Vec3(0.0f, 0.0f, 0.5f), 1.25f, "GO [interaction '%s'], effect '%s', active: %i", m_interaction.c_str(), pEffectName, m_active);
  269.  
  270.                         IRenderAuxText::DrawLabelF(pos + Vec3(0.0f, 0.0f, 0.0f), 1.25f, "height %.1f/%.1f, base size/count scale %.2f/%.2f", rayPos.z - m_rayWorldIntersectHeight, m_height, m_sizeScale, m_countScale);
  271.                 }
  272.         }
  273. }
  274.  
  275. void CGroundEffect::Stop(bool stop)
  276. {
  277.         if (stop)
  278.         {
  279.                 Reset();
  280.         }
  281.  
  282.         m_stopped = stop;
  283. }
  284.  
  285. void CGroundEffect::OnRayCastDataReceived(const QueuedRayID& rayID, const RayCastResult& result)
  286. {
  287.         CRY_ASSERT_MESSAGE(rayID == m_raycastID, "CGroundEffect: Received raycast data with mismatching id");
  288.  
  289.         m_validRayWorldIntersect = result.hitCount > 0;
  290.  
  291.         if (m_validRayWorldIntersect)
  292.         {
  293.                 m_rayWorldIntersectHeight = result->pt.z;
  294.                 m_rayWorldIntersectSurfaceIdx = result->surface_idx;
  295.         }
  296.  
  297.         m_raycastID = 0;
  298. }
  299.  
  300. void CGroundEffect::SetSpawnParams(const SpawnParams& params)
  301. {
  302.         if (m_slot < 0)
  303.         {
  304.                 return;
  305.         }
  306.  
  307.         SEntitySlotInfo info;
  308.  
  309.         if (m_pEntity->GetSlotInfo(m_slot, info) && info.pParticleEmitter)
  310.         {
  311.                 info.pParticleEmitter->SetSpawnParams(params);
  312.         }
  313. }
  314.  
  315. void CGroundEffect::Reset()
  316. {
  317.         if (m_slot != -1)
  318.         {
  319.                 if (m_pEntity)
  320.                 {
  321.                         SEntitySlotInfo info;
  322.  
  323.                         if (m_pEntity->GetSlotInfo(m_slot, info) && info.pParticleEmitter)
  324.                         {
  325.                                 info.pParticleEmitter->Activate(false);
  326.                         }
  327.  
  328.                         m_pEntity->FreeSlot(m_slot);
  329.                 }
  330.  
  331.                 m_slot = -1;
  332.         }
  333.  
  334.         m_active = false;
  335. }
  336.  
downloadGroundEffect.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