LCOV - code coverage report
Current view: top level - source/tools/atlas/GameInterface - ActorViewer.cpp (source / functions) Hit Total Coverage
Test: 0 A.D. test coverage report Lines: 1 260 0.4 %
Date: 2023-01-19 00:18:29 Functions: 2 31 6.5 %

          Line data    Source code
       1             : /* Copyright (C) 2022 Wildfire Games.
       2             :  * This file is part of 0 A.D.
       3             :  *
       4             :  * 0 A.D. is free software: you can redistribute it and/or modify
       5             :  * it under the terms of the GNU General Public License as published by
       6             :  * the Free Software Foundation, either version 2 of the License, or
       7             :  * (at your option) any later version.
       8             :  *
       9             :  * 0 A.D. is distributed in the hope that it will be useful,
      10             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      11             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12             :  * GNU General Public License for more details.
      13             :  *
      14             :  * You should have received a copy of the GNU General Public License
      15             :  * along with 0 A.D.  If not, see <http://www.gnu.org/licenses/>.
      16             :  */
      17             : 
      18             : #include "precompiled.h"
      19             : 
      20             : #include "ActorViewer.h"
      21             : 
      22             : #include "View.h"
      23             : 
      24             : #include "graphics/Canvas2D.h"
      25             : #include "graphics/ColladaManager.h"
      26             : #include "graphics/LOSTexture.h"
      27             : #include "graphics/MiniMapTexture.h"
      28             : #include "graphics/Model.h"
      29             : #include "graphics/ModelDef.h"
      30             : #include "graphics/ObjectManager.h"
      31             : #include "graphics/ParticleManager.h"
      32             : #include "graphics/Patch.h"
      33             : #include "graphics/SkeletonAnimManager.h"
      34             : #include "graphics/Terrain.h"
      35             : #include "graphics/TerrainTextureEntry.h"
      36             : #include "graphics/TerrainTextureManager.h"
      37             : #include "graphics/TerritoryTexture.h"
      38             : #include "graphics/Unit.h"
      39             : #include "graphics/UnitManager.h"
      40             : #include "graphics/Overlay.h"
      41             : #include "maths/MathUtil.h"
      42             : #include "ps/Filesystem.h"
      43             : #include "ps/CLogger.h"
      44             : #include "ps/GameSetup/Config.h"
      45             : #include "ps/ProfileViewer.h"
      46             : #include "ps/VideoMode.h"
      47             : #include "renderer/backend/IDevice.h"
      48             : #include "renderer/backend/IDeviceCommandContext.h"
      49             : #include "renderer/Renderer.h"
      50             : #include "renderer/RenderingOptions.h"
      51             : #include "renderer/Scene.h"
      52             : #include "renderer/SceneRenderer.h"
      53             : #include "renderer/SkyManager.h"
      54             : #include "renderer/WaterManager.h"
      55             : #include "scriptinterface/ScriptContext.h"
      56             : #include "simulation2/Simulation2.h"
      57             : #include "simulation2/components/ICmpAttack.h"
      58             : #include "simulation2/components/ICmpOwnership.h"
      59             : #include "simulation2/components/ICmpPosition.h"
      60             : #include "simulation2/components/ICmpRangeManager.h"
      61             : #include "simulation2/components/ICmpTerrain.h"
      62             : #include "simulation2/components/ICmpUnitMotion.h"
      63             : #include "simulation2/components/ICmpVisual.h"
      64             : #include "simulation2/components/ICmpWaterManager.h"
      65             : #include "simulation2/helpers/Render.h"
      66             : 
      67             : extern int g_xres, g_yres;
      68             : 
      69           0 : struct ActorViewerImpl : public Scene
      70             : {
      71             :     NONCOPYABLE(ActorViewerImpl);
      72             : public:
      73           0 :     ActorViewerImpl() :
      74             :         Entity(INVALID_ENTITY),
      75             :         Terrain(),
      76             :         ColladaManager(g_VFS),
      77             :         MeshManager(ColladaManager),
      78             :         SkeletonAnimManager(ColladaManager),
      79             :         UnitManager(),
      80           0 :         Simulation2(&UnitManager, g_ScriptContext, &Terrain),
      81             :         ObjectManager(MeshManager, SkeletonAnimManager, Simulation2),
      82             :         LOSTexture(Simulation2),
      83             :         TerritoryTexture(Simulation2),
      84           0 :         MiniMapTexture(Simulation2)
      85             :     {
      86           0 :         UnitManager.SetObjectManager(ObjectManager);
      87           0 :     }
      88             : 
      89             :     entity_id_t Entity;
      90             :     CStrW CurrentUnitID;
      91             :     CStr CurrentUnitAnim;
      92             :     float CurrentSpeed;
      93             :     bool WalkEnabled;
      94             :     bool GroundEnabled;
      95             :     bool WaterEnabled;
      96             :     bool ShadowsEnabled;
      97             : 
      98             :     // Whether shadows, sky and water are enabled outside of the actor viewer.
      99             :     bool OldShadows;
     100             :     bool OldSky;
     101             :     bool OldWater;
     102             : 
     103             :     bool SelectionBoxEnabled;
     104             :     bool AxesMarkerEnabled;
     105             :     int PropPointsMode; // 0 disabled, 1 for point markers, 2 for point markers + axes
     106             : 
     107             :     CTerrain Terrain;
     108             : 
     109             :     CColladaManager ColladaManager;
     110             :     CMeshManager MeshManager;
     111             :     CSkeletonAnimManager SkeletonAnimManager;
     112             :     CUnitManager UnitManager;
     113             :     CSimulation2 Simulation2;
     114             :     CObjectManager ObjectManager; // Keep this after Simulation2 - it needs it for initialisation.
     115             :     CLOSTexture LOSTexture;
     116             :     CTerritoryTexture TerritoryTexture;
     117             :     CMiniMapTexture MiniMapTexture;
     118             : 
     119             :     SOverlayLine SelectionBoxOverlay;
     120             :     SOverlayLine AxesMarkerOverlays[3];
     121             :     std::vector<CModel::Prop> Props;
     122             :     std::vector<SOverlayLine> PropPointOverlays;
     123             : 
     124             :     // Simplistic implementation of the Scene interface
     125           0 :     virtual void EnumerateObjects(const CFrustum& frustum, SceneCollector* c)
     126             :     {
     127           0 :         if (GroundEnabled)
     128             :         {
     129           0 :             for (ssize_t pj = 0; pj < Terrain.GetPatchesPerSide(); ++pj)
     130           0 :                 for (ssize_t pi = 0; pi < Terrain.GetPatchesPerSide(); ++pi)
     131           0 :                     c->Submit(Terrain.GetPatch(pi, pj));
     132             :         }
     133             : 
     134           0 :         CmpPtr<ICmpVisual> cmpVisual(Simulation2, Entity);
     135           0 :         if (cmpVisual)
     136             :         {
     137             :             // add selection box outlines manually
     138           0 :             if (SelectionBoxEnabled)
     139             :             {
     140           0 :                 SelectionBoxOverlay.m_Color = CColor(35/255.f, 86/255.f, 188/255.f, .75f); // pretty blue
     141           0 :                 SelectionBoxOverlay.m_Thickness = 0.1f;
     142             : 
     143           0 :                 SimRender::ConstructBoxOutline(cmpVisual->GetSelectionBox(), SelectionBoxOverlay);
     144           0 :                 c->Submit(&SelectionBoxOverlay);
     145             :             }
     146             : 
     147             :             // add origin axis thingy
     148           0 :             if (AxesMarkerEnabled)
     149             :             {
     150           0 :                 CMatrix3D worldSpaceAxes;
     151             :                 // offset from the ground a little bit to prevent fighting with the floor texture (also note: SetTranslation
     152             :                 // sets the identity 3x3 transformation matrix, which are the world axes)
     153           0 :                 worldSpaceAxes.SetTranslation(cmpVisual->GetPosition() + CVector3D(0, 0.02f, 0));
     154           0 :                 SimRender::ConstructAxesMarker(worldSpaceAxes, AxesMarkerOverlays[0], AxesMarkerOverlays[1], AxesMarkerOverlays[2]);
     155             : 
     156           0 :                 c->Submit(&AxesMarkerOverlays[0]);
     157           0 :                 c->Submit(&AxesMarkerOverlays[1]);
     158           0 :                 c->Submit(&AxesMarkerOverlays[2]);
     159             :             }
     160             : 
     161             :             // add prop point overlays
     162           0 :             if (PropPointsMode > 0 && Props.size() > 0)
     163             :             {
     164           0 :                 PropPointOverlays.clear(); // doesn't clear capacity, but should be ok since the number of prop points is usually pretty limited
     165           0 :                 for (size_t i = 0; i < Props.size(); ++i)
     166             :                 {
     167           0 :                     CModel::Prop& prop = Props[i];
     168           0 :                     if (prop.m_Model) // should always be the case
     169             :                     {
     170             :                         // prop point positions are automatically updated during animations etc. by CModel::ValidatePosition
     171           0 :                         const CMatrix3D& propCoordSystem = prop.m_Model->GetTransform();
     172             : 
     173           0 :                         SOverlayLine pointGimbal;
     174           0 :                         pointGimbal.m_Color = CColor(1.f, 0.f, 1.f, 1.f);
     175           0 :                         SimRender::ConstructGimbal(propCoordSystem.GetTranslation(), 0.05f, pointGimbal);
     176           0 :                         PropPointOverlays.push_back(pointGimbal);
     177             : 
     178           0 :                         if (PropPointsMode > 1)
     179             :                         {
     180             :                             // scale the prop axes coord system down a bit to distinguish them from the main world-space axes markers
     181           0 :                             CMatrix3D displayCoordSystem = propCoordSystem;
     182           0 :                             displayCoordSystem.Scale(0.5f, 0.5f, 0.5f);
     183             :                             // revert translation scaling
     184           0 :                             displayCoordSystem._14 = propCoordSystem._14;
     185           0 :                             displayCoordSystem._24 = propCoordSystem._24;
     186           0 :                             displayCoordSystem._34 = propCoordSystem._34;
     187             : 
     188             :                             // construct an XYZ axes marker for the prop's coordinate system
     189           0 :                             SOverlayLine xAxis, yAxis, zAxis;
     190           0 :                             SimRender::ConstructAxesMarker(displayCoordSystem, xAxis, yAxis, zAxis);
     191           0 :                             PropPointOverlays.push_back(xAxis);
     192           0 :                             PropPointOverlays.push_back(yAxis);
     193           0 :                             PropPointOverlays.push_back(zAxis);
     194             :                         }
     195             :                     }
     196             :                 }
     197             : 
     198           0 :                 for (size_t i = 0; i < PropPointOverlays.size(); ++i)
     199             :                 {
     200           0 :                     c->Submit(&PropPointOverlays[i]);
     201             :                 }
     202             :             }
     203             :         }
     204             : 
     205             :         // send a RenderSubmit message so the components can submit their visuals to the renderer
     206           0 :         Simulation2.RenderSubmit(*c, frustum, false);
     207           0 :     }
     208             : 
     209           0 :     virtual CLOSTexture& GetLOSTexture()
     210             :     {
     211           0 :         return LOSTexture;
     212             :     }
     213             : 
     214           0 :     virtual CTerritoryTexture& GetTerritoryTexture()
     215             :     {
     216           0 :         return TerritoryTexture;
     217             :     }
     218             : 
     219           0 :     virtual CMiniMapTexture& GetMiniMapTexture()
     220             :     {
     221           0 :         return MiniMapTexture;
     222             :     }
     223             : 
     224             :     /**
     225             :      * Recursively fetches the props of the currently displayed entity model and its submodels, and stores them for rendering.
     226             :      */
     227             :     void UpdatePropList();
     228             :     void UpdatePropListRecursive(CModelAbstract* model);
     229             : 
     230             : };
     231             : 
     232           0 : void ActorViewerImpl::UpdatePropList()
     233             : {
     234           0 :     Props.clear();
     235             : 
     236           0 :     CmpPtr<ICmpVisual> cmpVisual(Simulation2, Entity);
     237           0 :     if (cmpVisual)
     238             :     {
     239           0 :         CUnit* unit = cmpVisual->GetUnit();
     240           0 :         if (unit)
     241             :         {
     242           0 :             CModelAbstract& modelAbstract = unit->GetModel();
     243           0 :             UpdatePropListRecursive(&modelAbstract);
     244             :         }
     245             :     }
     246           0 : }
     247             : 
     248           0 : void ActorViewerImpl::UpdatePropListRecursive(CModelAbstract* modelAbstract)
     249             : {
     250           0 :     ENSURE(modelAbstract);
     251             : 
     252           0 :     CModel* model = modelAbstract->ToCModel();
     253           0 :     if (model)
     254             :     {
     255           0 :         std::vector<CModel::Prop>& modelProps = model->GetProps();
     256           0 :         for (CModel::Prop& modelProp : modelProps)
     257             :         {
     258           0 :             Props.push_back(modelProp);
     259           0 :             if (modelProp.m_Model)
     260           0 :                 UpdatePropListRecursive(modelProp.m_Model);
     261             :         }
     262             :     }
     263           0 : }
     264             : 
     265           0 : ActorViewer::ActorViewer()
     266           0 :     : m(*new ActorViewerImpl())
     267             : {
     268           0 :     m.WalkEnabled = false;
     269           0 :     m.GroundEnabled = true;
     270           0 :     m.WaterEnabled = false;
     271           0 :     m.ShadowsEnabled = g_RenderingOptions.GetShadows();
     272           0 :     m.SelectionBoxEnabled = false;
     273           0 :     m.AxesMarkerEnabled = false;
     274           0 :     m.PropPointsMode = 0;
     275             : 
     276             :     // Create a tiny empty piece of terrain, just so we can put shadows
     277             :     // on it without having to think too hard
     278           0 :     m.Terrain.Initialize(2, NULL);
     279           0 :     CTerrainTextureEntry* tex = g_TexMan.FindTexture("whiteness");
     280           0 :     if (tex)
     281             :     {
     282           0 :         for (ssize_t pi = 0; pi < m.Terrain.GetPatchesPerSide(); ++pi)
     283             :         {
     284           0 :             for (ssize_t pj = 0; pj < m.Terrain.GetPatchesPerSide(); ++pj)
     285             :             {
     286           0 :                 CPatch* patch = m.Terrain.GetPatch(pi, pj);
     287           0 :                 for (ssize_t i = 0; i < PATCH_SIZE; ++i)
     288             :                 {
     289           0 :                     for (ssize_t j = 0; j < PATCH_SIZE; ++j)
     290             :                     {
     291           0 :                         CMiniPatch& mp = patch->m_MiniPatches[i][j];
     292           0 :                         mp.Tex = tex;
     293           0 :                         mp.Priority = 0;
     294             :                     }
     295             :                 }
     296             :             }
     297             :         }
     298             :     }
     299             :     else
     300             :     {
     301           0 :         debug_warn(L"Failed to load whiteness texture");
     302             :     }
     303             : 
     304             :     // Prepare the simulation
     305           0 :     m.Simulation2.LoadDefaultScripts();
     306           0 :     m.Simulation2.ResetState();
     307             : 
     308             :     // Set player data
     309           0 :     m.Simulation2.SetMapSettings(m.Simulation2.GetPlayerDefaults());
     310           0 :     m.Simulation2.LoadPlayerSettings(true);
     311             : 
     312             :     // Tell the simulation we've already loaded the terrain
     313           0 :     CmpPtr<ICmpTerrain> cmpTerrain(m.Simulation2, SYSTEM_ENTITY);
     314           0 :     if (cmpTerrain)
     315           0 :         cmpTerrain->ReloadTerrain(false);
     316             : 
     317             :     // Remove FOW since we're in Atlas
     318           0 :     CmpPtr<ICmpRangeManager> cmpRangeManager(m.Simulation2, SYSTEM_ENTITY);
     319           0 :     if (cmpRangeManager)
     320           0 :         cmpRangeManager->SetLosRevealAll(-1, true);
     321             : 
     322           0 :     m.Simulation2.InitGame();
     323           0 : }
     324             : 
     325           0 : ActorViewer::~ActorViewer()
     326             : {
     327           0 :     delete &m;
     328           0 : }
     329             : 
     330           0 : CSimulation2* ActorViewer::GetSimulation2()
     331             : {
     332           0 :     return &m.Simulation2;
     333             : }
     334             : 
     335           0 : entity_id_t ActorViewer::GetEntity()
     336             : {
     337           0 :     return m.Entity;
     338             : }
     339             : 
     340           0 : void ActorViewer::UnloadObjects()
     341             : {
     342           0 :     m.ObjectManager.UnloadObjects();
     343           0 : }
     344             : 
     345           0 : void ActorViewer::SetActor(const CStrW& name, const CStr& animation, player_id_t playerID)
     346             : {
     347           0 :     bool needsAnimReload = false;
     348             : 
     349           0 :     CStrW id = name;
     350             : 
     351             :     // Recreate the entity, if we don't have one or if the new one is different
     352           0 :     if (m.Entity == INVALID_ENTITY || id != m.CurrentUnitID)
     353             :     {
     354             :         // Delete the old entity (if any)
     355           0 :         if (m.Entity != INVALID_ENTITY)
     356             :         {
     357           0 :             m.Simulation2.DestroyEntity(m.Entity);
     358           0 :             m.Simulation2.FlushDestroyedEntities();
     359           0 :             m.Entity = INVALID_ENTITY;
     360             :         }
     361             : 
     362             :         // Clear particles associated with deleted entity
     363           0 :         g_Renderer.GetSceneRenderer().GetParticleManager().ClearUnattachedEmitters();
     364             : 
     365             :         // If there's no actor to display, return with nothing loaded
     366           0 :         if (id.empty())
     367           0 :             return;
     368             : 
     369           0 :         m.Entity = m.Simulation2.AddEntity(L"preview|" + id);
     370           0 :         if (m.Entity == INVALID_ENTITY)
     371           0 :             return;
     372             : 
     373           0 :         CmpPtr<ICmpPosition> cmpPosition(m.Simulation2, m.Entity);
     374           0 :         if (cmpPosition)
     375             :         {
     376           0 :             ssize_t c = TERRAIN_TILE_SIZE * m.Terrain.GetPatchesPerSide()*PATCH_SIZE/2;
     377           0 :             cmpPosition->JumpTo(entity_pos_t::FromInt(c), entity_pos_t::FromInt(c));
     378           0 :             cmpPosition->SetYRotation(entity_angle_t::Pi());
     379             :         }
     380             : 
     381           0 :         CmpPtr<ICmpOwnership> cmpOwnership(m.Simulation2, m.Entity);
     382           0 :         if (cmpOwnership)
     383           0 :             cmpOwnership->SetOwner(playerID);
     384             : 
     385           0 :         needsAnimReload = true;
     386             :     }
     387             : 
     388           0 :     if (animation != m.CurrentUnitAnim)
     389           0 :         needsAnimReload = true;
     390             : 
     391           0 :     if (needsAnimReload)
     392             :     {
     393             :         // Emulate the typical simulation animation behaviour.
     394           0 :         CStr anim = animation.LowerCase();
     395           0 :         float speed = 1.0f;
     396             :         // Speed will be ignored if we have a repeat time.
     397           0 :         float repeatTime = 0.0f;
     398           0 :         m.CurrentSpeed = 0.0f;
     399           0 :         if (anim == "walk")
     400             :         {
     401           0 :             CmpPtr<ICmpUnitMotion> cmpUnitMotion(m.Simulation2, m.Entity);
     402           0 :             if (cmpUnitMotion)
     403           0 :                 speed  = cmpUnitMotion->GetWalkSpeed().ToFloat();
     404             :             else
     405           0 :                 speed = 7.f; // Typical unit walk speed.
     406           0 :             m.CurrentSpeed = speed;
     407             :         }
     408           0 :         else if (anim == "run")
     409             :         {
     410           0 :             CmpPtr<ICmpUnitMotion> cmpUnitMotion(m.Simulation2, m.Entity);
     411           0 :             if (cmpUnitMotion)
     412           0 :                 speed = cmpUnitMotion->GetWalkSpeed().ToFloat() * cmpUnitMotion->GetRunMultiplier().ToFloat();
     413             :             else
     414           0 :                 speed = 12.f; // Typical unit run speed.
     415             : 
     416           0 :             m.CurrentSpeed = speed;
     417             :         }
     418           0 :         else if (anim.Find("attack_") == 0)
     419             :         {
     420           0 :             CmpPtr<ICmpAttack> cmpAttack(m.Simulation2, m.Entity);
     421           0 :             if (cmpAttack)
     422           0 :                 for (const CStr& type : cmpAttack->GetAttackTypes())
     423           0 :                     if (anim == "attack_" + type.LowerCase())
     424             :                     {
     425           0 :                         repeatTime = GetRepeatTimeByAttackType(type);
     426           0 :                         break;
     427             :                     }
     428             :         }
     429             : 
     430           0 :         CmpPtr<ICmpVisual> cmpVisual(m.Simulation2, m.Entity);
     431           0 :         if (cmpVisual)
     432             :         {
     433             :             // TODO: SetEntitySelection(anim)
     434           0 :             cmpVisual->SelectAnimation(anim, false, fixed::FromFloat(speed));
     435           0 :             if (repeatTime > 0.0f)
     436           0 :                 cmpVisual->SetAnimationSyncRepeat(fixed::FromFloat(repeatTime));
     437             :         }
     438             : 
     439             :         // update prop list for new entity/animation (relies on needsAnimReload also getting called for entire entity changes)
     440           0 :         m.UpdatePropList();
     441             :     }
     442             : 
     443           0 :     m.CurrentUnitID = id;
     444           0 :     m.CurrentUnitAnim = animation;
     445             : }
     446             : 
     447           0 : void ActorViewer::SetEnabled(bool enabled)
     448             : {
     449           0 :     if (enabled)
     450             :     {
     451             :         // Set shadows, sky and water.
     452           0 :         m.OldShadows = g_RenderingOptions.GetShadows();
     453           0 :         SetShadowsEnabled(m.ShadowsEnabled);
     454             : 
     455           0 :         m.OldSky = g_Renderer.GetSceneRenderer().GetSkyManager().IsSkyVisible();
     456           0 :         g_Renderer.GetSceneRenderer().GetSkyManager().SetSkyVisible(false);
     457             : 
     458           0 :         m.OldWater = g_Renderer.GetSceneRenderer().GetWaterManager().m_RenderWater;
     459           0 :         g_Renderer.GetSceneRenderer().GetWaterManager().m_RenderWater = m.WaterEnabled;
     460             :     }
     461             :     else
     462             :     {
     463             :         // Restore the old renderer state
     464           0 :         SetShadowsEnabled(m.OldShadows);
     465           0 :         g_Renderer.GetSceneRenderer().GetSkyManager().SetSkyVisible(m.OldSky);
     466           0 :         g_Renderer.GetSceneRenderer().GetWaterManager().m_RenderWater = m.OldWater;
     467             :     }
     468           0 : }
     469             : 
     470           0 : void ActorViewer::SetWalkEnabled(bool enabled)    { m.WalkEnabled = enabled; }
     471           0 : void ActorViewer::SetGroundEnabled(bool enabled)  { m.GroundEnabled = enabled; }
     472           0 : void ActorViewer::SetWaterEnabled(bool enabled)
     473             : {
     474           0 :     m.WaterEnabled = enabled;
     475             :     // Adjust water level
     476           0 :     entity_pos_t waterLevel = entity_pos_t::FromFloat(enabled ? 10.f : 0.f);
     477           0 :     CmpPtr<ICmpWaterManager> cmpWaterManager(m.Simulation2, SYSTEM_ENTITY);
     478           0 :     if (cmpWaterManager)
     479           0 :         cmpWaterManager->SetWaterLevel(waterLevel);
     480           0 : }
     481           0 : void ActorViewer::SetShadowsEnabled(bool enabled) {
     482           0 :     g_RenderingOptions.SetShadows(enabled);
     483           0 :     m.ShadowsEnabled = enabled;
     484           0 : }
     485           0 : void ActorViewer::ToggleShadows()
     486             : {
     487           0 :     SetShadowsEnabled(!m.ShadowsEnabled);
     488           0 : }
     489           0 : void ActorViewer::SetBoundingBoxesEnabled(bool enabled) { m.SelectionBoxEnabled = enabled; }
     490           0 : void ActorViewer::SetAxesMarkerEnabled(bool enabled)    { m.AxesMarkerEnabled = enabled; }
     491           0 : void ActorViewer::SetPropPointsMode(int mode)           { m.PropPointsMode = mode; }
     492             : 
     493           0 : void ActorViewer::SetStatsEnabled(bool enabled)
     494             : {
     495           0 :     if (enabled)
     496           0 :         g_ProfileViewer.ShowTable("renderer");
     497             :     else
     498           0 :         g_ProfileViewer.ShowTable("");
     499           0 : }
     500             : 
     501           0 : float ActorViewer::GetRepeatTimeByAttackType(const std::string& type) const
     502             : {
     503           0 :     CmpPtr<ICmpAttack> cmpAttack(m.Simulation2, m.Entity);
     504           0 :     if (cmpAttack)
     505           0 :         return cmpAttack->GetRepeatTime(type);
     506             : 
     507           0 :     return 0.0f;
     508             : }
     509             : 
     510           0 : void ActorViewer::Render()
     511             : {
     512             :     // TODO: ActorViewer should reuse CRenderer code and not duplicate it.
     513             : 
     514           0 :     CSceneRenderer& sceneRenderer = g_Renderer.GetSceneRenderer();
     515             : 
     516             :     // Set simulation context for rendering purposes
     517           0 :     sceneRenderer.SetSimulation(&m.Simulation2);
     518             : 
     519             :     // Find the centre of the interesting region, in the middle of the patch
     520             :     // and half way up the model (assuming there is one)
     521           0 :     CVector3D centre;
     522           0 :     CmpPtr<ICmpVisual> cmpVisual(m.Simulation2, m.Entity);
     523           0 :     if (cmpVisual)
     524           0 :         cmpVisual->GetBounds().GetCenter(centre);
     525             :     else
     526           0 :         centre.Y = 0.f;
     527           0 :     centre.X = centre.Z = TERRAIN_TILE_SIZE * m.Terrain.GetPatchesPerSide()*PATCH_SIZE/2;
     528             : 
     529           0 :     CCamera camera = AtlasView::GetView_Actor()->GetCamera();
     530           0 :     camera.m_Orientation.Translate(centre.X, centre.Y, centre.Z);
     531           0 :     camera.UpdateFrustum();
     532             : 
     533           0 :     sceneRenderer.SetSceneCamera(camera, camera);
     534             : 
     535           0 :     g_Renderer.BeginFrame();
     536             : 
     537             :     Renderer::Backend::IDeviceCommandContext* deviceCommandContext =
     538           0 :         g_Renderer.GetDeviceCommandContext();
     539             : 
     540           0 :     sceneRenderer.PrepareScene(deviceCommandContext, m);
     541             : 
     542             :     Renderer::Backend::IFramebuffer* backbuffer =
     543           0 :         deviceCommandContext->GetDevice()->GetCurrentBackbuffer(
     544             :             Renderer::Backend::AttachmentLoadOp::DONT_CARE,
     545             :             Renderer::Backend::AttachmentStoreOp::STORE,
     546             :             Renderer::Backend::AttachmentLoadOp::CLEAR,
     547           0 :             Renderer::Backend::AttachmentStoreOp::DONT_CARE);
     548           0 :     deviceCommandContext->BeginFramebufferPass(backbuffer);
     549             : 
     550           0 :     Renderer::Backend::IDeviceCommandContext::Rect viewportRect{};
     551           0 :     viewportRect.width = backbuffer->GetWidth();
     552           0 :     viewportRect.height = backbuffer->GetHeight();
     553           0 :     deviceCommandContext->SetViewports(1, &viewportRect);
     554             : 
     555           0 :     sceneRenderer.RenderScene(deviceCommandContext);
     556           0 :     sceneRenderer.RenderSceneOverlays(deviceCommandContext);
     557             : 
     558             :     {
     559           0 :         CCanvas2D canvas(g_xres, g_yres, g_VideoMode.GetScale(), deviceCommandContext);
     560           0 :         g_Logger->Render(canvas);
     561           0 :         g_ProfileViewer.RenderProfile(canvas);
     562             :     }
     563             : 
     564           0 :     deviceCommandContext->EndFramebufferPass();
     565             : 
     566           0 :     g_Renderer.EndFrame();
     567           0 : }
     568             : 
     569           0 : void ActorViewer::Update(float simFrameLength, float realFrameLength)
     570             : {
     571           0 :     m.Simulation2.Update((int)(simFrameLength*1000));
     572           0 :     m.Simulation2.Interpolate(simFrameLength, 0, realFrameLength);
     573             : 
     574           0 :     if (m.WalkEnabled && m.CurrentSpeed)
     575             :     {
     576           0 :         CmpPtr<ICmpPosition> cmpPosition(m.Simulation2, m.Entity);
     577           0 :         if (cmpPosition)
     578             :         {
     579             :             // Move the model by speed*simFrameLength forwards
     580           0 :             float z = cmpPosition->GetPosition().Z.ToFloat();
     581           0 :             z -= m.CurrentSpeed*simFrameLength;
     582             :             // Wrap at the edges, so it doesn't run off into the horizon
     583           0 :             ssize_t c = TERRAIN_TILE_SIZE * m.Terrain.GetPatchesPerSide()*PATCH_SIZE/2;
     584           0 :             if (z < c - TERRAIN_TILE_SIZE*PATCH_SIZE * 0.1f)
     585           0 :                 z = c + TERRAIN_TILE_SIZE*PATCH_SIZE * 0.1f;
     586           0 :             cmpPosition->JumpTo(cmpPosition->GetPosition().X, entity_pos_t::FromFloat(z));
     587             :         }
     588             :     }
     589           3 : }

Generated by: LCOV version 1.13