forked from 0ad/0ad
Add obstruction debug mode, with GUI toggle.
Make pathfinder debug mode off by default, with GUI toggle. This was SVN commit r7377.
This commit is contained in:
parent
55adcfc595
commit
a5b8ec6028
@ -44,6 +44,16 @@
|
||||
|
||||
<object size="0 16 100%-18 32" type="text" text_align="right">Display selection state</object>
|
||||
<object size="100%-16 16 100% 32" type="checkbox" name="devDisplayState" style="wheatCrossBox"/>
|
||||
|
||||
<object size="0 32 100%-18 48" type="text" text_align="right">Pathfinder overlay</object>
|
||||
<object size="100%-16 32 100% 48" type="checkbox" style="wheatCrossBox">
|
||||
<action on="Press">Engine.GuiInterfaceCall("SetPathfinderDebugOverlay", this.checked);</action>
|
||||
</object>
|
||||
|
||||
<object size="0 48 100%-18 64" type="text" text_align="right">Obstruction overlay</object>
|
||||
<object size="100%-16 48 100% 64" type="checkbox" style="wheatCrossBox">
|
||||
<action on="Press">Engine.GuiInterfaceCall("SetObstructionDebugOverlay", this.checked);</action>
|
||||
</object>
|
||||
</object>
|
||||
|
||||
<!-- Debug text -->
|
||||
|
@ -204,6 +204,18 @@ GuiInterface.prototype.SetBuildingPlacementPreview = function(player, cmd)
|
||||
return false;
|
||||
};
|
||||
|
||||
GuiInterface.prototype.SetPathfinderDebugOverlay = function(player, enabled)
|
||||
{
|
||||
var cmpPathfinder = Engine.QueryInterface(SYSTEM_ENTITY, IID_Pathfinder);
|
||||
cmpPathfinder.SetDebugOverlay(enabled);
|
||||
};
|
||||
|
||||
GuiInterface.prototype.SetObstructionDebugOverlay = function(player, enabled)
|
||||
{
|
||||
var cmpObstructionManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_ObstructionManager);
|
||||
cmpObstructionManager.SetDebugOverlay(enabled);
|
||||
};
|
||||
|
||||
// List the GuiInterface functions that can be safely called by GUI scripts.
|
||||
// (GUI scripts are non-deterministic and untrusted, so these functions must be
|
||||
// appropriately careful. They are called with a first argument "player", which is
|
||||
@ -214,7 +226,9 @@ var exposedFunctions = {
|
||||
"GetEntityState": 1,
|
||||
"GetTemplateData": 1,
|
||||
"SetSelectionHighlight": 1,
|
||||
"SetBuildingPlacementPreview": 1
|
||||
"SetBuildingPlacementPreview": 1,
|
||||
"SetPathfinderDebugOverlay": 1,
|
||||
"SetObstructionDebugOverlay": 1
|
||||
};
|
||||
|
||||
GuiInterface.prototype.ScriptCall = function(player, name, args)
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "graphics/Camera.h"
|
||||
#include "graphics/GameView.h"
|
||||
#include "gui/GUIManager.h"
|
||||
#include "maths/FixedVector3D.h"
|
||||
#include "ps/CLogger.h"
|
||||
#include "ps/Game.h"
|
||||
#include "ps/Overlay.h"
|
||||
|
@ -21,13 +21,15 @@
|
||||
#include "ICmpObstructionManager.h"
|
||||
|
||||
#include "simulation2/MessageTypes.h"
|
||||
#include "simulation2/helpers/Render.h"
|
||||
|
||||
#include "graphics/Overlay.h"
|
||||
#include "graphics/Terrain.h"
|
||||
#include "maths/FixedVector2D.h"
|
||||
#include "maths/MathUtil.h"
|
||||
#include "ps/Overlay.h"
|
||||
#include "ps/Profile.h"
|
||||
#include "renderer/TerrainOverlay.h"
|
||||
#include "renderer/Scene.h"
|
||||
|
||||
// Externally, tags are opaque non-zero positive integers.
|
||||
// Internally, they are tagged (by shape) indexes into shape lists.
|
||||
@ -59,12 +61,17 @@ struct Square
|
||||
class CCmpObstructionManager : public ICmpObstructionManager
|
||||
{
|
||||
public:
|
||||
static void ClassInit(CComponentManager& UNUSED(componentManager))
|
||||
static void ClassInit(CComponentManager& componentManager)
|
||||
{
|
||||
componentManager.SubscribeToMessageType(MT_RenderSubmit); // for debug overlays
|
||||
}
|
||||
|
||||
DEFAULT_COMPONENT_ALLOCATOR(ObstructionManager)
|
||||
|
||||
bool m_DebugOverlayEnabled;
|
||||
bool m_DebugOverlayDirty;
|
||||
std::vector<SOverlayLine> m_DebugOverlayLines;
|
||||
|
||||
// TODO: using std::map is a bit inefficient; is there a better way to store these?
|
||||
std::map<u32, Circle> m_Circles;
|
||||
std::map<u32, Square> m_Squares;
|
||||
@ -73,6 +80,9 @@ public:
|
||||
|
||||
virtual void Init(const CSimContext& context, const CParamNode& UNUSED(paramNode))
|
||||
{
|
||||
m_DebugOverlayEnabled = false;
|
||||
m_DebugOverlayDirty = true;
|
||||
|
||||
m_CircleNext = 1;
|
||||
m_SquareNext = 1;
|
||||
|
||||
@ -97,6 +107,19 @@ public:
|
||||
// TODO
|
||||
}
|
||||
|
||||
virtual void HandleMessage(const CSimContext& context, const CMessage& msg, bool UNUSED(global))
|
||||
{
|
||||
switch (msg.GetType())
|
||||
{
|
||||
case MT_RenderSubmit:
|
||||
{
|
||||
const CMessageRenderSubmit& msgData = static_cast<const CMessageRenderSubmit&> (msg);
|
||||
RenderSubmit(context, msgData.collector);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual tag_t AddCircle(entity_pos_t x, entity_pos_t z, entity_pos_t r)
|
||||
{
|
||||
Circle c = { x, z, r };
|
||||
@ -154,6 +177,16 @@ public:
|
||||
|
||||
virtual bool Rasterise(Grid<u8>& grid);
|
||||
|
||||
virtual void SetDebugOverlay(bool enabled)
|
||||
{
|
||||
m_DebugOverlayEnabled = enabled;
|
||||
m_DebugOverlayDirty = true;
|
||||
if (!enabled)
|
||||
m_DebugOverlayLines.clear();
|
||||
}
|
||||
|
||||
void RenderSubmit(const CSimContext& context, SceneCollector& collector);
|
||||
|
||||
private:
|
||||
// To support lazy updates of grid rasterisations of obstruction data,
|
||||
// we maintain a DirtyID here and increment it whenever obstructions change;
|
||||
@ -167,6 +200,7 @@ private:
|
||||
void MakeDirty()
|
||||
{
|
||||
++m_DirtyID;
|
||||
m_DebugOverlayDirty = true;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -320,3 +354,36 @@ bool CCmpObstructionManager::Rasterise(Grid<u8>& grid)
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CCmpObstructionManager::RenderSubmit(const CSimContext& context, SceneCollector& collector)
|
||||
{
|
||||
if (!m_DebugOverlayEnabled)
|
||||
return;
|
||||
|
||||
CColor defaultColour(0, 0, 1, 1);
|
||||
|
||||
// If the shapes have changed, then regenerate all the overlays
|
||||
if (m_DebugOverlayDirty)
|
||||
{
|
||||
m_DebugOverlayLines.clear();
|
||||
|
||||
for (std::map<u32, Circle>::iterator it = m_Circles.begin(); it != m_Circles.end(); ++it)
|
||||
{
|
||||
m_DebugOverlayLines.push_back(SOverlayLine());
|
||||
m_DebugOverlayLines.back().m_Color = defaultColour;
|
||||
SimRender::ConstructCircleOnGround(context, it->second.x.ToFloat(), it->second.z.ToFloat(), it->second.r.ToFloat(), m_DebugOverlayLines.back());
|
||||
}
|
||||
|
||||
for (std::map<u32, Square>::iterator it = m_Squares.begin(); it != m_Squares.end(); ++it)
|
||||
{
|
||||
m_DebugOverlayLines.push_back(SOverlayLine());
|
||||
m_DebugOverlayLines.back().m_Color = defaultColour;
|
||||
SimRender::ConstructSquareOnGround(context, it->second.x.ToFloat(), it->second.z.ToFloat(), it->second.w.ToFloat(), it->second.h.ToFloat(), it->second.a.ToFloat(), m_DebugOverlayLines.back());
|
||||
}
|
||||
|
||||
m_DebugOverlayDirty = false;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < m_DebugOverlayLines.size(); ++i)
|
||||
collector.Submit(&m_DebugOverlayLines[i]);
|
||||
}
|
||||
|
@ -91,7 +91,7 @@ public:
|
||||
m_MapSize = 0;
|
||||
m_Grid = NULL;
|
||||
|
||||
m_DebugOverlay = new PathfinderOverlay(*this);
|
||||
m_DebugOverlay = NULL;
|
||||
m_DebugGrid = NULL;
|
||||
m_DebugPath = NULL;
|
||||
}
|
||||
@ -124,6 +124,9 @@ public:
|
||||
|
||||
virtual void SetDebugPath(entity_pos_t x0, entity_pos_t z0, const Goal& goal)
|
||||
{
|
||||
if (!m_DebugOverlay)
|
||||
return;
|
||||
|
||||
delete m_DebugGrid;
|
||||
m_DebugGrid = NULL;
|
||||
delete m_DebugPath;
|
||||
@ -131,6 +134,19 @@ public:
|
||||
ComputePath(x0, z0, goal, *m_DebugPath);
|
||||
}
|
||||
|
||||
virtual void SetDebugOverlay(bool enabled)
|
||||
{
|
||||
if (enabled && !m_DebugOverlay)
|
||||
{
|
||||
m_DebugOverlay = new PathfinderOverlay(*this);
|
||||
}
|
||||
else if (!enabled && m_DebugOverlay)
|
||||
{
|
||||
delete m_DebugOverlay;
|
||||
m_DebugOverlay = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the tile containing the given position
|
||||
*/
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
#include "ICmpPosition.h"
|
||||
#include "simulation2/MessageTypes.h"
|
||||
#include "simulation2/helpers/Render.h"
|
||||
|
||||
#include "graphics/Overlay.h"
|
||||
#include "maths/MathUtil.h"
|
||||
@ -29,8 +30,6 @@
|
||||
#include "maths/Vector3D.h"
|
||||
#include "renderer/Scene.h"
|
||||
|
||||
const size_t SELECTION_CIRCLE_POINTS = 16;
|
||||
|
||||
class CCmpSelectable : public ICmpSelectable
|
||||
{
|
||||
public:
|
||||
@ -119,31 +118,19 @@ public:
|
||||
|
||||
CMatrix3D transform = cmpPosition->GetInterpolatedTransform(frameOffset);
|
||||
CVector3D pos = transform.GetTranslation();
|
||||
// TODO: this is an unnecessarily inefficient way to get X and Z coordinates;
|
||||
// ought to have a GetInterpolated2DPosition instead
|
||||
|
||||
// TODO: should use ICmpFootprint to find the shape
|
||||
|
||||
float radius = 2.f;
|
||||
|
||||
m_Overlay.m_Coords.clear();
|
||||
m_Overlay.m_Coords.reserve((SELECTION_CIRCLE_POINTS + 1) * 3);
|
||||
|
||||
for (size_t i = 0; i <= SELECTION_CIRCLE_POINTS; ++i) // use '<=' so it's a closed loop
|
||||
{
|
||||
float a = i * 2 * M_PI / SELECTION_CIRCLE_POINTS;
|
||||
float x = pos.X + radius * sin(a);
|
||||
float z = pos.Z + radius * cos(a);
|
||||
float y = pos.Y + 0.25f; // TODO: clamp to ground instead
|
||||
m_Overlay.m_Coords.push_back(x);
|
||||
m_Overlay.m_Coords.push_back(y);
|
||||
m_Overlay.m_Coords.push_back(z);
|
||||
}
|
||||
SimRender::ConstructCircleOnGround(context, pos.X, pos.Z, radius, m_Overlay);
|
||||
}
|
||||
|
||||
void RenderSubmit(SceneCollector& collector)
|
||||
{
|
||||
// (This is only called if a > 0)
|
||||
|
||||
// TODO: maybe should do some frustum culling
|
||||
collector.Submit(&m_Overlay);
|
||||
}
|
||||
|
||||
|
@ -22,4 +22,5 @@
|
||||
#include "simulation2/system/InterfaceScripted.h"
|
||||
|
||||
BEGIN_INTERFACE_WRAPPER(ObstructionManager)
|
||||
DEFINE_INTERFACE_METHOD_1("SetDebugOverlay", void, ICmpObstructionManager, SetDebugOverlay, bool)
|
||||
END_INTERFACE_WRAPPER(ObstructionManager)
|
||||
|
@ -128,6 +128,11 @@ public:
|
||||
*/
|
||||
virtual bool Rasterise(Grid<u8>& grid) = 0;
|
||||
|
||||
/**
|
||||
* Toggle the rendering of debug info.
|
||||
*/
|
||||
virtual void SetDebugOverlay(bool enabled) = 0;
|
||||
|
||||
DECLARE_INTERFACE_TYPE(ObstructionManager)
|
||||
};
|
||||
|
||||
|
@ -22,4 +22,5 @@
|
||||
#include "simulation2/system/InterfaceScripted.h"
|
||||
|
||||
BEGIN_INTERFACE_WRAPPER(Pathfinder)
|
||||
DEFINE_INTERFACE_METHOD_1("SetDebugOverlay", void, ICmpPathfinder, SetDebugOverlay, bool)
|
||||
END_INTERFACE_WRAPPER(Pathfinder)
|
||||
|
@ -80,6 +80,11 @@ public:
|
||||
*/
|
||||
virtual void SetDebugPath(entity_pos_t x0, entity_pos_t z0, const Goal& goal) = 0;
|
||||
|
||||
/**
|
||||
* Toggle the storage and rendering of debug info.
|
||||
*/
|
||||
virtual void SetDebugOverlay(bool enabled) = 0;
|
||||
|
||||
DECLARE_INTERFACE_TYPE(Pathfinder)
|
||||
};
|
||||
|
||||
|
82
source/simulation2/helpers/Render.cpp
Normal file
82
source/simulation2/helpers/Render.cpp
Normal file
@ -0,0 +1,82 @@
|
||||
/* Copyright (C) 2010 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 0 A.D. is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
#include "Render.h"
|
||||
|
||||
#include "simulation2/Simulation2.h"
|
||||
#include "simulation2/components/ICmpTerrain.h"
|
||||
#include "graphics/Overlay.h"
|
||||
|
||||
static const size_t RENDER_CIRCLE_POINTS = 16;
|
||||
static const float RENDER_HEIGHT_DELTA = 0.25f; // distance above terrain
|
||||
|
||||
void SimRender::ConstructCircleOnGround(const CSimContext& context, float x, float z, float radius, SOverlayLine& overlay)
|
||||
{
|
||||
overlay.m_Coords.clear();
|
||||
|
||||
CmpPtr<ICmpTerrain> cmpTerrain(context, SYSTEM_ENTITY);
|
||||
if (cmpTerrain.null())
|
||||
return;
|
||||
|
||||
overlay.m_Coords.reserve((RENDER_CIRCLE_POINTS + 1) * 3);
|
||||
|
||||
for (size_t i = 0; i <= RENDER_CIRCLE_POINTS; ++i) // use '<=' so it's a closed loop
|
||||
{
|
||||
float a = i * 2 * M_PI / RENDER_CIRCLE_POINTS;
|
||||
float px = x + radius * sin(a);
|
||||
float pz = z + radius * cos(a);
|
||||
float py = cmpTerrain->GetGroundLevel(px, pz) + RENDER_HEIGHT_DELTA;
|
||||
overlay.m_Coords.push_back(px);
|
||||
overlay.m_Coords.push_back(py);
|
||||
overlay.m_Coords.push_back(pz);
|
||||
}
|
||||
}
|
||||
|
||||
void SimRender::ConstructSquareOnGround(const CSimContext& context, float x, float z, float w, float h, float a, SOverlayLine& overlay)
|
||||
{
|
||||
overlay.m_Coords.clear();
|
||||
|
||||
CmpPtr<ICmpTerrain> cmpTerrain(context, SYSTEM_ENTITY);
|
||||
if (cmpTerrain.null())
|
||||
return;
|
||||
|
||||
// TODO: might be nicer to split this into little pieces so it copes better with uneven terrain
|
||||
|
||||
overlay.m_Coords.reserve(5 * 3);
|
||||
|
||||
float c = cos(a);
|
||||
float s = sin(a);
|
||||
|
||||
std::vector<std::pair<float, float> > coords;
|
||||
coords.push_back(std::make_pair(x - w/2*c + h/2*s, z + w/2*s + h/2*c));
|
||||
coords.push_back(std::make_pair(x - w/2*c - h/2*s, z + w/2*s - h/2*c));
|
||||
coords.push_back(std::make_pair(x + w/2*c - h/2*s, z - w/2*s - h/2*c));
|
||||
coords.push_back(std::make_pair(x + w/2*c + h/2*s, z - w/2*s + h/2*c));
|
||||
coords.push_back(std::make_pair(x - w/2*c + h/2*s, z + w/2*s + h/2*c));
|
||||
|
||||
for (size_t i = 0; i < coords.size(); ++i)
|
||||
{
|
||||
float px = coords[i].first;
|
||||
float pz = coords[i].second;
|
||||
float py = cmpTerrain->GetGroundLevel(px, pz) + RENDER_HEIGHT_DELTA;
|
||||
overlay.m_Coords.push_back(px);
|
||||
overlay.m_Coords.push_back(py);
|
||||
overlay.m_Coords.push_back(pz);
|
||||
}
|
||||
}
|
45
source/simulation2/helpers/Render.h
Normal file
45
source/simulation2/helpers/Render.h
Normal file
@ -0,0 +1,45 @@
|
||||
/* Copyright (C) 2010 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 0 A.D. is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_HELPER_RENDER
|
||||
#define INCLUDED_HELPER_RENDER
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Helper functions related to rendering
|
||||
*/
|
||||
|
||||
class CSimContext;
|
||||
struct SOverlayLine;
|
||||
|
||||
namespace SimRender
|
||||
{
|
||||
|
||||
/**
|
||||
* Updates @p overlay so that it represents the given circle, flattened on the terrain.
|
||||
*/
|
||||
void ConstructCircleOnGround(const CSimContext& context, float x, float z, float radius, SOverlayLine& overlay);
|
||||
|
||||
/**
|
||||
* Updates @p overlay so that it represents the given square, flattened on the terrain.
|
||||
* @p x and @p z are position of center, @p w and @p h are size of rectangle, @p a is clockwise angle.
|
||||
*/
|
||||
void ConstructSquareOnGround(const CSimContext& context, float x, float z, float w, float h, float a, SOverlayLine& overlay);
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif // INCLUDED_HELPER_RENDER
|
@ -23,7 +23,7 @@
|
||||
* Helper functions related to entity selection
|
||||
*/
|
||||
|
||||
#include "simulation2/components/ICmpPosition.h"
|
||||
#include "simulation2/system/Entity.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user