BVB Source Codes

CRYENGINE Show MissLocationSensor.cpp Source code

Return Download CRYENGINE: download MissLocationSensor.cpp Source code - Download CRYENGINE Source code - Type:.cpp
  1. // Copyright 2001-2016 Crytek GmbH / Crytek Group. All rights reserved.
  2.  
  3. /********************************************************************
  4.    -------------------------------------------------------------------------
  5.    File name:   MissLocationSensor.h
  6.    $Id$
  7.    Description:
  8.  
  9.    -------------------------------------------------------------------------
  10.    History:
  11.    - 29 Mar 2010                         : Alex McCarthy: extracted from AIPlayer.h/cpp
  12.  
  13.  *********************************************************************/
  14. #include "StdAfx.h"
  15. #include "MissLocationSensor.h"
  16. #include "DebugDrawContext.h"
  17.  
  18. CMissLocationSensor::CMissLocationSensor(const CAIActor* owner)
  19.         : m_state(Starting)
  20.         , m_owner(owner)
  21.         , m_lastCollectionLocation(ZERO)
  22. {
  23.         AddDestroyableClass("DestroyableObject");
  24.         AddDestroyableClass("BreakableObject");
  25.         AddDestroyableClass("PressurizedObject");
  26. }
  27.  
  28. CMissLocationSensor::~CMissLocationSensor()
  29. {
  30.         ClearEntities();
  31. }
  32.  
  33. void CMissLocationSensor::Reset()
  34. {
  35.         ClearEntities();
  36.  
  37.         MissLocations().swap(m_working);
  38.         MissLocations().swap(m_locations);
  39.         MissLocations().swap(m_goodies);
  40.  
  41.         m_lastCollectionLocation.zero();
  42. }
  43.  
  44. void CMissLocationSensor::Update(float timeLimit)
  45. {
  46.         while (true)
  47.         {
  48.                 switch (m_state)
  49.                 {
  50.                 case Starting:
  51.                         {
  52.                                 m_updateCount = 0;
  53.  
  54.                                 if ((m_lastCollectionLocation - m_owner->GetPhysicsPos()).len2() > sqr(0.5f))
  55.                                 {
  56.                                         m_state = Collecting;
  57.                                         break;
  58.                                 }
  59.                         }
  60.                         return;
  61.                 case Collecting:
  62.                         {
  63.                                 Collect(ent_static | ent_rigid | ent_sleeping_rigid | ent_independent);
  64.                                 m_state = Filtering;
  65.                         }
  66.                         return;
  67.                 case Filtering:
  68.                         {
  69.                                 if (Filter(timeLimit))
  70.                                 {
  71.                                         m_state = Finishing;
  72.                                         break;
  73.                                 }
  74.                         }
  75.                         return;
  76.                 case Finishing:
  77.                         {
  78.                                 m_working.swap(m_locations);
  79.                                 m_working.resize(0);
  80.                                 m_state = Starting;
  81.                         }
  82.                         return;
  83.                 default:
  84.                         {
  85.                                 assert(0);
  86.                                 return;
  87.                         }
  88.                 }
  89.         }
  90.  
  91.         ++m_updateCount;
  92. }
  93.  
  94. void CMissLocationSensor::Collect(int types)
  95. {
  96.         FUNCTION_PROFILER(gEnv->pSystem, PROFILE_AI);
  97.  
  98.         const float boxHalfSize = gAIEnv.CVars.CoolMissesBoxSize * 0.5f;
  99.         const float boxHeight = gAIEnv.CVars.CoolMissesBoxHeight;
  100.  
  101.         const Vec3& feet = m_owner->GetPhysicsPos();
  102.         const Vec3& dir = m_owner->GetViewDir();
  103.  
  104.         Vec3 pos = feet + Vec3(0.0f, 0.0f, -0.25f) + dir * boxHalfSize * 0.5f;
  105.         Vec3 min(pos.x - boxHalfSize, pos.y - boxHalfSize, pos.z);
  106.         Vec3 max(pos.x + boxHalfSize, pos.y + boxHalfSize, pos.z + boxHeight);
  107.  
  108.         types |= ent_addref_results;
  109.  
  110.         ClearEntities();
  111.         m_entities.resize(MaxCollectedCount);
  112.  
  113.         IPhysicalEntity** entities = &m_entities.front();
  114.         size_t entityCount = gEnv->pPhysicalWorld->GetEntitiesInBox(min, max, entities, types, MaxCollectedCount);
  115.  
  116.         if (entityCount > MaxCollectedCount)
  117.         {
  118.                 assert(entities != &m_entities.front());
  119.  
  120.                 for (size_t i = 0; i < entityCount; ++i)
  121.                 {
  122.                         if (entities[i])
  123.                                 entities[i]->Release();
  124.                 }
  125.  
  126.                 m_entities.resize(0);
  127.         }
  128.         else
  129.                 m_entities.resize(entityCount);
  130.  
  131.         m_lastCollectionLocation = feet;
  132. }
  133.  
  134. bool CMissLocationSensor::Filter(float timeLimit)
  135. {
  136.         if (m_entities.empty())
  137.                 return true;
  138.  
  139.         CTimeValue now = gEnv->pTimer->GetAsyncTime();
  140.         CTimeValue start = now;
  141.         CTimeValue endTime = now + CTimeValue(timeLimit);
  142.  
  143.         float MaxMass = gAIEnv.CVars.CoolMissesMaxLightweightEntityMass;
  144.  
  145.         pe_params_part pp;
  146.         pe_status_dynamics dyn;
  147.         pe_params_rope prope;
  148.         pe_status_pos spos;
  149.         pe_params_structural_joint sjp;
  150.         pe_status_rope srope;
  151.  
  152.         do
  153.         {
  154.                 IPhysicalEntity* entity = m_entities.front();
  155.                 std::swap(m_entities.front(), m_entities.back());
  156.                 m_entities.pop_back();
  157.  
  158.                 bool destroyable = false;
  159.                 bool lightweight = false;
  160.  
  161.                 if (IEntity* ientity = gEnv->pEntitySystem->GetEntityFromPhysics(entity))
  162.                 {
  163.                         IEntityClass* entityClass = ientity->GetClass();
  164.                         for (uint c = 0; c < m_destroyableEntityClasses.size(); ++c)
  165.                         {
  166.                                 if (entityClass == m_destroyableEntityClasses[c])
  167.                                 {
  168.                                         destroyable = true;
  169.                                         break;
  170.                                 }
  171.                         }
  172.  
  173.                         MARK_UNUSED dyn.partid, dyn.ipart;
  174.  
  175.                         if (entity->GetStatus(&dyn) && (dyn.mass > 0.0001f) && (dyn.mass <= MaxMass))
  176.                                 lightweight = true;
  177.                 }
  178.  
  179.                 // Check for idmatBreakable or geom_manually_breakable
  180.                 // If the entity was previous known to be destroyable add all it's physical parts
  181.                 if (entity)
  182.                 {
  183.                         Matrix34 worldTM;
  184.                         Matrix34 partTM;
  185.  
  186.                         spos.ipart = -1;
  187.                         spos.partid = -1;
  188.                         spos.pMtx3x4 = &worldTM;
  189.  
  190.                         if (entity->GetStatus(&spos))
  191.                         {
  192.                                 {
  193.                                         pp.pMtx3x4 = &partTM;
  194.                                         pp.ipart = 0;
  195.                                         MARK_UNUSED pp.partid;
  196.  
  197.                                         uint32 partCount = 0;
  198.                                         while (entity->GetParams(&pp))
  199.                                         {
  200.                                                 MARK_UNUSED pp.partid;
  201.                                                 pp.ipart = ++partCount;
  202.  
  203.                                                 if (!pp.pPhysGeom || !pp.pPhysGeom->pGeom)
  204.                                                         continue;
  205.  
  206.                                                 primitives::box box;
  207.                                                 pp.pPhysGeom->pGeom->GetBBox(&box);
  208.  
  209.                                                 Vec3 pos = (worldTM * partTM).TransformPoint(box.center);
  210.  
  211.                                                 if (!destroyable && !lightweight)
  212.                                                 {
  213.                                                         if (pp.flagsOR & geom_manually_breakable)
  214.                                                         {
  215.                                                                 m_working.push_back(
  216.                                                                   MissLocation(pos, MissLocation::ManuallyBreakable));
  217.                                                         }
  218.  
  219.                                                         if (pp.idmatBreakable >= 0)
  220.                                                         {
  221.                                                                 m_working.push_back(
  222.                                                                   MissLocation(pos, MissLocation::MatBreakable));
  223.                                                         }
  224.  
  225.                                                         if (pp.idSkeleton >= 0)
  226.                                                         {
  227.                                                                 m_working.push_back(
  228.                                                                   MissLocation(pos, MissLocation::Deformable));
  229.                                                         }
  230.                                                 }
  231.                                                 else
  232.                                                 {
  233.                                                         m_working.push_back(
  234.                                                           MissLocation(pos, lightweight ? MissLocation::Lightweight : MissLocation::Destroyable));
  235.                                                 }
  236.                                         }
  237.                                 }
  238.  
  239.                                 // Check if entity contains structural joints
  240.                                 // Track which parts are connected by joints
  241.                                 // Add those parts as good miss locations
  242.                                 {
  243.                                         uint64 jointConnectedParts = 0;
  244.                                         uint32 jointCount = 0;
  245.                                         sjp.idx = 0;
  246.  
  247.                                         while (entity->GetParams(&sjp))
  248.                                         {
  249.                                                 ++jointCount;
  250.                                                 if (sjp.bBreakable && !sjp.bBroken)
  251.                                                 {
  252.                                                         if ((sjp.partid[0] > -1) && (sjp.partid[0] < 64))
  253.                                                                 jointConnectedParts |= 1ll << sjp.partid[0];
  254.  
  255.                                                         if ((sjp.partid[1] > -1) && (sjp.partid[1] < 64))
  256.                                                                 jointConnectedParts |= 1ll << sjp.partid[1];
  257.                                                 }
  258.  
  259.                                                 sjp.idx = jointCount;
  260.                                                 MARK_UNUSED sjp.id;
  261.                                         }
  262.  
  263.                                         if (jointConnectedParts)
  264.                                         {
  265.                                                 for (uint32 p = 0; p < 64; ++p)
  266.                                                 {
  267.                                                         if (jointConnectedParts & (1ll << p))
  268.                                                         {
  269.                                                                 spos.ipart = -1;
  270.                                                                 spos.partid = p;
  271.                                                                 spos.pMtx3x4 = &partTM;
  272.  
  273.                                                                 if (!entity->GetStatus(&spos))
  274.                                                                         continue;
  275.  
  276.                                                                 if (!spos.pGeom)
  277.                                                                         continue;
  278.  
  279.                                                                 primitives::box box;
  280.                                                                 spos.pGeom->GetBBox(&box);
  281.  
  282.                                                                 m_working.push_back(
  283.                                                                   MissLocation((worldTM * partTM).TransformPoint(box.center), MissLocation::JointStructure));
  284.                                                         }
  285.                                                 }
  286.                                         }
  287.                                 }
  288.  
  289.                                 // Add rope vertices
  290.                                 if (entity->GetStatus(&srope) && entity->GetParams(&prope))
  291.                                 {
  292.                                         if (prope.pEntTiedTo[0] && prope.pEntTiedTo[1])
  293.                                         {
  294.                                                 uint32 pointCount = std::max(srope.nVtx, (srope.nSegments + 1)); // use the version with the most detail
  295.                                                 if ((pointCount > 0) && (pointCount < 128))
  296.                                                 {
  297.                                                         Vec3 vertices[128];
  298.                                                         uint32 step = 1;
  299.  
  300.                                                         if (pointCount > MaxRopeVertexCount)
  301.                                                                 step = pointCount / MaxRopeVertexCount;
  302.  
  303.                                                         if (srope.nVtx >= (srope.nSegments + 1))
  304.                                                                 srope.pVtx = &vertices[0];
  305.                                                         else
  306.                                                                 srope.pPoints = &vertices[0];
  307.  
  308.                                                         entity->GetStatus(&srope);
  309.  
  310.                                                         for (uint i = 0; i < pointCount; i += step)
  311.                                                                 m_working.push_back(MissLocation(vertices[i], MissLocation::Rope));
  312.                                                 }
  313.                                         }
  314.                                 }
  315.                         }
  316.  
  317.                         entity->Release();
  318.                 }
  319.  
  320.                 now = gEnv->pTimer->GetAsyncTime();
  321.  
  322.                 if (m_entities.empty())
  323.                         return true;
  324.  
  325.         }
  326.         while (now < endTime);
  327.  
  328.         return false;
  329. }
  330.  
  331. bool CMissLocationSensor::GetLocation(CAIObject* target, const Vec3& shootPos, const Vec3& shootDir, float maxAngle, Vec3& pos)
  332. {
  333.         FUNCTION_PROFILER(gEnv->pSystem, PROFILE_AI);
  334.  
  335.         if (m_locations.empty())
  336.                 return false;
  337.  
  338.         m_goodies.resize(0);
  339.  
  340.         float maxAngleCos = cos_tpl(maxAngle);
  341.         float angleIntervalInv = 1.0f / (1.0f - maxAngleCos);
  342.  
  343.         const Vec3 targetViewDir = target->GetViewDir();
  344.         const Vec3 targetLocation = target->GetPos();
  345.  
  346.         uint32 maxConsidered = std::min<uint32>(MaxConsiderCount, m_locations.size());
  347.  
  348.         MissLocations::iterator it = m_locations.begin();
  349.         MissLocations::iterator end = m_locations.end();
  350.  
  351.         for (; maxConsidered && (it != end); ++it)
  352.         {
  353.                 MissLocation& location = *it;
  354.  
  355.                 Vec3 dir(location.position - shootPos);
  356.                 dir.Normalize();
  357.  
  358.                 float angleCos = dir.dot(shootDir);
  359.                 if (angleCos <= maxAngleCos)
  360.                         continue;
  361.  
  362.                 float extraScore = min(1.0f + (location.position - targetLocation).dot(targetViewDir), 1.0f);
  363.                 //if ((location.position - targetLocation).dot(targetViewDir) <= 0.0f)
  364.                 //continue;
  365.  
  366.                 // Ignore anything that would hit the player
  367.                 if (IPhysicalEntity* ownerPhysics = m_owner->GetPhysics())
  368.                 {
  369.                         pe_status_pos ppos;
  370.                         if (ownerPhysics->GetStatus(&ppos))
  371.                         {
  372.                                 AABB player(ppos.BBox[0] - ppos.pos, ppos.BBox[1] + ppos.pos);
  373.                                 player.Expand(Vec3(0.35f));
  374.  
  375.                                 Lineseg lineOfFire;
  376.                                 lineOfFire.start = shootPos;
  377.  
  378.                                 uint32 locationCount = m_goodies.size();
  379.                                 for (uint32 i = 0; (i < locationCount) && (i < MaxRandomPool); ++i)
  380.                                 {
  381.                                         lineOfFire.end = m_goodies[i].position;
  382.  
  383.                                         if (Overlap::Lineseg_AABB(lineOfFire, player))
  384.                                                 continue;
  385.                                 }
  386.                         }
  387.                 }
  388.  
  389.                 float typeScore = 0.0f;
  390.                 switch (location.type)
  391.                 {
  392.                 case MissLocation::Lightweight:
  393.                         typeScore = 1.0f;
  394.                         break;
  395.                 case MissLocation::Destroyable:
  396.                         typeScore = 0.95f;
  397.                         break;
  398.                 case MissLocation::Rope:
  399.                         typeScore = 0.90f;
  400.                         break;
  401.                 case MissLocation::ManuallyBreakable:
  402.                         typeScore = 0.85f;
  403.                         break;
  404.                 case MissLocation::JointStructure:
  405.                         typeScore = 0.75f;
  406.                         break;
  407.                 case MissLocation::Deformable:
  408.                         typeScore = 0.65f;
  409.                         break;
  410.                 case MissLocation::MatBreakable:
  411.                         typeScore = 0.5f;
  412.                         break;
  413.                 case MissLocation::Unbreakable:
  414.                 default:
  415.                         break;
  416.                 }
  417.  
  418.                 float angleScore = (angleCos - maxAngleCos) * angleIntervalInv;
  419.  
  420.                 m_goodies.push_back(location);
  421.                 m_goodies.back().score = (angleScore * 0.4f) + (typeScore * 0.6f);
  422.                 m_goodies.back().score *= extraScore;
  423.                 --maxConsidered;
  424.         }
  425.  
  426.         size_t goodiesCount = std::min<size_t>(MaxRandomPool, m_goodies.size());
  427.         std::partial_sort(m_goodies.begin(), m_goodies.begin() + goodiesCount, m_goodies.end());
  428.  
  429.         if (m_goodies.empty())
  430.                 return false;
  431.  
  432.         const MissLocation& location = m_goodies[cry_random((size_t)0, goodiesCount - 1)];
  433.  
  434. #ifdef CRYAISYSTEM_DEBUG
  435.         if (gAIEnv.CVars.DebugDrawCoolMisses)
  436.         {
  437.                 GetAISystem()->AddDebugCone(location.position + Vec3(0.0f, 0.0f, 0.75f), Vec3(0.0f, 0.0f, -1.0f), 0.225f, 0.35f,
  438.                                             Col_Green, 0.5f);
  439.         }
  440. #endif
  441.  
  442.         pos = location.position;
  443.  
  444.         return true;
  445. }
  446.  
  447. void CMissLocationSensor::DebugDraw()
  448. {
  449. #ifdef CRYAISYSTEM_DEBUG
  450.         if (gAIEnv.CVars.DebugDrawCoolMisses)
  451.         {
  452.                 CDebugDrawContext dc;
  453.  
  454.                 for (size_t i = 0; i < m_locations.size(); ++i)
  455.                 {
  456.                         const MissLocation& location = m_locations[i];
  457.  
  458.                         dc->DrawSphere(location.position + Vec3(0.0f, 0.0f, 0.3f), 0.2f, Col_Sienna);
  459.                 }
  460.         }
  461. #endif
  462. }
  463.  
  464. void CMissLocationSensor::AddDestroyableClass(const char* className)
  465. {
  466.         if (IEntityClass* entityClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass(className))
  467.                 stl::push_back_unique(m_destroyableEntityClasses, entityClass);
  468. }
  469.  
  470. void CMissLocationSensor::ResetDestroyableClasses()
  471. {
  472.         m_destroyableEntityClasses.clear();
  473. }
  474.  
  475. void CMissLocationSensor::ClearEntities()
  476. {
  477.         MissEntities::iterator it = m_entities.begin();
  478.         MissEntities::iterator end = m_entities.end();
  479.  
  480.         for (; it != end; ++it)
  481.         {
  482.                 if ((*it))
  483.                 {
  484.                         (*it)->Release();
  485.                 }
  486.         }
  487.  
  488.         m_entities.clear();
  489. }
  490.  
downloadMissLocationSensor.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