# Initial support for territories
This was SVN commit r9889.
This commit is contained in:
parent
cdbd347466
commit
f9d7c1246d
@ -5,12 +5,14 @@
|
||||
<uniform name="sunColor" loc="0" type="vec3"/>
|
||||
<uniform name="losTransform" loc="1" type="vec2"/>
|
||||
<uniform name="shadowTransform" loc="2" type="mat4"/>
|
||||
<uniform name="territoryTransform" loc="6" type="vec2"/>
|
||||
</vertex>
|
||||
|
||||
<fragment file="terrain_common.fp">
|
||||
<uniform name="baseTex" loc="0" type="sampler2D"/>
|
||||
<uniform name="shadowTex" loc="2" type="sampler2DShadow"/>
|
||||
<uniform name="losTex" loc="3" type="sampler2D"/>
|
||||
<uniform name="territoryTex" loc="4" type="sampler2D"/>
|
||||
|
||||
<uniform name="ambient" loc="0" type="vec3"/>
|
||||
<uniform name="shadowOffsets1" loc="2" type="vec4"/>
|
||||
|
@ -7,6 +7,7 @@
|
||||
<uniform name="sunColor" loc="0" type="vec3"/>
|
||||
<uniform name="losTransform" loc="1" type="vec2"/>
|
||||
<uniform name="shadowTransform" loc="2" type="mat4"/>
|
||||
<uniform name="territoryTransform" loc="6" type="vec2"/>
|
||||
</vertex>
|
||||
|
||||
<fragment file="terrain_common.fp">
|
||||
@ -14,6 +15,7 @@
|
||||
<uniform name="blendTex" loc="1" type="sampler2D"/>
|
||||
<uniform name="shadowTex" loc="2" type="sampler2DShadow"/>
|
||||
<uniform name="losTex" loc="3" type="sampler2D"/>
|
||||
<uniform name="territoryTex" loc="4" type="sampler2D"/>
|
||||
|
||||
<uniform name="ambient" loc="0" type="vec3"/>
|
||||
<uniform name="shadowOffsets1" loc="2" type="vec4"/>
|
||||
|
@ -81,6 +81,10 @@ TEX color, fragment.texcoord[0], texture[0], 2D;
|
||||
MUL color.rgb, color, temp;
|
||||
#endif
|
||||
|
||||
// Blend with the territory boundary texture
|
||||
TEX tex, fragment.texcoord[4], texture[4], 2D;
|
||||
LRP color.rgb, tex.a, tex, color;
|
||||
|
||||
// Multiply everything by the LOS texture
|
||||
TEX tex.a, fragment.texcoord[3], texture[3], 2D;
|
||||
MUL color.rgb, color, tex.a;
|
||||
|
@ -2,6 +2,7 @@
|
||||
PARAM sunColor = program.local[0];
|
||||
PARAM losTransform = program.local[1];
|
||||
PARAM shadowTransform[4] = { program.local[2..5] };
|
||||
PARAM territoryTransform = program.local[6];
|
||||
|
||||
TEMP lighting;
|
||||
|
||||
@ -38,5 +39,6 @@ MOV result.texcoord[0], vertex.texcoord[0];
|
||||
#endif
|
||||
|
||||
MAD result.texcoord[3], position.xzzz, losTransform.x, losTransform.y;
|
||||
MAD result.texcoord[4], position.xzzz, territoryTransform.x, territoryTransform.y;
|
||||
|
||||
END
|
||||
|
@ -7,12 +7,14 @@
|
||||
<uniform name="sunColor" loc="0" type="vec3"/>
|
||||
<uniform name="losTransform" loc="1" type="vec2"/>
|
||||
<uniform name="shadowTransform" loc="2" type="mat4"/>
|
||||
<uniform name="territoryTransform" loc="6" type="vec2"/>
|
||||
</vertex>
|
||||
|
||||
<fragment file="terrain_common.fp">
|
||||
<uniform name="baseTex" loc="0" type="sampler2D"/>
|
||||
<uniform name="shadowTex" loc="2" type="sampler2DShadow"/>
|
||||
<uniform name="losTex" loc="3" type="sampler2D"/>
|
||||
<uniform name="territoryTex" loc="4" type="sampler2D"/>
|
||||
|
||||
<uniform name="ambient" loc="0" type="vec3"/>
|
||||
<uniform name="shadingColor" loc="1" type="vec3"/>
|
||||
|
@ -1 +0,0 @@
|
||||
Engine.RegisterInterface("Settlement");
|
@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Entity>
|
||||
<Position>
|
||||
<Altitude>0</Altitude>
|
||||
<Anchor>upright</Anchor>
|
||||
<Floating>false</Floating>
|
||||
<TurnRate>6.0</TurnRate>
|
||||
</Position>
|
||||
<Footprint>
|
||||
<Square width="64" depth="8"/>
|
||||
<Height>9.0</Height>
|
||||
</Footprint>
|
||||
<Selectable/>
|
||||
<Obstruction>
|
||||
<Static width="64" depth="8"/>
|
||||
<Active>true</Active>
|
||||
<BlockMovement>false</BlockMovement>
|
||||
<BlockPathfinding>false</BlockPathfinding>
|
||||
<BlockFoundation>false</BlockFoundation>
|
||||
<BlockConstruction>false</BlockConstruction>
|
||||
<DisableBlockMovement>false</DisableBlockMovement>
|
||||
<DisableBlockPathfinding>false</DisableBlockPathfinding>
|
||||
</Obstruction>
|
||||
<Ownership/>
|
||||
<VisualActor>
|
||||
<SilhouetteDisplay>false</SilhouetteDisplay>
|
||||
<SilhouetteOccluder>true</SilhouetteOccluder>
|
||||
<Actor>structures/hellenes/wall_med.xml</Actor>
|
||||
</VisualActor>
|
||||
<TerritoryInfluence>
|
||||
<OverrideCost>100</OverrideCost>
|
||||
</TerritoryInfluence>
|
||||
</Entity>
|
@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Entity>
|
||||
<Position>
|
||||
<Altitude>0</Altitude>
|
||||
<Anchor>upright</Anchor>
|
||||
<Floating>false</Floating>
|
||||
<TurnRate>6.0</TurnRate>
|
||||
</Position>
|
||||
<Footprint>
|
||||
<Square width="64" depth="8"/>
|
||||
<Height>9.0</Height>
|
||||
</Footprint>
|
||||
<Selectable/>
|
||||
<Obstruction>
|
||||
<Static width="64" depth="8"/>
|
||||
<Active>true</Active>
|
||||
<BlockMovement>false</BlockMovement>
|
||||
<BlockPathfinding>false</BlockPathfinding>
|
||||
<BlockFoundation>false</BlockFoundation>
|
||||
<BlockConstruction>false</BlockConstruction>
|
||||
<DisableBlockMovement>false</DisableBlockMovement>
|
||||
<DisableBlockPathfinding>false</DisableBlockPathfinding>
|
||||
</Obstruction>
|
||||
<Ownership/>
|
||||
<VisualActor>
|
||||
<SilhouetteDisplay>false</SilhouetteDisplay>
|
||||
<SilhouetteOccluder>true</SilhouetteOccluder>
|
||||
<Actor>structures/hellenes/wall_med.xml</Actor>
|
||||
</VisualActor>
|
||||
<TerritoryInfluence>
|
||||
<OverrideCost>0</OverrideCost>
|
||||
</TerritoryInfluence>
|
||||
</Entity>
|
@ -31,6 +31,7 @@
|
||||
#include "graphics/SkeletonAnimManager.h"
|
||||
#include "graphics/Terrain.h"
|
||||
#include "graphics/TerrainTextureManager.h"
|
||||
#include "graphics/TerritoryTexture.h"
|
||||
#include "graphics/Unit.h"
|
||||
#include "graphics/UnitManager.h"
|
||||
#include "lib/input.h"
|
||||
@ -159,6 +160,7 @@ public:
|
||||
ColladaManager(), MeshManager(ColladaManager), SkeletonAnimManager(ColladaManager),
|
||||
ObjectManager(MeshManager, SkeletonAnimManager, *game->GetSimulation2()),
|
||||
LOSTexture(*game->GetSimulation2()),
|
||||
TerritoryTexture(*game->GetSimulation2()),
|
||||
ViewCamera(),
|
||||
CullCamera(),
|
||||
LockCullCamera(false),
|
||||
@ -204,6 +206,7 @@ public:
|
||||
CSkeletonAnimManager SkeletonAnimManager;
|
||||
CObjectManager ObjectManager;
|
||||
CLOSTexture LOSTexture;
|
||||
CTerritoryTexture TerritoryTexture;
|
||||
|
||||
/**
|
||||
* this camera controls the eye position when rendering
|
||||
@ -381,6 +384,11 @@ CLOSTexture& CGameView::GetLOSTexture()
|
||||
return m->LOSTexture;
|
||||
}
|
||||
|
||||
CTerritoryTexture& CGameView::GetTerritoryTexture()
|
||||
{
|
||||
return m->TerritoryTexture;
|
||||
}
|
||||
|
||||
|
||||
void CGameViewImpl::ScriptingInit()
|
||||
{
|
||||
|
@ -27,7 +27,6 @@ class CGame;
|
||||
class CObjectManager;
|
||||
class CCamera;
|
||||
class CCinemaManager;
|
||||
class CLOSTexture;
|
||||
class CVector3D;
|
||||
struct SViewPort;
|
||||
|
||||
@ -51,6 +50,7 @@ public:
|
||||
//BEGIN: Implementation of Scene
|
||||
virtual void EnumerateObjects(const CFrustum& frustum, SceneCollector* c);
|
||||
virtual CLOSTexture& GetLOSTexture();
|
||||
virtual CTerritoryTexture& GetTerritoryTexture();
|
||||
//END: Implementation of Scene
|
||||
|
||||
private:
|
||||
|
@ -23,7 +23,6 @@
|
||||
#include "lib/bits.h"
|
||||
#include "ps/Game.h"
|
||||
#include "ps/Profile.h"
|
||||
#include "ps/World.h"
|
||||
#include "renderer/Renderer.h"
|
||||
#include "simulation2/Simulation2.h"
|
||||
#include "simulation2/components/ICmpRangeManager.h"
|
||||
|
260
source/graphics/TerritoryTexture.cpp
Normal file
260
source/graphics/TerritoryTexture.cpp
Normal file
@ -0,0 +1,260 @@
|
||||
/* Copyright (C) 2011 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 "TerritoryTexture.h"
|
||||
|
||||
#include "graphics/Terrain.h"
|
||||
#include "lib/bits.h"
|
||||
#include "ps/Profile.h"
|
||||
#include "renderer/Renderer.h"
|
||||
#include "simulation2/Simulation2.h"
|
||||
#include "simulation2/components/ICmpTerrain.h"
|
||||
#include "simulation2/components/ICmpTerritoryManager.h"
|
||||
|
||||
// TODO: There's a lot of duplication with CLOSTexture - might be nice to refactor a bit
|
||||
|
||||
CTerritoryTexture::CTerritoryTexture(CSimulation2& simulation) :
|
||||
m_Simulation(simulation), m_DirtyID(0), m_Texture(0), m_MapSize(0), m_TextureSize(0)
|
||||
{
|
||||
}
|
||||
|
||||
CTerritoryTexture::~CTerritoryTexture()
|
||||
{
|
||||
if (m_Texture)
|
||||
DeleteTexture();
|
||||
}
|
||||
|
||||
void CTerritoryTexture::DeleteTexture()
|
||||
{
|
||||
glDeleteTextures(1, &m_Texture);
|
||||
m_Texture = 0;
|
||||
}
|
||||
|
||||
bool CTerritoryTexture::UpdateDirty()
|
||||
{
|
||||
CmpPtr<ICmpTerritoryManager> cmpTerritoryManager(m_Simulation, SYSTEM_ENTITY);
|
||||
if (cmpTerritoryManager.null())
|
||||
return false;
|
||||
|
||||
return cmpTerritoryManager->NeedUpdate(&m_DirtyID);
|
||||
}
|
||||
|
||||
void CTerritoryTexture::BindTexture(int unit)
|
||||
{
|
||||
if (UpdateDirty())
|
||||
RecomputeTexture(unit);
|
||||
|
||||
g_Renderer.BindTexture(unit, m_Texture);
|
||||
}
|
||||
|
||||
GLuint CTerritoryTexture::GetTexture()
|
||||
{
|
||||
if (UpdateDirty())
|
||||
RecomputeTexture(0);
|
||||
|
||||
return m_Texture;
|
||||
}
|
||||
|
||||
const float* CTerritoryTexture::GetTextureMatrix()
|
||||
{
|
||||
ENSURE(!UpdateDirty());
|
||||
return &m_TextureMatrix._11;
|
||||
}
|
||||
|
||||
const float* CTerritoryTexture::GetMinimapTextureMatrix()
|
||||
{
|
||||
ENSURE(!UpdateDirty());
|
||||
return &m_MinimapTextureMatrix._11;
|
||||
}
|
||||
|
||||
void CTerritoryTexture::ConstructTexture(int unit)
|
||||
{
|
||||
CmpPtr<ICmpTerrain> cmpTerrain(m_Simulation, SYSTEM_ENTITY);
|
||||
if (cmpTerrain.null())
|
||||
return;
|
||||
|
||||
m_MapSize = cmpTerrain->GetVerticesPerSide() - 1;
|
||||
|
||||
m_TextureSize = (GLsizei)round_up_to_pow2((size_t)m_MapSize);
|
||||
|
||||
glGenTextures(1, &m_Texture);
|
||||
g_Renderer.BindTexture(unit, m_Texture);
|
||||
|
||||
// Initialise texture with transparency, for the areas we don't
|
||||
// overwrite with glTexSubImage2D later
|
||||
u8* texData = new u8[m_TextureSize * m_TextureSize * 4];
|
||||
memset(texData, 0x00, m_TextureSize * m_TextureSize * 4);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_TextureSize, m_TextureSize, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, texData);
|
||||
delete[] texData;
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
{
|
||||
// Texture matrix: We want to map
|
||||
// world pos (0, y, 0) (i.e. bottom-left of first tile)
|
||||
// onto texcoord (0, 0) (i.e. bottom-left of first texel);
|
||||
// world pos (mapsize*cellsize, y, mapsize*cellsize) (i.e. top-right of last tile)
|
||||
// onto texcoord (mapsize / texsize, mapsize / texsize) (i.e. top-right of last texel)
|
||||
|
||||
float s = 1.f / (float)(m_TextureSize * CELL_SIZE);
|
||||
float t = 0.f;
|
||||
m_TextureMatrix.SetZero();
|
||||
m_TextureMatrix._11 = s;
|
||||
m_TextureMatrix._23 = s;
|
||||
m_TextureMatrix._14 = t;
|
||||
m_TextureMatrix._24 = t;
|
||||
m_TextureMatrix._44 = 1;
|
||||
}
|
||||
|
||||
{
|
||||
// Minimap matrix: We want to map UV (0,0)-(1,1) onto (0,0)-(mapsize/texsize, mapsize/texsize)
|
||||
|
||||
float s = m_MapSize / (float)m_TextureSize;
|
||||
m_MinimapTextureMatrix.SetZero();
|
||||
m_MinimapTextureMatrix._11 = s;
|
||||
m_MinimapTextureMatrix._22 = s;
|
||||
m_MinimapTextureMatrix._44 = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void CTerritoryTexture::RecomputeTexture(int unit)
|
||||
{
|
||||
// If the map was resized, delete and regenerate the texture
|
||||
if (m_Texture)
|
||||
{
|
||||
CmpPtr<ICmpTerrain> cmpTerrain(m_Simulation, SYSTEM_ENTITY);
|
||||
if (!cmpTerrain.null() && m_MapSize != (ssize_t)cmpTerrain->GetVerticesPerSide())
|
||||
DeleteTexture();
|
||||
}
|
||||
|
||||
if (!m_Texture)
|
||||
ConstructTexture(unit);
|
||||
|
||||
PROFILE("recompute territory texture");
|
||||
|
||||
std::vector<u8> bitmap;
|
||||
bitmap.resize(m_MapSize * m_MapSize * 4);
|
||||
|
||||
CmpPtr<ICmpTerritoryManager> cmpTerritoryManager(m_Simulation, SYSTEM_ENTITY);
|
||||
if (cmpTerritoryManager.null())
|
||||
return;
|
||||
|
||||
const Grid<u8> territories = cmpTerritoryManager->GetTerritoryGrid();
|
||||
|
||||
GenerateBitmap(territories, &bitmap[0], m_MapSize, m_MapSize);
|
||||
|
||||
g_Renderer.BindTexture(unit, m_Texture);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_MapSize, m_MapSize, GL_BGRA_EXT, GL_UNSIGNED_BYTE, &bitmap[0]);
|
||||
}
|
||||
|
||||
void CTerritoryTexture::GenerateBitmap(const Grid<u8>& territories, u8* bitmap, ssize_t w, ssize_t h)
|
||||
{
|
||||
int alphaMax = 0xC0;
|
||||
int alphaFalloff = 0x20;
|
||||
|
||||
u8* p = bitmap;
|
||||
for (ssize_t j = 0; j < h; ++j)
|
||||
{
|
||||
for (ssize_t i = 0; i < w; ++i)
|
||||
{
|
||||
u8 val = territories.get(i, j);
|
||||
switch (val)
|
||||
{
|
||||
// TODO: use player colours or something
|
||||
case 1: *p++ = 0x00; *p++ = 0x00; *p++ = 0xFF; break;
|
||||
case 2: *p++ = 0x00; *p++ = 0xFF; *p++ = 0x00; break;
|
||||
case 3: *p++ = 0xFF; *p++ = 0x00; *p++ = 0x00; break;
|
||||
case 4: *p++ = 0x00; *p++ = 0xFF; *p++ = 0xFF; break;
|
||||
case 5: *p++ = 0xFF; *p++ = 0xFF; *p++ = 0x00; break;
|
||||
case 6: *p++ = 0xFF; *p++ = 0x00; *p++ = 0xFF; break;
|
||||
default: *p++ = 0xFF; *p++ = 0xFF; *p++ = 0xFF; break;
|
||||
}
|
||||
|
||||
if ((i > 0 && territories.get(i-1, j) != val)
|
||||
|| (i < w-1 && territories.get(i+1, j) != val)
|
||||
|| (j > 0 && territories.get(i, j-1) != val)
|
||||
|| (j < h-1 && territories.get(i, j+1) != val)
|
||||
// || (i > 0 && j > 0 && territories.get(i-1, j-1) != val)
|
||||
// || (i < w-1 && j > 0 && territories.get(i+1, j-1) != val)
|
||||
// || (i > 0 && j > h-1 && territories.get(i-1, j+1) != val)
|
||||
// || (i < w-1 && j < h-1 && territories.get(i+1, j+1) != val)
|
||||
)
|
||||
{
|
||||
*p++ = alphaMax;
|
||||
}
|
||||
else
|
||||
{
|
||||
*p++ = 0x00;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Do a low-quality cheap blur effect
|
||||
|
||||
for (ssize_t j = 0; j < h; ++j)
|
||||
{
|
||||
int a;
|
||||
|
||||
a = 0;
|
||||
for (ssize_t i = 0; i < w; ++i)
|
||||
{
|
||||
a = std::max(a - alphaFalloff, (int)bitmap[(j*w+i)*4 + 3]);
|
||||
bitmap[(j*w+i)*4 + 3] = a;
|
||||
}
|
||||
|
||||
a = 0;
|
||||
for (ssize_t i = w-1; i >= 0; --i)
|
||||
{
|
||||
a = std::max(a - alphaFalloff, (int)bitmap[(j*w+i)*4 + 3]);
|
||||
bitmap[(j*w+i)*4 + 3] = a;
|
||||
}
|
||||
}
|
||||
|
||||
for (ssize_t i = 0; i < w; ++i)
|
||||
{
|
||||
int a;
|
||||
|
||||
a = 0;
|
||||
for (ssize_t j = 0; j < w; ++j)
|
||||
{
|
||||
a = std::max(a - alphaFalloff, (int)bitmap[(j*w+i)*4 + 3]);
|
||||
bitmap[(j*w+i)*4 + 3] = a;
|
||||
}
|
||||
|
||||
a = 0;
|
||||
for (ssize_t j = w-1; j >= 0; --j)
|
||||
{
|
||||
a = std::max(a - alphaFalloff, (int)bitmap[(j*w+i)*4 + 3]);
|
||||
bitmap[(j*w+i)*4 + 3] = a;
|
||||
}
|
||||
}
|
||||
|
||||
// Add a gap between the boundaries, by deleting the max-alpha tiles
|
||||
for (ssize_t j = 0; j < h; ++j)
|
||||
{
|
||||
for (ssize_t i = 0; i < w; ++i)
|
||||
{
|
||||
if (bitmap[(j*w+i)*4 + 3] == alphaMax)
|
||||
bitmap[(j*w+i)*4 + 3] = 0;
|
||||
}
|
||||
}
|
||||
}
|
89
source/graphics/TerritoryTexture.h
Normal file
89
source/graphics/TerritoryTexture.h
Normal file
@ -0,0 +1,89 @@
|
||||
/* Copyright (C) 2011 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 "lib/ogl.h"
|
||||
|
||||
#include "maths/Matrix3D.h"
|
||||
#include "simulation2/helpers/Grid.h"
|
||||
|
||||
class CSimulation2;
|
||||
|
||||
/**
|
||||
* Maintains the territory boundary texture, used for
|
||||
* rendering and for the minimap.
|
||||
*/
|
||||
class CTerritoryTexture
|
||||
{
|
||||
NONCOPYABLE(CTerritoryTexture);
|
||||
|
||||
public:
|
||||
CTerritoryTexture(CSimulation2& simulation);
|
||||
~CTerritoryTexture();
|
||||
|
||||
/**
|
||||
* Recomputes the territory texture if necessary, and binds it to the requested
|
||||
* texture unit.
|
||||
* Also switches the current active texture unit, and enables texturing on it.
|
||||
* The texture is in 32-bit BGRA format.
|
||||
*/
|
||||
void BindTexture(int unit);
|
||||
|
||||
/**
|
||||
* Recomputes the territory texture if necessary, and returns the texture handle.
|
||||
* Also potentially switches the current active texture unit, and enables texturing on it.
|
||||
* The texture is in 32-bit BGRA format.
|
||||
*/
|
||||
GLuint GetTexture();
|
||||
|
||||
/**
|
||||
* Returns a matrix to map (x,y,z) world coordinates onto (u,v) texture
|
||||
* coordinates, in the form expected by glLoadMatrixf.
|
||||
* This must only be called after BindTexture.
|
||||
*/
|
||||
const float* GetTextureMatrix();
|
||||
|
||||
/**
|
||||
* Returns a matrix to map (0,0)-(1,1) texture coordinates onto texture
|
||||
* coordinates, in the form expected by glLoadMatrixf.
|
||||
* This must only be called after BindTexture.
|
||||
*/
|
||||
const float* GetMinimapTextureMatrix();
|
||||
|
||||
private:
|
||||
/**
|
||||
* Returns true if the territory state has changed since the last call to this function
|
||||
*/
|
||||
bool UpdateDirty();
|
||||
|
||||
void DeleteTexture();
|
||||
void ConstructTexture(int unit);
|
||||
void RecomputeTexture(int unit);
|
||||
|
||||
void GenerateBitmap(const Grid<u8>& territories, u8* bitmap, ssize_t w, ssize_t h);
|
||||
|
||||
CSimulation2& m_Simulation;
|
||||
|
||||
size_t m_DirtyID;
|
||||
|
||||
GLuint m_Texture;
|
||||
|
||||
ssize_t m_MapSize; // tiles per side
|
||||
GLsizei m_TextureSize; // texels per side
|
||||
|
||||
CMatrix3D m_TextureMatrix;
|
||||
CMatrix3D m_MinimapTextureMatrix;
|
||||
};
|
@ -27,6 +27,7 @@
|
||||
#include "graphics/Terrain.h"
|
||||
#include "graphics/TerrainTextureEntry.h"
|
||||
#include "graphics/TerrainTextureManager.h"
|
||||
#include "graphics/TerritoryTexture.h"
|
||||
#include "lib/ogl.h"
|
||||
#include "lib/external_libraries/sdl.h"
|
||||
#include "lib/bits.h"
|
||||
@ -39,6 +40,7 @@
|
||||
#include "scriptinterface/ScriptInterface.h"
|
||||
#include "simulation2/Simulation2.h"
|
||||
#include "simulation2/components/ICmpMinimap.h"
|
||||
#include "simulation2/components/ICmpTerritoryManager.h"
|
||||
|
||||
bool g_GameRestarted = false;
|
||||
|
||||
@ -310,58 +312,22 @@ void CMiniMap::Draw()
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
DrawTexture(texCoordMax, angle, x, y, x2, y2, z);
|
||||
|
||||
/* // TODO: reimplement with new sim system
|
||||
// Shade territories by player
|
||||
CTerritoryManager* territoryMgr = g_Game->GetWorld()->GetTerritoryManager();
|
||||
std::vector<CTerritory*>& territories = territoryMgr->GetTerritories();
|
||||
|
||||
PROFILE_START("minimap territory shade");
|
||||
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
for( size_t i=0; i<territories.size(); i++ )
|
||||
{
|
||||
if( territories[i]->owner->GetPlayerID() == 0 )
|
||||
continue;
|
||||
std::vector<CVector2D>& boundary = territories[i]->boundary;
|
||||
SPlayerColour col = territories[i]->owner->GetColour();
|
||||
glColor4f(col.r, col.g, col.b, 0.25f);
|
||||
glBegin(GL_POLYGON);
|
||||
for( size_t j=0; j<boundary.size(); j++ )
|
||||
{
|
||||
float fx = boundary[j].x / (m_Terrain->GetTilesPerSide() * CELL_SIZE);
|
||||
float fy = boundary[j].y / (m_Terrain->GetTilesPerSide() * CELL_SIZE);
|
||||
glVertex3f( x*(1-fx) + x2*fx, y*(1-fy) + y2*fy, z );
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
PROFILE_END("minimap territory shade");
|
||||
|
||||
// Draw territory boundaries
|
||||
glEnable(GL_LINE_SMOOTH);
|
||||
glLineWidth(1.0f);
|
||||
CTerritoryTexture& territoryTexture = g_Game->GetView()->GetTerritoryTexture();
|
||||
territoryTexture.BindTexture(0);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glColor4f(0.8f, 0.8f, 0.8f, 0.8f);
|
||||
for( size_t i=0; i<territories.size(); i++ )
|
||||
{
|
||||
std::vector<CVector2D>& boundary = territories[i]->boundary;
|
||||
glBegin(GL_LINE_LOOP);
|
||||
for( size_t j=0; j<boundary.size(); j++ )
|
||||
{
|
||||
float fx = boundary[j].x / (m_Terrain->GetTilesPerSide() * CELL_SIZE);
|
||||
float fy = boundary[j].y / (m_Terrain->GetTilesPerSide() * CELL_SIZE);
|
||||
glVertex3f( x*(1-fx) + x2*fx, y*(1-fy) + y2*fy, z );
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
glLineWidth(1.0f);
|
||||
glDisable(GL_LINE_SMOOTH);
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
glLoadMatrixf(territoryTexture.GetMinimapTextureMatrix());
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
|
||||
DrawTexture(1.0f, angle, x, y, x2, y2, z);
|
||||
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
glLoadIdentity();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glDisable(GL_BLEND);
|
||||
*/
|
||||
|
||||
|
||||
// Draw the LOS quad in black, using alpha values from the LOS texture
|
||||
CLOSTexture& losTexture = g_Game->GetView()->GetLOSTexture();
|
||||
|
@ -35,6 +35,7 @@ class CModelDecal;
|
||||
class CParticleEmitter;
|
||||
class CPatch;
|
||||
class CLOSTexture;
|
||||
class CTerritoryTexture;
|
||||
struct SOverlayLine;
|
||||
struct SOverlaySprite;
|
||||
|
||||
@ -63,6 +64,11 @@ public:
|
||||
* Return the LOS texture to be used for rendering this scene.
|
||||
*/
|
||||
virtual CLOSTexture& GetLOSTexture() = 0;
|
||||
|
||||
/**
|
||||
* Return the territory texture to be used for rendering this scene.
|
||||
*/
|
||||
virtual CTerritoryTexture& GetTerritoryTexture() = 0;
|
||||
};
|
||||
|
||||
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "graphics/GameView.h"
|
||||
#include "graphics/Model.h"
|
||||
#include "graphics/ShaderManager.h"
|
||||
#include "graphics/TerritoryTexture.h"
|
||||
|
||||
#include "maths/MathUtil.h"
|
||||
|
||||
@ -401,6 +402,10 @@ void TerrainRenderer::PrepareShader(const CShaderProgramPtr& shader, ShadowMap*
|
||||
shader->BindTexture("losTex", los.GetTexture());
|
||||
shader->Uniform("losTransform", los.GetTextureMatrix()[0], los.GetTextureMatrix()[12], 0.f, 0.f);
|
||||
|
||||
CTerritoryTexture& territory = g_Renderer.GetScene().GetTerritoryTexture();
|
||||
shader->BindTexture("territoryTex", territory.GetTexture());
|
||||
shader->Uniform("territoryTransform", territory.GetTextureMatrix()[0], territory.GetTextureMatrix()[12], 0.f, 0.f);
|
||||
|
||||
shader->Uniform("ambient", lightEnv.m_TerrainAmbientColor);
|
||||
shader->Uniform("sunColor", lightEnv.m_SunColor);
|
||||
}
|
||||
|
@ -84,6 +84,7 @@ public:
|
||||
m_ComponentManager.AddComponent(SYSTEM_ENTITY, CID_RangeManager, noParam);
|
||||
m_ComponentManager.AddComponent(SYSTEM_ENTITY, CID_SoundManager, noParam);
|
||||
m_ComponentManager.AddComponent(SYSTEM_ENTITY, CID_Terrain, noParam);
|
||||
m_ComponentManager.AddComponent(SYSTEM_ENTITY, CID_TerritoryManager, noParam);
|
||||
m_ComponentManager.AddComponent(SYSTEM_ENTITY, CID_WaterManager, noParam);
|
||||
|
||||
if (!skipAI)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2010 Wildfire Games.
|
||||
/* Copyright (C) 2011 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -119,12 +119,21 @@ COMPONENT(RangeManager)
|
||||
INTERFACE(Selectable)
|
||||
COMPONENT(Selectable)
|
||||
|
||||
INTERFACE(Settlement)
|
||||
COMPONENT(SettlementScripted)
|
||||
|
||||
INTERFACE(SoundManager)
|
||||
COMPONENT(SoundManager)
|
||||
|
||||
INTERFACE(Terrain)
|
||||
COMPONENT(Terrain)
|
||||
|
||||
INTERFACE(TerritoryInfluence)
|
||||
COMPONENT(TerritoryInfluence)
|
||||
|
||||
INTERFACE(TerritoryManager)
|
||||
COMPONENT(TerritoryManager)
|
||||
|
||||
INTERFACE(UnitMotion)
|
||||
COMPONENT(UnitMotion) // must be after Obstruction
|
||||
COMPONENT(UnitMotionScripted)
|
||||
|
67
source/simulation2/components/CCmpTerritoryInfluence.cpp
Normal file
67
source/simulation2/components/CCmpTerritoryInfluence.cpp
Normal file
@ -0,0 +1,67 @@
|
||||
/* Copyright (C) 2011 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 "simulation2/system/Component.h"
|
||||
#include "ICmpTerritoryInfluence.h"
|
||||
|
||||
class CCmpTerritoryInfluence : public ICmpTerritoryInfluence
|
||||
{
|
||||
public:
|
||||
static void ClassInit(CComponentManager& UNUSED(componentManager))
|
||||
{
|
||||
}
|
||||
|
||||
DEFAULT_COMPONENT_ALLOCATOR(TerritoryInfluence)
|
||||
|
||||
u8 m_Cost;
|
||||
|
||||
static std::string GetSchema()
|
||||
{
|
||||
return
|
||||
"<element name='OverrideCost'>"
|
||||
"<data type='nonNegativeInteger'/>"
|
||||
"</element>";
|
||||
}
|
||||
|
||||
virtual void Init(const CParamNode& paramNode)
|
||||
{
|
||||
m_Cost = paramNode.GetChild("OverrideCost").ToInt();
|
||||
}
|
||||
|
||||
virtual void Deinit()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void Serialize(ISerializer& UNUSED(serialize))
|
||||
{
|
||||
}
|
||||
|
||||
virtual void Deserialize(const CParamNode& paramNode, IDeserializer& UNUSED(deserialize))
|
||||
{
|
||||
Init(paramNode);
|
||||
}
|
||||
|
||||
virtual u8 GetCost()
|
||||
{
|
||||
return m_Cost;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
REGISTER_COMPONENT_TYPE(TerritoryInfluence)
|
401
source/simulation2/components/CCmpTerritoryManager.cpp
Normal file
401
source/simulation2/components/CCmpTerritoryManager.cpp
Normal file
@ -0,0 +1,401 @@
|
||||
/* Copyright (C) 2011 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 "simulation2/system/Component.h"
|
||||
#include "ICmpTerritoryManager.h"
|
||||
|
||||
#include "graphics/Terrain.h"
|
||||
#include "maths/MathUtil.h"
|
||||
#include "ps/Overlay.h"
|
||||
#include "renderer/TerrainOverlay.h"
|
||||
#include "simulation2/MessageTypes.h"
|
||||
#include "simulation2/components/ICmpObstruction.h"
|
||||
#include "simulation2/components/ICmpObstructionManager.h"
|
||||
#include "simulation2/components/ICmpPathfinder.h"
|
||||
#include "simulation2/components/ICmpPosition.h"
|
||||
#include "simulation2/components/ICmpSettlement.h"
|
||||
#include "simulation2/components/ICmpTerrain.h"
|
||||
#include "simulation2/components/ICmpTerritoryInfluence.h"
|
||||
#include "simulation2/helpers/Geometry.h"
|
||||
#include "simulation2/helpers/Grid.h"
|
||||
#include "simulation2/helpers/PriorityQueue.h"
|
||||
|
||||
class CCmpTerritoryManager;
|
||||
|
||||
class TerritoryOverlay : public TerrainOverlay
|
||||
{
|
||||
NONCOPYABLE(TerritoryOverlay);
|
||||
public:
|
||||
CCmpTerritoryManager& m_TerritoryManager;
|
||||
|
||||
TerritoryOverlay(CCmpTerritoryManager& manager) : m_TerritoryManager(manager) { }
|
||||
virtual void StartRender();
|
||||
virtual void ProcessTile(ssize_t i, ssize_t j);
|
||||
};
|
||||
|
||||
class CCmpTerritoryManager : public ICmpTerritoryManager
|
||||
{
|
||||
public:
|
||||
static void ClassInit(CComponentManager& componentManager)
|
||||
{
|
||||
componentManager.SubscribeGloballyToMessageType(MT_OwnershipChanged);
|
||||
componentManager.SubscribeGloballyToMessageType(MT_PositionChanged);
|
||||
componentManager.SubscribeToMessageType(MT_TerrainChanged);
|
||||
}
|
||||
|
||||
DEFAULT_COMPONENT_ALLOCATOR(TerritoryManager)
|
||||
|
||||
static std::string GetSchema()
|
||||
{
|
||||
return "<a:component type='system'/><empty/>";
|
||||
}
|
||||
|
||||
Grid<u8>* m_Territories;
|
||||
TerritoryOverlay* m_DebugOverlay;
|
||||
|
||||
virtual void Init(const CParamNode& UNUSED(paramNode))
|
||||
{
|
||||
m_Territories = NULL;
|
||||
m_DebugOverlay = NULL;
|
||||
// m_DebugOverlay = new TerritoryOverlay(*this);
|
||||
|
||||
m_DirtyID = 1;
|
||||
}
|
||||
|
||||
virtual void Deinit()
|
||||
{
|
||||
SAFE_DELETE(m_Territories);
|
||||
SAFE_DELETE(m_DebugOverlay);
|
||||
}
|
||||
|
||||
virtual void Serialize(ISerializer& serialize)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
virtual void Deserialize(const CParamNode& paramNode, IDeserializer& deserialize)
|
||||
{
|
||||
Init(paramNode);
|
||||
}
|
||||
|
||||
virtual void HandleMessage(const CMessage& msg, bool UNUSED(global))
|
||||
{
|
||||
switch (msg.GetType())
|
||||
{
|
||||
case MT_OwnershipChanged:
|
||||
{
|
||||
const CMessageOwnershipChanged& msgData = static_cast<const CMessageOwnershipChanged&> (msg);
|
||||
MakeDirtyIfRelevantEntity(msgData.entity);
|
||||
break;
|
||||
}
|
||||
case MT_PositionChanged:
|
||||
{
|
||||
const CMessagePositionChanged& msgData = static_cast<const CMessagePositionChanged&> (msg);
|
||||
MakeDirtyIfRelevantEntity(msgData.entity);
|
||||
break;
|
||||
}
|
||||
case MT_TerrainChanged:
|
||||
{
|
||||
MakeDirty();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check whether the entity is either a settlement or territory influence;
|
||||
// ignore any others
|
||||
void MakeDirtyIfRelevantEntity(entity_id_t ent)
|
||||
{
|
||||
CmpPtr<ICmpSettlement> cmpSettlement(GetSimContext(), ent);
|
||||
if (!cmpSettlement.null())
|
||||
MakeDirty();
|
||||
|
||||
CmpPtr<ICmpTerritoryInfluence> cmpTerritoryInfluence(GetSimContext(), ent);
|
||||
if (!cmpTerritoryInfluence.null())
|
||||
MakeDirty();
|
||||
}
|
||||
|
||||
virtual const Grid<u8>& GetTerritoryGrid()
|
||||
{
|
||||
CalculateTerritories();
|
||||
return *m_Territories;
|
||||
}
|
||||
|
||||
// To support lazy updates of territory render data,
|
||||
// we maintain a DirtyID here and increment it whenever territories change;
|
||||
// if a caller has a lower DirtyID then it needs to be updated.
|
||||
|
||||
size_t m_DirtyID;
|
||||
|
||||
void MakeDirty()
|
||||
{
|
||||
SAFE_DELETE(m_Territories);
|
||||
++m_DirtyID;
|
||||
}
|
||||
|
||||
virtual bool NeedUpdate(size_t* dirtyID)
|
||||
{
|
||||
ENSURE(*dirtyID <= m_DirtyID);
|
||||
if (*dirtyID < m_DirtyID)
|
||||
{
|
||||
*dirtyID = m_DirtyID;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void CalculateTerritories();
|
||||
|
||||
/**
|
||||
* Updates @p grid based on the obstruction shapes of all entities with
|
||||
* a TerritoryInfluence component. Grid cells are 0 if no influence,
|
||||
* or 1+c if the influence have cost c (assumed between 0 and 254).
|
||||
*/
|
||||
void RasteriseInfluences(Grid<u8>& grid);
|
||||
};
|
||||
|
||||
REGISTER_COMPONENT_TYPE(TerritoryManager)
|
||||
|
||||
|
||||
/*
|
||||
|
||||
We compute territory influences with a kind of best-first search:
|
||||
1) Initialise an 'open' list with tiles that contain settlements (annotated with
|
||||
territory ID) with initial cost 0
|
||||
2) Pick the lowest cost tile from 'item'
|
||||
3) For each neighbour which has not already been assigned to a territory,
|
||||
assign it to this territory and compute its new cost (effectively the
|
||||
distance from the associated settlement) and add to 'open'
|
||||
4) Go to 2 until 'open' is empty
|
||||
|
||||
*/
|
||||
|
||||
typedef PriorityQueueHeap<std::pair<u16, u16>, u32> OpenQueue;
|
||||
|
||||
static void ProcessNeighbour(u8 pid, u16 i, u16 j, u32 pg, bool diagonal,
|
||||
Grid<u8>& grid, OpenQueue& queue, const Grid<u8>& influenceGrid)
|
||||
{
|
||||
// Ignore tiles that are already claimed
|
||||
u8 id = grid.get(i, j);
|
||||
if (id)
|
||||
return;
|
||||
|
||||
// Base cost for moving onto this tile
|
||||
u32 dg = diagonal ? 362 : 256;
|
||||
|
||||
// Adjust cost based on this tile's influences
|
||||
dg *= influenceGrid.get(i, j);
|
||||
|
||||
u32 g = pg + dg; // cost to this tile = cost to predecessor + delta from predecessor
|
||||
|
||||
grid.set(i, j, pid);
|
||||
OpenQueue::Item tile = { std::make_pair(i, j), g };
|
||||
queue.push(tile);
|
||||
}
|
||||
|
||||
void CCmpTerritoryManager::CalculateTerritories()
|
||||
{
|
||||
PROFILE("CalculateTerritories");
|
||||
|
||||
if (m_Territories)
|
||||
return;
|
||||
|
||||
CmpPtr<ICmpTerrain> cmpTerrain(GetSimContext(), SYSTEM_ENTITY);
|
||||
uint32_t tilesW = cmpTerrain->GetVerticesPerSide() - 1;
|
||||
uint32_t tilesH = cmpTerrain->GetVerticesPerSide() - 1;
|
||||
|
||||
Grid<u8> influenceGrid(tilesW, tilesH);
|
||||
|
||||
RasteriseInfluences(influenceGrid);
|
||||
|
||||
SAFE_DELETE(m_Territories);
|
||||
m_Territories = new Grid<u8>(tilesW, tilesH);
|
||||
|
||||
CmpPtr<ICmpPathfinder> cmpPathfinder(GetSimContext(), SYSTEM_ENTITY);
|
||||
ICmpPathfinder::pass_class_t passClass = cmpPathfinder->GetPassabilityClass("default");
|
||||
const Grid<u16>& passGrid = cmpPathfinder->GetPassabilityGrid();
|
||||
|
||||
// Adjust influenceGrid so it contains terrain-passability-dependent costs,
|
||||
// unless overridden by existing values in influenceGrid
|
||||
for (u32 j = 0; j < tilesH; ++j)
|
||||
{
|
||||
for (u32 i = 0; i < tilesW; ++i)
|
||||
{
|
||||
u8 cost;
|
||||
u8 inflCost = influenceGrid.get(i, j);
|
||||
if (inflCost)
|
||||
{
|
||||
cost = inflCost-1; // undo RasteriseInfluences's offset
|
||||
}
|
||||
else
|
||||
{
|
||||
if (passGrid.get(i, j) & passClass)
|
||||
cost = 100;
|
||||
else
|
||||
cost = 1;
|
||||
}
|
||||
influenceGrid.set(i, j, cost);
|
||||
}
|
||||
}
|
||||
|
||||
OpenQueue openTiles;
|
||||
|
||||
// Initialise open list with all settlements
|
||||
|
||||
CComponentManager::InterfaceList settlements = GetSimContext().GetComponentManager().GetEntitiesWithInterface(IID_Settlement);
|
||||
u8 id = 1;
|
||||
for (CComponentManager::InterfaceList::iterator it = settlements.begin(); it != settlements.end(); ++it)
|
||||
{
|
||||
entity_id_t settlement = it->first;
|
||||
CmpPtr<ICmpPosition> cmpPosition(GetSimContext(), settlement);
|
||||
if (cmpPosition.null() || !cmpPosition->IsInWorld())
|
||||
continue;
|
||||
|
||||
// TODO: maybe we need to ignore settlements with owner -1,
|
||||
// since they're probably destroyed
|
||||
|
||||
CFixedVector2D pos = cmpPosition->GetPosition2D();
|
||||
int i = clamp((pos.X / (int)CELL_SIZE).ToInt_RoundToNegInfinity(), 0, (int)tilesW-1);
|
||||
int j = clamp((pos.Y / (int)CELL_SIZE).ToInt_RoundToNegInfinity(), 0, (int)tilesH-1);
|
||||
|
||||
// Must avoid duplicates in the priority queue; ignore the settlement
|
||||
// if there's already one on that tile
|
||||
if (!m_Territories->get(i, j))
|
||||
{
|
||||
m_Territories->set(i, j, id);
|
||||
OpenQueue::Item tile = { std::make_pair((u16)i, (i16)j), 0 };
|
||||
openTiles.push(tile);
|
||||
}
|
||||
|
||||
id += 1;
|
||||
}
|
||||
|
||||
while (!openTiles.empty())
|
||||
{
|
||||
OpenQueue::Item tile = openTiles.pop();
|
||||
|
||||
// Get current tile's territory ID
|
||||
u8 tid = m_Territories->get(tile.id.first, tile.id.second);
|
||||
|
||||
// Process neighbours (if they're not off the edge of the map)
|
||||
u16 x = tile.id.first;
|
||||
u16 z = tile.id.second;
|
||||
if (x > 0)
|
||||
ProcessNeighbour(tid, x-1, z, tile.rank, false, *m_Territories, openTiles, influenceGrid);
|
||||
if (x < tilesW-1)
|
||||
ProcessNeighbour(tid, x+1, z, tile.rank, false, *m_Territories, openTiles, influenceGrid);
|
||||
if (z > 0)
|
||||
ProcessNeighbour(tid, x, z-1, tile.rank, false, *m_Territories, openTiles, influenceGrid);
|
||||
if (z < tilesH-1)
|
||||
ProcessNeighbour(tid, x, z+1, tile.rank, false, *m_Territories, openTiles, influenceGrid);
|
||||
if (x > 0 && z > 0)
|
||||
ProcessNeighbour(tid, x-1, z-1, tile.rank, true, *m_Territories, openTiles, influenceGrid);
|
||||
if (x > 0 && z < tilesH-1)
|
||||
ProcessNeighbour(tid, x-1, z+1, tile.rank, true, *m_Territories, openTiles, influenceGrid);
|
||||
if (x < tilesW-1 && z > 0)
|
||||
ProcessNeighbour(tid, x+1, z-1, tile.rank, true, *m_Territories, openTiles, influenceGrid);
|
||||
if (x < tilesW-1 && z < tilesH-1)
|
||||
ProcessNeighbour(tid, x+1, z+1, tile.rank, true, *m_Territories, openTiles, influenceGrid);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the tile indexes on the grid nearest to a given point
|
||||
*/
|
||||
static void NearestTile(entity_pos_t x, entity_pos_t z, u16& i, u16& j, u16 w, u16 h)
|
||||
{
|
||||
i = clamp((x / (int)CELL_SIZE).ToInt_RoundToZero(), 0, w-1);
|
||||
j = clamp((z / (int)CELL_SIZE).ToInt_RoundToZero(), 0, h-1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the position of the center of the given tile
|
||||
*/
|
||||
static void TileCenter(u16 i, u16 j, entity_pos_t& x, entity_pos_t& z)
|
||||
{
|
||||
x = entity_pos_t::FromInt(i*(int)CELL_SIZE + CELL_SIZE/2);
|
||||
z = entity_pos_t::FromInt(j*(int)CELL_SIZE + CELL_SIZE/2);
|
||||
}
|
||||
|
||||
// TODO: would be nice not to duplicate those two functions from CCmpObstructionManager.cpp
|
||||
|
||||
|
||||
void CCmpTerritoryManager::RasteriseInfluences(Grid<u8>& grid)
|
||||
{
|
||||
CComponentManager::InterfaceList infls = GetSimContext().GetComponentManager().GetEntitiesWithInterface(IID_TerritoryInfluence);
|
||||
for (CComponentManager::InterfaceList::iterator it = infls.begin(); it != infls.end(); ++it)
|
||||
{
|
||||
ICmpTerritoryInfluence* cmpTerritoryInfluence = static_cast<ICmpTerritoryInfluence*>(it->second);
|
||||
|
||||
CmpPtr<ICmpObstruction> cmpObstruction(GetSimContext(), it->first);
|
||||
if (cmpObstruction.null())
|
||||
continue;
|
||||
|
||||
ICmpObstructionManager::ObstructionSquare square;
|
||||
if (!cmpObstruction->GetObstructionSquare(square))
|
||||
continue;
|
||||
|
||||
u8 cost = cmpTerritoryInfluence->GetCost();
|
||||
|
||||
CFixedVector2D halfSize(square.hw, square.hh);
|
||||
CFixedVector2D halfBound = Geometry::GetHalfBoundingBox(square.u, square.v, halfSize);
|
||||
|
||||
u16 i0, j0, i1, j1;
|
||||
NearestTile(square.x - halfBound.X, square.z - halfBound.Y, i0, j0, grid.m_W, grid.m_H);
|
||||
NearestTile(square.x + halfBound.X, square.z + halfBound.Y, i1, j1, grid.m_W, grid.m_H);
|
||||
for (u16 j = j0; j <= j1; ++j)
|
||||
{
|
||||
for (u16 i = i0; i <= i1; ++i)
|
||||
{
|
||||
entity_pos_t x, z;
|
||||
TileCenter(i, j, x, z);
|
||||
if (Geometry::PointIsInSquare(CFixedVector2D(x - square.x, z - square.z), square.u, square.v, halfSize))
|
||||
grid.set(i, j, cost+1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void TerritoryOverlay::StartRender()
|
||||
{
|
||||
m_TerritoryManager.CalculateTerritories();
|
||||
}
|
||||
|
||||
void TerritoryOverlay::ProcessTile(ssize_t i, ssize_t j)
|
||||
{
|
||||
if (!m_TerritoryManager.m_Territories)
|
||||
return;
|
||||
|
||||
u8 id = m_TerritoryManager.m_Territories->get(i, j);
|
||||
|
||||
float a = 0.2f;
|
||||
switch (id)
|
||||
{
|
||||
case 0: break;
|
||||
case 1: RenderTile(CColor(1, 0, 0, a), false); break;
|
||||
case 2: RenderTile(CColor(0, 1, 0, a), false); break;
|
||||
case 3: RenderTile(CColor(0, 0, 1, a), false); break;
|
||||
case 4: RenderTile(CColor(1, 1, 0, a), false); break;
|
||||
case 5: RenderTile(CColor(0, 1, 1, a), false); break;
|
||||
case 6: RenderTile(CColor(1, 0, 1, a), false); break;
|
||||
default: RenderTile(CColor(1, 1, 1, a), false); break;
|
||||
}
|
||||
}
|
@ -32,6 +32,11 @@ public:
|
||||
|
||||
virtual ICmpObstructionManager::tag_t GetObstruction() = 0;
|
||||
|
||||
/**
|
||||
* Gets the square corresponding to this obstruction shape.
|
||||
* @return true and updates @p out on success;
|
||||
* false on failure (e.g. object not in the world).
|
||||
*/
|
||||
virtual bool GetObstructionSquare(ICmpObstructionManager::ObstructionSquare& out) = 0;
|
||||
|
||||
virtual entity_pos_t GetUnitRadius() = 0;
|
||||
|
35
source/simulation2/components/ICmpSettlement.cpp
Normal file
35
source/simulation2/components/ICmpSettlement.cpp
Normal file
@ -0,0 +1,35 @@
|
||||
/* Copyright (C) 2011 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 "ICmpSettlement.h"
|
||||
|
||||
#include "simulation2/system/InterfaceScripted.h"
|
||||
#include "simulation2/scripting/ScriptComponent.h"
|
||||
|
||||
|
||||
BEGIN_INTERFACE_WRAPPER(Settlement)
|
||||
END_INTERFACE_WRAPPER(Settlement)
|
||||
|
||||
class CCmpSettlementScripted : public ICmpSettlement
|
||||
{
|
||||
public:
|
||||
DEFAULT_SCRIPT_WRAPPER(SettlementScripted)
|
||||
};
|
||||
|
||||
REGISTER_COMPONENT_SCRIPT_WRAPPER(SettlementScripted)
|
29
source/simulation2/components/ICmpSettlement.h
Normal file
29
source/simulation2/components/ICmpSettlement.h
Normal file
@ -0,0 +1,29 @@
|
||||
/* Copyright (C) 2011 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_ICMPSETTLEMENT
|
||||
#define INCLUDED_ICMPSETTLEMENT
|
||||
|
||||
#include "simulation2/system/Interface.h"
|
||||
|
||||
class ICmpSettlement : public IComponent
|
||||
{
|
||||
public:
|
||||
DECLARE_INTERFACE_TYPE(Settlement)
|
||||
};
|
||||
|
||||
#endif // INCLUDED_ICMPSETTLEMENT
|
25
source/simulation2/components/ICmpTerritoryInfluence.cpp
Normal file
25
source/simulation2/components/ICmpTerritoryInfluence.cpp
Normal file
@ -0,0 +1,25 @@
|
||||
/* Copyright (C) 2011 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 "ICmpTerritoryInfluence.h"
|
||||
|
||||
#include "simulation2/system/InterfaceScripted.h"
|
||||
|
||||
BEGIN_INTERFACE_WRAPPER(TerritoryInfluence)
|
||||
END_INTERFACE_WRAPPER(TerritoryInfluence)
|
31
source/simulation2/components/ICmpTerritoryInfluence.h
Normal file
31
source/simulation2/components/ICmpTerritoryInfluence.h
Normal file
@ -0,0 +1,31 @@
|
||||
/* Copyright (C) 2011 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_ICMPTERRITORYINFLUENCE
|
||||
#define INCLUDED_ICMPTERRITORYINFLUENCE
|
||||
|
||||
#include "simulation2/system/Interface.h"
|
||||
|
||||
class ICmpTerritoryInfluence : public IComponent
|
||||
{
|
||||
public:
|
||||
virtual u8 GetCost() = 0;
|
||||
|
||||
DECLARE_INTERFACE_TYPE(TerritoryInfluence)
|
||||
};
|
||||
|
||||
#endif // INCLUDED_ICMPTERRITORYINFLUENCE
|
25
source/simulation2/components/ICmpTerritoryManager.cpp
Normal file
25
source/simulation2/components/ICmpTerritoryManager.cpp
Normal file
@ -0,0 +1,25 @@
|
||||
/* Copyright (C) 2011 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 "ICmpTerritoryManager.h"
|
||||
|
||||
#include "simulation2/system/InterfaceScripted.h"
|
||||
|
||||
BEGIN_INTERFACE_WRAPPER(TerritoryManager)
|
||||
END_INTERFACE_WRAPPER(TerritoryManager)
|
35
source/simulation2/components/ICmpTerritoryManager.h
Normal file
35
source/simulation2/components/ICmpTerritoryManager.h
Normal file
@ -0,0 +1,35 @@
|
||||
/* Copyright (C) 2011 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_ICMPTERRITORYMANAGER
|
||||
#define INCLUDED_ICMPTERRITORYMANAGER
|
||||
|
||||
#include "simulation2/system/Interface.h"
|
||||
|
||||
#include "simulation2/helpers/Grid.h"
|
||||
|
||||
class ICmpTerritoryManager : public IComponent
|
||||
{
|
||||
public:
|
||||
virtual bool NeedUpdate(size_t* dirtyID) = 0;
|
||||
|
||||
virtual const Grid<u8>& GetTerritoryGrid() = 0;
|
||||
|
||||
DECLARE_INTERFACE_TYPE(TerritoryManager)
|
||||
};
|
||||
|
||||
#endif // INCLUDED_ICMPTERRITORYMANAGER
|
@ -31,6 +31,7 @@
|
||||
#include "graphics/Terrain.h"
|
||||
#include "graphics/TerrainTextureEntry.h"
|
||||
#include "graphics/TerrainTextureManager.h"
|
||||
#include "graphics/TerritoryTexture.h"
|
||||
#include "graphics/UnitManager.h"
|
||||
#include "maths/MathUtil.h"
|
||||
#include "ps/Font.h"
|
||||
@ -60,7 +61,8 @@ public:
|
||||
UnitManager(),
|
||||
Simulation2(&UnitManager, &Terrain),
|
||||
ObjectManager(MeshManager, SkeletonAnimManager, Simulation2),
|
||||
LOSTexture(Simulation2)
|
||||
LOSTexture(Simulation2),
|
||||
TerritoryTexture(Simulation2)
|
||||
{
|
||||
UnitManager.SetObjectManager(ObjectManager);
|
||||
}
|
||||
@ -84,6 +86,7 @@ public:
|
||||
CUnitManager UnitManager;
|
||||
CSimulation2 Simulation2;
|
||||
CLOSTexture LOSTexture;
|
||||
CTerritoryTexture TerritoryTexture;
|
||||
|
||||
// Simplistic implementation of the Scene interface
|
||||
virtual void EnumerateObjects(const CFrustum& frustum, SceneCollector* c)
|
||||
@ -103,6 +106,10 @@ public:
|
||||
return LOSTexture;
|
||||
}
|
||||
|
||||
virtual CTerritoryTexture& GetTerritoryTexture()
|
||||
{
|
||||
return TerritoryTexture;
|
||||
}
|
||||
};
|
||||
|
||||
ActorViewer::ActorViewer()
|
||||
|
Loading…
Reference in New Issue
Block a user