BVB Source Codes

CRYENGINE Show EntityTags.cpp Source code

Return Download CRYENGINE: download EntityTags.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 "PersistantDebug.h"
  5. #include "CryAction.h"
  6. #include <CryRenderer/IRenderAuxGeom.h>
  7. #include <IUIDraw.h>
  8.  
  9. const char* CPersistantDebug::entityTagsContext = "PersistantDebugEntities";
  10. const float CPersistantDebug::kUnlimitedTime = -1.0f;
  11.  
  12. void CPersistantDebug::AddEntityTag(const SEntityTagParams& params, const char* tagContext)
  13. {
  14.         // Create tag
  15.         SEntityTag tag;
  16.         tag.params = params;
  17.         tag.params.column = max(1, tag.params.column);
  18.         tag.params.fadeTime = max(0.f, tag.params.fadeTime);
  19.         if (tagContext != NULL && *tagContext != '\0')
  20.                 tag.params.tagContext = tagContext;
  21.         tag.totalTime = tag.params.visibleTime < 0 ? kUnlimitedTime : tag.params.visibleTime + tag.params.fadeTime;
  22.         tag.totalFadeTime = tag.params.fadeTime;
  23.         tag.vScreenPos.zero();
  24.  
  25.         SObj* obj = FindObj(params.entity);
  26.         if (!obj)
  27.         {
  28.                 // Create new object to push back
  29.                 SObj sobj;
  30.                 sobj.obj = eOT_EntityTag;
  31.                 sobj.entityId = params.entity;
  32.                 sobj.entityHeight = 0.f;
  33.                 sobj.timeRemaining = tag.totalTime;
  34.                 sobj.totalTime = tag.totalTime;
  35.                 sobj.columns.resize(params.column);
  36.                 AddToTagList(sobj.tags, tag);
  37.  
  38.                 m_objects[entityTagsContext].push_back(sobj);
  39.         }
  40.         else
  41.         {
  42.                 obj->timeRemaining = tag.totalTime < 0 ? kUnlimitedTime : max(obj->timeRemaining, tag.totalTime);
  43.                 obj->totalTime = obj->timeRemaining;
  44.                 int size = max(int(obj->columns.size()), params.column);
  45.                 if (obj->columns.size() < size)
  46.                         obj->columns.resize(size);
  47.  
  48.                 AddToTagList(obj->tags, tag);
  49.         }
  50.  
  51.         if (m_pETLog->GetIVal() > 0)
  52.         {
  53.                 IEntity* ent = gEnv->pEntitySystem->GetEntity(params.entity);
  54.                 if (ent)
  55.                 {
  56.                         CryLog("[Entity Tag] %s added tag: %s", ent->GetName(), params.text.c_str());
  57.  
  58.                         if (m_pETLog->GetIVal() > 1)
  59.                         {
  60.                                 char text[256];
  61.                                 cry_sprintf(text, "[Entity Tag] %s", params.text.c_str());
  62.                                 gEnv->pAISystem->Record(ent->GetAI(), IAIRecordable::E_NONE, text);
  63.                         }
  64.                 }
  65.         }
  66. }
  67.  
  68. void CPersistantDebug::ClearEntityTags(EntityId entityId)
  69. {
  70.         SObj* obj = FindObj(entityId);
  71.         if (obj)
  72.                 obj->tags.clear();
  73. }
  74.  
  75. void CPersistantDebug::ClearStaticTag(EntityId entityId, const char* staticId)
  76. {
  77.         SObj* obj = FindObj(entityId);
  78.         if (obj && staticId)
  79.         {
  80.                 for (TListTag::iterator iterList = obj->tags.begin(); iterList != obj->tags.end(); ++iterList)
  81.                 {
  82.                         if (iterList->params.staticId.compare(staticId) == 0)
  83.                         {
  84.                                 obj->tags.erase(iterList);
  85.                                 break;
  86.                         }
  87.                 }
  88.         }
  89. }
  90.  
  91. void CPersistantDebug::ClearTagContext(const char* tagContext)
  92. {
  93.         if (!tagContext)
  94.                 return;
  95.  
  96.         MapListObj::iterator it = m_objects.find(entityTagsContext);
  97.         if (it != m_objects.end())
  98.         {
  99.                 for (ListObj::iterator iterList = it->second.begin(); iterList != it->second.end(); ++iterList)
  100.                         ClearTagContext(tagContext, iterList->entityId);
  101.         }
  102. }
  103.  
  104. void CPersistantDebug::ClearTagContext(const char* tagContext, EntityId entityId)
  105. {
  106.         if (!tagContext)
  107.                 return;
  108.  
  109.         SObj* obj = FindObj(entityId);
  110.         if (obj)
  111.         {
  112.                 for (TListTag::iterator iterList = obj->tags.begin(); iterList != obj->tags.end(); )
  113.                 {
  114.                         if (iterList->params.tagContext.compare(tagContext) != 0)
  115.                         {
  116.                                 ++iterList;
  117.                         }
  118.                         else
  119.                         {
  120.                                 TListTag::iterator nextIter = obj->tags.erase(iterList);
  121.                                 iterList = nextIter;
  122.                         }
  123.                 }
  124.         }
  125. }
  126.  
  127. void CPersistantDebug::UpdateTags(float frameTime, SObj& obj, bool doFirstPass)
  128. {
  129.         if (!doFirstPass)
  130.         {
  131.                 // Every update calls itself recursively first to calculate the widths of each column
  132.                 // for multicolumn mode. Not the prettiest thing, but it's the best idea I've got so far!
  133.                 UpdateTags(frameTime, obj, true);
  134.                 frameTime = 0.f;
  135.  
  136.                 for (int i = 0; i < obj.columns.size(); ++i)
  137.                         obj.columns[i].height = 0.f;
  138.         }
  139.  
  140.         IFFont* pFont = gEnv->pCryFont->GetFont("default");
  141.         assert(pFont);
  142.         STextDrawContext ctx;
  143.         ctx.SetSizeIn800x600(false);
  144.         ctx.SetProportional(true);
  145.  
  146.         for (TListTag::iterator iterList = obj.tags.begin(); iterList != obj.tags.end(); ++iterList)
  147.         {
  148.                 if (iterList->vScreenPos.IsZero())
  149.                         continue;
  150.  
  151.                 float tagMaxDist = iterList->params.viewDistance;
  152.                 float fontSize = iterList->params.size * m_pETFontSizeMultiplier->GetFVal();
  153.  
  154.                 // Calculate size of text on screen (so we can place it properly)
  155.                 ctx.SetSize(Vec2(12 * fontSize, 12 * fontSize));
  156.                 Vec2 textBoxSize = pFont->GetTextSize(iterList->params.text.c_str(), true, ctx);
  157.  
  158.                 if (doFirstPass)
  159.                 {
  160.                         int pos(iterList->params.column - 1);
  161.                         obj.columns[pos].width = max(obj.columns[pos].width, textBoxSize.x + 15.f);
  162.                 }
  163.                 else
  164.                 {
  165.                         // Determine position
  166.                         SColumn& column = obj.columns[iterList->params.column - 1];
  167.                         Vec3 screenPos(iterList->vScreenPos);
  168.                         screenPos.x = screenPos.x * 0.01f * gEnv->pRenderer->GetWidth();
  169.                         screenPos.y = screenPos.y * 0.01f * gEnv->pRenderer->GetHeight() - textBoxSize.y - column.height;
  170.                         column.height += textBoxSize.y;
  171.  
  172.                         // Adjust X value for multi-columns
  173.                         if (obj.columns.size() > 1)
  174.                         {
  175.                                 int centerLine = obj.columns.size() / 2;
  176.                                 if (iterList->params.column <= centerLine)
  177.                                         for (int i = iterList->params.column - 1; i < centerLine; ++i)
  178.                                                 screenPos.x -= obj.columns[i].width;
  179.                                 else
  180.                                         for (int i = centerLine; i < iterList->params.column - 1; ++i)
  181.                                                 screenPos.x += obj.columns[i].width;
  182.  
  183.                                 if (obj.columns.size() % 2 != 0)
  184.                                         screenPos.x -= textBoxSize.x * 0.5f;
  185.                         }
  186.                         else
  187.                         {
  188.                                 screenPos.x -= textBoxSize.x * 0.5f;
  189.                         }
  190.  
  191.                         // Determine color
  192.                         ColorF clr = iterList->params.color;
  193.                         if (1 == m_pETColorOverrideEnable->GetIVal())
  194.                         {
  195.                                 clr.r = max(0.f, min(1.f, m_pETColorOverrideR->GetFVal()));
  196.                                 clr.g = max(0.f, min(1.f, m_pETColorOverrideG->GetFVal()));
  197.                                 clr.b = max(0.f, min(1.f, m_pETColorOverrideB->GetFVal()));
  198.                         }
  199.                         clr.a *= iterList->params.fadeTime / iterList->totalFadeTime; // Apply fade out time to alpha
  200.  
  201.                         float clrAry[4] = { clr.r, clr.g, clr.b, clr.a };
  202.                         IRenderAuxText::Draw2dLabel(screenPos.x, screenPos.y, fontSize, clrAry, true, "%s", iterList->params.text.c_str());
  203.                 }
  204.         }
  205. }
  206.  
  207. void CPersistantDebug::PostUpdateTags(float frameTime, SObj& obj)
  208. {
  209.         Vec3 baseCenterPos;
  210.         float heightAboveBase(0.f);
  211.         if (!GetEntityParams(obj.entityId, baseCenterPos, heightAboveBase))
  212.                 return;
  213.  
  214.         // Check if entity is outside of global distance maximum or behind camera
  215.         CCamera& cam = GetISystem()->GetViewCamera();
  216.         float distFromCam = (cam.GetPosition() - baseCenterPos).GetLength();
  217.         float maxDist = m_pETMaxDisplayDistance->GetFVal();
  218.         bool isOutOfRange(maxDist >= 0.f && distFromCam > maxDist);
  219.         bool isBehindCamera(cam.GetViewdir().Dot(baseCenterPos - cam.GetPosition()) <= 0);
  220.  
  221.         heightAboveBase = max(obj.entityHeight, heightAboveBase); // never let stored entity height get smaller
  222.         obj.entityHeight = heightAboveBase;                       // update stored position
  223.         heightAboveBase += 0.2f;                                  // make tags start a little above the entity
  224.  
  225.         std::vector<TListTag::iterator> toClear;
  226.         for (TListTag::iterator iterList = obj.tags.begin(); iterList != obj.tags.end(); ++iterList)
  227.         {
  228.                 iterList->vScreenPos.zero();
  229.  
  230.                 if (iterList->params.visibleTime != kUnlimitedTime)
  231.                 {
  232.                         if (iterList->params.visibleTime > 0.0f)
  233.                         {
  234.                                 iterList->params.visibleTime -= frameTime;
  235.                                 if (iterList->params.visibleTime < 0.0f)
  236.                                 {
  237.                                         // If visibleTime has hit 0, make sure any spillover gets applied to fade time
  238.                                         iterList->params.fadeTime += iterList->params.visibleTime;
  239.                                 }
  240.                         }
  241.                         else
  242.                         {
  243.                                 iterList->params.fadeTime -= frameTime;
  244.                         }
  245.                 }
  246.  
  247.                 if (iterList->params.fadeTime < 0.0f)
  248.                 {
  249.                         toClear.push_back(iterList);
  250.                 }
  251.                 else
  252.                 {
  253.                         if (isOutOfRange || isBehindCamera || 1 == m_pETHideAll->GetIVal() ||
  254.                             (1 == m_pETHideBehaviour->GetIVal() && iterList->params.tagContext.compareNoCase("behaviour") == 0) ||
  255.                             (1 == m_pETHideReadability->GetIVal() && iterList->params.tagContext.compareNoCase("readability") == 0) ||
  256.                             (1 == m_pETHideAIDebug->GetIVal() && iterList->params.tagContext.compareNoCase("aidebug") == 0) ||
  257.                             (1 == m_pETHideFlowgraph->GetIVal() && iterList->params.tagContext.compareNoCase("flowgraph") == 0) ||
  258.                             (1 == m_pETHideScriptBind->GetIVal() && iterList->params.tagContext.compareNoCase("scriptbind") == 0))
  259.                                 continue;
  260.  
  261.                         // Check if entity is outside of max distance for this tag
  262.                         float tagMaxDist = iterList->params.viewDistance;
  263.                         if (tagMaxDist >= 0.f && distFromCam > tagMaxDist)
  264.                                 continue;
  265.  
  266.                         float distanceFix = distFromCam * 0.015f; // this constant found through trial and error
  267.                         float riseAmount(0.0f);
  268.                         if (iterList->params.staticId == "")
  269.                                 riseAmount = 2.0f * distanceFix * (1 - (obj.timeRemaining / obj.totalTime));
  270.  
  271.                         Vec3 tagPos(baseCenterPos.x, baseCenterPos.y, baseCenterPos.z + heightAboveBase + riseAmount);
  272.                         Vec3 screenPos(ZERO);
  273.                         gEnv->pRenderer->ProjectToScreen(tagPos.x, tagPos.y, tagPos.z, &screenPos.x, &screenPos.y, &screenPos.z);
  274.  
  275.                         iterList->vScreenPos = screenPos;
  276.                 }
  277.         }
  278.         while (!toClear.empty())
  279.         {
  280.                 obj.tags.erase(toClear.back());
  281.                 toClear.pop_back();
  282.         }
  283. }
  284.  
  285. CPersistantDebug::SObj* CPersistantDebug::FindObj(EntityId entity)
  286. {
  287.         MapListObj::iterator it = m_objects.find(entityTagsContext);
  288.         if (it != m_objects.end())
  289.         {
  290.                 ListObj::iterator it2 = std::find_if(it->second.begin(), it->second.end(), SObjFinder(entity));
  291.                 if (it2 != it->second.end())
  292.                         return &*it2;
  293.         }
  294.  
  295.         return NULL;
  296. }
  297.  
  298. void CPersistantDebug::AddToTagList(TListTag& tagList, SEntityTag& tag)
  299. {
  300.         if (tag.params.staticId != "")
  301.         {
  302.                 // Special handling for static tags
  303.  
  304.                 TListTag::iterator iter = tagList.begin();
  305.                 while (iter != tagList.end() &&
  306.                        iter->params.staticId != "" &&
  307.                        iter->params.staticId != tag.params.staticId)
  308.                         ++iter;
  309.  
  310.                 if (iter != tagList.end() && iter->params.staticId == tag.params.staticId)
  311.                 {
  312.                         // Replace this tag with new static tag
  313.                         *iter = tag;
  314.                 }
  315.                 else
  316.                 {
  317.                         // Insert as last static tag on list
  318.                         tagList.insert(iter, tag);
  319.                 }
  320.         }
  321.         else
  322.         {
  323.                 TListTag::iterator iter = tagList.begin();
  324.                 while (iter != tagList.end() && iter->params.staticId != "")
  325.                         //(iter->totalTime > tag.totalTime || iter->params.staticId != ""))
  326.                         ++iter;
  327.  
  328.                 tagList.insert(iter, tag);
  329.         }
  330. }
  331.  
  332. bool CPersistantDebug::GetEntityParams(EntityId entityId, Vec3& baseCenterPos, float& height)
  333. {
  334.         IEntity* ent = gEnv->pEntitySystem->GetEntity(entityId);
  335.         if (ent)
  336.         {
  337.                 AABB bounds;
  338.                 ent->GetWorldBounds(bounds);
  339.                 baseCenterPos = bounds.GetCenter();
  340.                 baseCenterPos.z = bounds.min.z;
  341.                 height = bounds.GetSize().z;
  342.                 return true;
  343.         }
  344.  
  345.         return false;
  346. }
  347.  
downloadEntityTags.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