From f20890f5fae6cd077f68e2ad31391b233f773ccc Mon Sep 17 00:00:00 2001 From: kai Date: Sat, 13 Oct 2007 23:37:23 +0000 Subject: [PATCH] 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. --- source/simulation/Entity.cpp | 22 ++++++ source/simulation/Entity.h | 5 ++ source/simulation/EntityManager.cpp | 111 +++++++++++++++++++++++++++ source/simulation/EntityManager.h | 4 + source/simulation/PathfindEngine.cpp | 73 +++++++++--------- source/simulation/PathfindEngine.h | 11 ++- 6 files changed, 190 insertions(+), 36 deletions(-) diff --git a/source/simulation/Entity.cpp b/source/simulation/Entity.cpp index ef4e339565..c6704b7433 100644 --- a/source/simulation/Entity.cpp +++ b/source/simulation/Entity.cpp @@ -33,6 +33,8 @@ #include +#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& 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 ); diff --git a/source/simulation/Entity.h b/source/simulation/Entity.h index 4ac64f95cd..55298ba9bd 100644 --- a/source/simulation/Entity.h +++ b/source/simulation/Entity.h @@ -223,6 +223,11 @@ public: std::vector m_sectorValues; //Slight optimization for aura rendering std::vector< std::vector > 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& actorSelections, const CStrW* building = 0 ); diff --git a/source/simulation/EntityManager.cpp b/source/simulation/EntityManager.cpp index b9a7143efa..843e7848a6 100644 --- a/source/simulation/EntityManager.cpp +++ b/source/simulation/EntityManager.cpp @@ -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& 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 ) ); } diff --git a/source/simulation/EntityManager.h b/source/simulation/EntityManager.h index c6ffca2342..2d993bec74 100644 --- a/source/simulation/EntityManager.h +++ b/source/simulation/EntityManager.h @@ -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 ); diff --git a/source/simulation/PathfindEngine.cpp b/source/simulation/PathfindEngine.cpp index af1538a584..167f8f8ce8 100644 --- a/source/simulation/PathfindEngine.cpp +++ b/source/simulation/PathfindEngine.cpp @@ -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(); diff --git a/source/simulation/PathfindEngine.h b/source/simulation/PathfindEngine.h index 0f60325d7e..e46ecb9ce1 100644 --- a/source/simulation/PathfindEngine.h +++ b/source/simulation/PathfindEngine.h @@ -33,13 +33,22 @@ class CPathfindEngine : public Singleton { public: + + //Kai: added for dcdt + const float OABBBOUNDREDUCTION ; + const float CIRCLEBOUNDREDUCTION ; + const float RADIUSINCREMENT ; + + + static SrArray processing; + bool dcdtInitialized; SeDcdt dcdtPathfinder; void initBoundary(); void insertObstacles(); - void drawTrianulation(); + void drawTriangulation(); //Kai:added tile overlay for pathfinding TriangulationTerrainOverlay triangulationOverlay;