pathfinder change: triangulation now handles static object update and removal. dcdt initialization is moved to RequestTriangulationPath() and will only be invoked when -triPathfind flag is supplied. unit radius slightly increased (again) to revolve the unit bouncing problem around buildings.

This was SVN commit r5416.
This commit is contained in:
kai 2007-10-13 23:37:23 +00:00
parent ddffdba2c3
commit f20890f5fa
6 changed files with 190 additions and 36 deletions

View File

@ -33,6 +33,8 @@
#include <algorithm>
#include "ps/GameSetup/Config.h"
const float MAX_ROTATION_RATE = 2*PI; // radians per second
CEntity::CEntity( CEntityTemplate* base, CVector3D position, float orientation, const std::set<CStr8>& actorSelections, const CStrW* building )
@ -222,6 +224,22 @@ void CEntity::initAuraData()
}
}
void CEntity::removeObstacle()
{
if(g_Pathfinder.dcdtInitialized)
{
g_Pathfinder.dcdtPathfinder.remove_polygon(m_dcdtId);
g_Pathfinder.dcdtPathfinder.DeleteAbstraction();
g_Pathfinder.dcdtPathfinder.Abstract();
if(g_ShowOverlay)
{
g_Pathfinder.drawTriangulation();
}
}
}
void CEntity::Kill(bool keepActor)
{
if( entf_get( ENTF_DESTROYED ) )
@ -253,6 +271,10 @@ void CEntity::Kill(bool keepActor)
m_extant = false;
UpdateCollisionPatch();
//Kai: added to remove the entity in the polygon soup (for triangulation)
removeObstacle();
g_Selection.RemoveAll( me );

View File

@ -223,6 +223,11 @@ public:
std::vector<bool> m_sectorValues;
//Slight optimization for aura rendering
std::vector< std::vector<CVector2D> > m_unsnappedPoints;
//Kai: add id to identify the entity in the polygon soup
// needed for update/remove entities in the triangulation.
int m_dcdtId;
void removeObstacle();
private:
CEntity( CEntityTemplate* base, CVector3D position, float orientation, const std::set<CStr8>& actorSelections, const CStrW* building = 0 );

View File

@ -13,6 +13,10 @@
#include "Entity.h"
#include "lib/timer.h"
#include "dcdt/se/se_dcdt.h"
#include "PathfindEngine.h"
#include "ps/GameSetup/Config.h"
int AURA_CIRCLE_POINTS;
int SELECTION_CIRCLE_POINTS;
int SELECTION_BOX_POINTS;
@ -82,6 +86,107 @@ void CEntityManager::DeleteAll()
m_extant = true;
}
void CEntityManager::updateObstacle( CEntity* tempHandle )
{
if(g_Pathfinder.dcdtInitialized)
{
SrPolygon poly;
poly.size(0);
CVector2D p, q;
CVector2D u, v;
q.x = tempHandle->m_position.X;
q.y = tempHandle->m_position.Z;
float d = ((CBoundingBox*)tempHandle->m_bounds)->m_d;
float w = ((CBoundingBox*)tempHandle->m_bounds)->m_w;
u.x = sin( tempHandle->m_graphics_orientation.Y );
u.y = cos( tempHandle->m_graphics_orientation.Y );
v.x = u.y;
v.y = -u.x;
CBoundingObject* m_bounds = tempHandle->m_bounds;
switch( m_bounds->m_type )
{
case CBoundingObject::BOUND_CIRCLE:
{
if(tempHandle->m_speed == 0)
{
poly.open(false);
w = 0.5;
d = 0.5;
p = q + u * d + v * w;
poly.push().set((float)(p.x), (float)(p.y));
p = q - u * d + v * w ;
poly.push().set((float)(p.x), (float)(p.y));
p = q - u * d - v * w;
poly.push().set((float)(p.x), (float)(p.y));
p = q + u * d - v * w;
poly.push().set((float)(p.x), (float)(p.y));
int dcdtId = g_Pathfinder.dcdtPathfinder.insert_polygon(poly);
tempHandle->m_dcdtId = dcdtId;
}
break;
}
case CBoundingObject::BOUND_OABB:
{
poly.open(false);
// Tighten the bound so the units will not get stuck near the buildings
//Note: the triangulation pathfinding code will not find a path for the unit if it is pushed into the bound of a unit.
//
w = w * 0.8;
d = d * 0.8;
p = q + u * d + v * w;
poly.push().set((float)(p.x), (float)(p.y));
p = q - u * d + v * w ;
poly.push().set((float)(p.x), (float)(p.y));
p = q - u * d - v * w;
poly.push().set((float)(p.x), (float)(p.y));
p = q + u * d - v * w;
poly.push().set((float)(p.x), (float)(p.y));
int dcdtId = g_Pathfinder.dcdtPathfinder.insert_polygon(poly);
tempHandle->m_dcdtId = dcdtId;
break;
}
}//end switch
g_Pathfinder.dcdtPathfinder.DeleteAbstraction();
g_Pathfinder.dcdtPathfinder.Abstract();
if(g_ShowOverlay)
{
g_Pathfinder.drawTriangulation();
}
}
}
HEntity CEntityManager::Create(CEntityTemplate* base, CVector3D position, float orientation,
const std::set<CStr>& actorSelections, const CStrW* building)
{
@ -107,6 +212,12 @@ HEntity CEntityManager::Create(CEntityTemplate* base, CVector3D position, float
if( m_collisionPatches)
m_entities[pos].m_entity->UpdateCollisionPatch();
m_entities[pos].m_entity->me = HEntity( pos );
//Kai: invoking triangulation update for new objects
updateObstacle(m_entities[pos].m_entity);
return( HEntity( pos ) );
}

View File

@ -102,6 +102,10 @@ public:
bool GetDeath() { return m_death; }
void SetDeath(bool set) { m_death=set; }
//Kai: added function to update the triangulation when entities are created
void updateObstacle(CEntity* tempHandle);
// Predicate functions
typedef bool (*EntityPredicate)( CEntity* target, void* userdata );

View File

@ -17,18 +17,19 @@
#define EPSILON 0.00001f
bool initialized = false;
CPathfindEngine::CPathfindEngine()
CPathfindEngine::CPathfindEngine():OABBBOUNDREDUCTION(0.8),CIRCLEBOUNDREDUCTION(0.5),RADIUSINCREMENT(2.0)
{
dcdtInitialized = false;
}
//Todo:
// 1; the bouncing problem with the fortress
// 2; update obstacles when things vanishes
// 2; update obstacles when things vanishes. done
void CPathfindEngine::initBoundary()
{
@ -89,8 +90,8 @@ void CPathfindEngine::insertObstacles()
poly.open(false);
w = 0.5;
d = 0.5;
w = CIRCLEBOUNDREDUCTION;
d = CIRCLEBOUNDREDUCTION;
p = q + u * d + v * w;
poly.push().set((float)(p.x), (float)(p.y));
@ -105,6 +106,8 @@ void CPathfindEngine::insertObstacles()
poly.push().set((float)(p.x), (float)(p.y));
int dcdtId = dcdtPathfinder.insert_polygon(poly);
tempHandle->m_dcdtId = dcdtId;
}
break;
@ -119,8 +122,8 @@ void CPathfindEngine::insertObstacles()
// Tighten the bound so the units will not get stuck near the buildings
//Note: the triangulation pathfinding code will not find a path for the unit if it is pushed into the bound of a unit.
//
w = w * 0.85;
d = d * 0.85;
w = w * OABBBOUNDREDUCTION;
d = d * OABBBOUNDREDUCTION;
p = q + u * d + v * w;
poly.push().set((float)(p.x), (float)(p.y));
@ -135,6 +138,7 @@ void CPathfindEngine::insertObstacles()
poly.push().set((float)(p.x), (float)(p.y));
int dcdtId = dcdtPathfinder.insert_polygon(poly);
tempHandle->m_dcdtId = dcdtId;
break;
}
@ -146,21 +150,17 @@ void CPathfindEngine::insertObstacles()
}//end for loop
dcdtPathfinder.DeleteAbstraction();
dcdtPathfinder.Abstract();
}
void CPathfindEngine::drawTrianulation()
void CPathfindEngine::drawTriangulation()
{
int polyNum = dcdtPathfinder.num_polygons();
debug_printf("Number of polygons: %d",polyNum);
//debug_printf("Number of polygons: %d",polyNum);
if(polyNum)
{
@ -180,28 +180,8 @@ void CPathfindEngine::drawTrianulation()
void CPathfindEngine::RequestPath( HEntity entity, const CVector2D& destination,
CEntityOrder::EOrderSource orderSource )
{
/* TODO:1. add code to verify the triangulation. done.
2. add code to convert a path from dcdtpathfinder to world waypoints
*/
if(!initialized)
{
initBoundary();
insertObstacles();
initialized =true;
//switch on/off triangulation drawing by command line arg "-showOverlay"
//it's guarded here to stop setting constrainedEdges and unconstrainedEdges in triangulationOverlay.
//(efficiency issue)
//the drawing is disable in the render() function in TerraiOverlay.cpp
if(g_ShowOverlay)
{
drawTrianulation();
}
}
/* TODO: Add code to generate high level path
For now, just the one high level waypoint to the final
destination is added
@ -215,7 +195,7 @@ void CPathfindEngine::RequestPath( HEntity entity, const CVector2D& destination,
//Kai: adding radius for pathfinding
CBoundingObject* m_bounds = entity->m_bounds;
waypoint.m_pathfinder_radius = m_bounds->m_radius +1.0f;
waypoint.m_pathfinder_radius = m_bounds->m_radius + RADIUSINCREMENT;
//waypoint.m_pathfinder_radius = 0.0f;
entity->m_orderQueue.push_front( waypoint );
@ -227,6 +207,29 @@ void CPathfindEngine::RequestTriangulationPath( HEntity entity, const CVector2D&
{
PROFILE_START("Pathfinding");
if(g_TriPathfind)
{
/* TODO:1. add code to verify the triangulation. done.
2. add code to convert a path from dcdtpathfinder to world waypoints done
*/
if(!dcdtInitialized)
{
initBoundary();
insertObstacles();
dcdtInitialized =true;
//switch on/off triangulation drawing by command line arg "-showOverlay"
//it's guarded here to stop setting constrainedEdges and unconstrainedEdges in triangulationOverlay.
//(efficiency issue)
//the drawing is disable in the render() function in TerraiOverlay.cpp
if(g_ShowOverlay)
{
drawTriangulation();
}
}
}
//Kai: added test for terrain information in entityManager
//mLowPathfinder.TAStarTest();

View File

@ -33,13 +33,22 @@ class CPathfindEngine : public Singleton<CPathfindEngine>
{
public:
//Kai: added for dcdt
const float OABBBOUNDREDUCTION ;
const float CIRCLEBOUNDREDUCTION ;
const float RADIUSINCREMENT ;
static SrArray<SeBase*> processing;
bool dcdtInitialized;
SeDcdt dcdtPathfinder;
void initBoundary();
void insertObstacles();
void drawTrianulation();
void drawTriangulation();
//Kai:added tile overlay for pathfinding
TriangulationTerrainOverlay triangulationOverlay;