- Timestamp:
- 06/03/04 04:20:48 (21 years ago)
- Location:
- ps/trunk/source
- Files:
-
- 13 edited
-
graphics/MapReader.cpp (modified) (1 diff)
-
lib/timer.cpp (modified) (1 diff)
-
renderer/Renderer.cpp (modified) (1 diff)
-
simulation/BoundingObjects.cpp (modified) (2 diffs)
-
simulation/BoundingObjects.h (modified) (1 diff)
-
simulation/Collision.cpp (modified) (3 diffs)
-
simulation/Collision.h (modified) (1 diff)
-
simulation/Entity.cpp (modified) (7 diffs)
-
simulation/EntityHandles.h (modified) (1 diff)
-
simulation/EntityOrders.h (modified) (2 diffs)
-
simulation/EntityStateProcessing.cpp (modified) (3 diffs)
-
simulation/PathfindSparse.cpp (modified) (9 diffs)
-
simulation/PathfindSparse.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
ps/trunk/source/graphics/MapReader.cpp
r348 r379 161 161 CVector3D position = ((CMatrix3D*)m_Objects[i].m_Transform)->GetTranslation(); 162 162 163 g_EntityManager.create( templateObject, position, atan2( orient.X,orient.Z ) );163 g_EntityManager.create( templateObject, position, atan2( -orient.X, -orient.Z ) ); 164 164 } 165 165 else -
ps/trunk/source/lib/timer.cpp
r353 r379 156 156 const float avg_fps = fps_sum / H; 157 157 const float d_avg = avg_fps-fps; 158 const float max_diff = fminf(5.f, 0.05f*fps);158 const float max_diff = __min( 5.f, 0.05f * fps ); //fminf(5.f, 0.05f*fps); 159 159 160 160 if((trend > 0 && (avg_fps > fps || d_avg < -4.f)) || // going up, or large drop -
ps/trunk/source/renderer/Renderer.cpp
r322 r379 1 1 2 /////////////////////////////////////////////////////////////////////////////// 2 3 // -
ps/trunk/source/simulation/BoundingObjects.cpp
r307 r379 47 47 { 48 48 m_pos.x = x; m_pos.y = y; 49 m_pos += m_offset;49 m_pos -= m_offset; 50 50 } 51 51 … … 98 98 setDimensions( copy->getWidth(), copy->getHeight() ); 99 99 setOrientation( u ); 100 } 101 102 CBoundingBox::CBoundingBox( float x, float y, float orientation, float width, float height ) 103 { 104 m_type = BOUND_OABB; 105 setPosition( x, y ); 106 setDimensions( width, height ); 107 setOrientation( orientation ); 108 } 109 110 CBoundingBox::CBoundingBox( float x, float y, float orientation, CBoundingBox* copy ) 111 { 112 m_type = BOUND_OABB; 113 m_offset = copy->m_offset; 114 setPosition( x, y ); 115 setDimensions( copy->getWidth(), copy->getHeight() ); 116 setOrientation( orientation ); 100 117 } 101 118 -
ps/trunk/source/simulation/BoundingObjects.h
r357 r379 57 57 float m_h; // Half this box's height. 58 58 float m_w; // Half this box's width. 59 CBoundingBox( float x, float y, float orientation, float width, float height ) 60 { 61 CBoundingBox( x, y, CVector2D( sin( orientation ), cos( orientation ) ), width, height ); 62 } 59 CBoundingBox( float x, float y, float orientation, float width, float height ); 63 60 CBoundingBox( float x, float y, const CVector2D& orientation, float width, float height ); 64 CBoundingBox( float x, float y, float orientation, CBoundingBox* copy ) 65 { 66 CBoundingBox( x, y, CVector2D( sin( orientation ), cos( orientation ) ), copy ); 67 } 61 CBoundingBox( float x, float y, float orientation, CBoundingBox* copy ); 68 62 CBoundingBox( float x, float y, const CVector2D& orientation, CBoundingBox* copy ); 69 63 void setDimensions( float width, float height ); -
ps/trunk/source/simulation/Collision.cpp
r357 r379 55 55 } 56 56 57 bool getRayIntersection( const CVector2D& source, const CVector2D& forward, const CVector2D& right, float length, float maxDistance, rayIntersectionResults* results )57 bool getRayIntersection( const CVector2D& source, const CVector2D& forward, const CVector2D& right, float length, float maxDistance, CBoundingObject* destinationCollisionObject, rayIntersectionResults* results ) 58 58 { 59 59 std::vector<HEntity>* entities = g_EntityManager.getActive(); … … 70 70 { 71 71 assert( (*it)->m_bounds ); 72 if( (*it)->m_bounds == destinationCollisionObject ) continue; 73 // HACK: 74 if( (*it)->m_bounds->m_type == CBoundingObject::BOUND_OABB ) continue; 72 75 if( (*it)->m_speed ) continue; 73 76 CBoundingObject* obj = (*it)->m_bounds; … … 75 78 closestApproach = delta.dot( right ); 76 79 dist = delta.dot( forward ); 80 float collisionRadius = maxDistance + obj->m_radius; 77 81 78 if( ( fabs( closestApproach ) < maxDistance + obj->m_radius ) && ( dist > -maxDistance ) && ( dist < length + maxDistance) )82 if( ( fabs( closestApproach ) < collisionRadius ) && ( dist > collisionRadius * 0.0f ) && ( dist < length - collisionRadius * 0.0f ) ) 79 83 { 80 84 if( dist < results->distance ) -
ps/trunk/source/simulation/Collision.h
r357 r379 31 31 HEntity getCollisionObject( CEntity* entity, float x, float y ); 32 32 CBoundingObject* getContainingObject( const CVector2D& point ); 33 bool getRayIntersection( const CVector2D& source, const CVector2D& forward, const CVector2D& right, float length, float maxDistance, rayIntersectionResults* results );33 bool getRayIntersection( const CVector2D& source, const CVector2D& forward, const CVector2D& right, float length, float maxDistance, CBoundingObject* destinationCollisionObject, rayIntersectionResults* results ); 34 34 35 35 #endif -
ps/trunk/source/simulation/Entity.cpp
r308 r379 17 17 m_base = base; 18 18 m_actor = new CUnit(m_base->m_actorObject,m_base->m_actorObject->m_Model->Clone()); 19 20 21 // HACK: Debugging 22 // assert( m_base->m_name != CStr( "Waypoint" ) ); 19 23 20 24 // Register the actor with the renderer. … … 34 38 if( m_base->m_bound_type == CBoundingObject::BOUND_CIRCLE ) 35 39 { 36 m_bounds = new CBoundingCircle( m_position.X, m_position.Z, m_base->m_bound_circle );40 m_bounds = new CBoundingCircle( m_position.X, m_position.Z, m_base->m_bound_circle ); 37 41 } 38 42 else if( m_base->m_bound_type == CBoundingObject::BOUND_OABB ) … … 40 44 m_bounds = new CBoundingBox( m_position.X, m_position.Z, m_ahead, m_base->m_bound_box ); 41 45 } 42 46 43 47 snapToGround(); 44 48 updateActorTransforms(); … … 142 146 case CEntityOrder::ORDER_GOTO_NOPATHING: 143 147 case CEntityOrder::ORDER_GOTO_COLLISION: 148 case CEntityOrder::ORDER_GOTO_SMOOTHED: 144 149 if( processGotoNoPathing( current, timestep ) ) break; 145 150 return; … … 201 206 { 202 207 // Rich! Help! ;) 203 // We can loose this later on, I just need a way to see collision boxes temporarily 208 209 // HACK: As in this entire function is a... 204 210 205 211 if( !m_orderQueue.empty() ) 206 212 { 213 std::deque<CEntityOrder>::iterator it; 214 CBoundingObject* destinationCollisionObject; 215 float x0, y0, x, y; 216 217 x = m_orderQueue.front().m_data[0].location.x; 218 y = m_orderQueue.front().m_data[0].location.y; 219 220 for( it = m_orderQueue.begin(); it < m_orderQueue.end(); it++ ) 221 { 222 if( it->m_type == CEntityOrder::ORDER_PATROL ) 223 break; 224 x = it->m_data[0].location.x; 225 y = it->m_data[0].location.y; 226 } 227 destinationCollisionObject = getContainingObject( CVector2D( x, y ) ); 228 207 229 glShadeModel( GL_FLAT ); 208 230 glBegin( GL_LINE_STRIP ); 209 231 210 std::deque<CEntityOrder>::iterator it; 211 212 glVertex3f( m_position.X, m_position.Y + 0.25f /* 20.0f */, m_position.Z ); 213 232 233 234 glVertex3f( m_position.X, m_position.Y + 0.25f, m_position.Z ); 235 236 237 x = m_position.X; 238 y = m_position.Z; 239 214 240 for( it = m_orderQueue.begin(); it < m_orderQueue.end(); it++ ) 215 241 { 216 float x = it->m_data[0].location.x; 217 float y = it->m_data[0].location.y; 242 x0 = x; y0 = y; 243 x = it->m_data[0].location.x; 244 y = it->m_data[0].location.y; 245 rayIntersectionResults r; 246 CVector2D fwd( x - x0, y - y0 ); 247 float l = fwd.length(); 248 fwd = fwd.normalize(); 249 CVector2D rgt = fwd.beta(); 250 if( getRayIntersection( CVector2D( x0, y0 ), fwd, rgt, l, m_bounds->m_radius, destinationCollisionObject, &r ) ) 251 { 252 glEnd(); 253 glBegin( GL_LINES ); 254 glColor3f( 1.0f, 0.0f, 0.0f ); 255 glVertex3f( x0 + fwd.x * r.distance, getExactGroundLevel( x0 + fwd.x * r.distance, y0 + fwd.y * r.distance ) + 0.25f, y0 + fwd.y * r.distance ); 256 glVertex3f( r.position.x, getExactGroundLevel( r.position.x, r.position.y ) + 0.25f, r.position.y ); 257 glEnd(); 258 glBegin( GL_LINE_STRIP ); 259 glVertex3f( x0, getExactGroundLevel( x0, y0 ), y0 ); 260 } 218 261 switch( it->m_type ) 219 262 { … … 223 266 glColor3f( 1.0f, 0.5f, 0.5f ); break; 224 267 case CEntityOrder::ORDER_GOTO_NOPATHING: 268 case CEntityOrder::ORDER_GOTO_SMOOTHED: 225 269 glColor3f( 0.5f, 0.5f, 0.5f ); break; 270 case CEntityOrder::ORDER_PATROL: 271 glColor3f( 0.0f, 1.0f, 0.0f ); break; 226 272 default: 227 glColor3f( 1.0f, 1.0f, 1.0f ); break; 228 } 229 glVertex3f( x, getExactGroundLevel( x, y ) + 0.25f /* 20.0f */, y ); 273 continue; 274 } 275 276 glVertex3f( x, getExactGroundLevel( x, y ) + 0.25f, y ); 230 277 } 231 278 … … 238 285 239 286 if( getCollisionObject( this ) ) glColor3f( 0.5f, 0.5f, 1.0f ); 240 m_bounds->render( m_position.Y + 0.25f /* 20.0f */);287 m_bounds->render( getExactGroundLevel( m_position.X, m_position.Z ) + 0.25f ); //m_position.Y + 0.25f ); 241 288 242 289 } -
ps/trunk/source/simulation/EntityHandles.h
r357 r379 40 40 friend class CEntityManager; 41 41 u16 m_handle; 42 private: 42 43 void addRef(); 43 44 void decRef(); -
ps/trunk/source/simulation/EntityOrders.h
r357 r379 7 7 // Usage: All orders at this point use the location component of the union. 8 8 // Orders are: ORDER_GOTO_NOPATHING: Attempts to reach the given destination via a line-of-sight 9 // system. Do not create an order of this typedirectly; it is9 // ORDER_GOTO_SMOOTED: system. Do not create an order of these types directly; it is 10 10 // used to return a path of line segments from the pathfinder. 11 // _SMOOTHED flags to the entity state-control that it's OK to 12 // smooth the corner between segments. _NOPATHING just does 13 // zero-radius turns. 11 14 // ORDER_GOTO_COLLISION: When the coldet system is trying to get us out of a collision, 12 15 // it generates these intermediate waypoints. We don't really have … … 46 49 { 47 50 ORDER_GOTO_NOPATHING, 51 ORDER_GOTO_SMOOTHED, 48 52 ORDER_GOTO_COLLISION, 49 53 ORDER_GOTO, -
ps/trunk/source/simulation/EntityStateProcessing.cpp
r357 r379 15 15 float len = delta.length(); 16 16 17 // Curve smoothing. 18 // Here there be trig. 19 20 if( current->m_type != CEntityOrder::ORDER_GOTO_SMOOTHED ) 21 { 22 // We can only really attempt to smooth paths the pathfinder 23 // has flagged for us. If the turning-radius calculations are 24 // applied to other types of waypoint, wierdness happens. 25 // Things like an entity trying to walk to a point inside 26 // his turning radius (which he can't do directly, so he'll 27 // orbit the point indefinately), or just massive deviations 28 // making the paths we calculate useless. 29 // It's also painful trying to watch two entities resolve their 30 // collision when they're both bound by turning constraints. 31 m_ahead = delta / len; 32 m_orientation = atan2( m_ahead.x, m_ahead.y ); 33 } 34 else 35 { 36 m_targetorientation = atan2( delta.x, delta.y ); 37 38 float deltatheta = m_targetorientation - m_orientation; 39 while( deltatheta > PI ) deltatheta -= 2 * PI; 40 while( deltatheta < -PI ) deltatheta += 2 * PI; 41 42 if( fabs( deltatheta ) > 0.01f ) 43 { 44 float maxTurningSpeed = ( m_speed / m_turningRadius ) * timestep; 45 if( deltatheta > 0 ) 46 { 47 m_orientation += MIN( deltatheta, maxTurningSpeed ); 48 } 49 else 50 m_orientation += MAX( deltatheta, -maxTurningSpeed ); 51 52 m_ahead.x = sin( m_orientation ); 53 m_ahead.y = cos( m_orientation ); 54 } 55 else 56 { 57 m_ahead = delta / len; 58 m_orientation = atan2( m_ahead.x, m_ahead.y ); 59 } 60 } 61 17 62 if( len < 0.1f ) 18 63 { 19 m_orderQueue.pop_front(); 64 if( current->m_type == CEntityOrder::ORDER_GOTO_COLLISION ) 65 { 66 // Repath. 67 CVector2D destination; 68 while( !m_orderQueue.empty() && 69 ( ( m_orderQueue.front().m_type == CEntityOrder::ORDER_GOTO_COLLISION ) 70 || ( m_orderQueue.front().m_type == CEntityOrder::ORDER_GOTO_NOPATHING ) 71 || ( m_orderQueue.front().m_type == CEntityOrder::ORDER_GOTO_SMOOTHED ) ) ) 72 { 73 destination = m_orderQueue.front().m_data[0].location; 74 m_orderQueue.pop_front(); 75 } 76 g_Pathfinder.requestPath( me, destination ); 77 } 78 else 79 m_orderQueue.pop_front(); 20 80 return( false ); 21 81 } 22 23 m_ahead = delta / len;24 82 25 83 if( m_bounds->m_type == CBoundingObject::BOUND_OABB ) … … 79 137 CVector2D right; 80 138 right.x = m_ahead.y; right.y = -m_ahead.x; 81 CVector2D avoidancePosition = collide->m_bounds->m_pos + right * ( collide->m_bounds->m_radius * 2.5f );139 CVector2D avoidancePosition = collide->m_bounds->m_pos + right * ( collide->m_bounds->m_radius + m_bounds->m_radius * 2.5f ); 82 140 avoidance.m_data[0].location = avoidancePosition; 83 141 if( current->m_type == CEntityOrder::ORDER_GOTO_COLLISION ) … … 92 150 // A circle. 93 151 // TODO: Implement this properly. 94 // Try turning right. 152 // Work out if our path goes to the left or to the right 153 // of this obstacle. Go that way. 154 // Weight a little to the right, too (helps unit-unit collisions) 155 95 156 CEntityOrder avoidance; 96 157 avoidance.m_type = CEntityOrder::ORDER_GOTO_COLLISION; 97 158 CVector2D right; 98 159 right.x = m_ahead.y; right.y = -m_ahead.x; 99 CVector2D avoidancePosition = collide->m_bounds->m_pos + right * ( collide->m_bounds->m_radius * 2.5f ); 160 CVector2D avoidancePosition; 161 162 if( ( collide->m_bounds->m_pos - m_bounds->m_pos ).dot( right ) < 1 ) 163 { 164 // Turn right. 165 avoidancePosition = collide->m_bounds->m_pos + right * ( collide->m_bounds->m_radius + m_bounds->m_radius * 2.5f ); 166 } 167 else 168 { 169 // Turn left. 170 avoidancePosition = collide->m_bounds->m_pos - right * ( collide->m_bounds->m_radius + m_bounds->m_radius * 2.5f ); 171 } 172 100 173 avoidance.m_data[0].location = avoidancePosition; 101 174 if( current->m_type == CEntityOrder::ORDER_GOTO_COLLISION ) -
ps/trunk/source/simulation/PathfindSparse.cpp
r357 r379 1 1 #include "PathfindSparse.h" 2 3 #define NODESMOOTH_STEPS 44 2 5 3 sparsePathTree::sparsePathTree( const CVector2D& _from, const CVector2D& _to, HEntity _entity, CBoundingObject* _destinationCollisionObject ) … … 14 12 type = SPF_OPEN_UNVISITED; 15 13 leftImpossible = false; rightImpossible = false; 14 nextSubtree = 0; 16 15 } 17 16 … … 32 31 CVector2D forward = to - from; 33 32 float len = forward.length(); 33 34 assert( len != 0.0f ); 35 34 36 forward /= len; 35 CVector2D right = CVector2D( forward.y, -forward.x ); 36 37 // Hit nothing or hit destination; that's OK. 38 if( !getRayIntersection( from, forward, right, len, entity->m_bounds->m_radius * 1.1f, &r ) || ( r.boundingObject == destinationCollisionObject ) ) 37 CVector2D v_right = CVector2D( forward.y, -forward.x ); 38 39 if( !getRayIntersection( from, forward, v_right, len, entity->m_bounds->m_radius * 1.1f, destinationCollisionObject, &r ) ) 39 40 { 40 41 type = SPF_CLOSED_DIRECT; … … 42 43 } 43 44 44 float turningRadius = ( entity->m_bounds->m_radius + r.boundingObject->m_radius ) * 1.1f;45 float turningRadius = ( entity->m_bounds->m_radius + r.boundingObject->m_radius ) * 1.1f; 45 46 46 47 if( turningRadius < entity->m_turningRadius ) turningRadius = entity->m_turningRadius; 47 48 48 49 // Too close, an impossible turn 49 if( r.distance < turningRadius || 50 r.distance > ( len - turningRadius ) ) 51 { 52 type = SPF_IMPOSSIBLE; 53 return( true ); 54 } 55 56 CVector2D delta = r.position - from; 57 float length = delta.length(); 58 59 float offsetDistance = ( turningRadius * length / sqrt( length * length - turningRadius * turningRadius ) ); 60 50 if( r.distance < turningRadius ) 51 { 52 // Too close to make a proper turn; try dodging immediately a long way to the left or right. 53 left = from - v_right * r.boundingObject->m_radius * 2.5f; 54 right = from + v_right * r.boundingObject->m_radius * 2.5f; 55 } 56 else if( r.distance > ( len - turningRadius ) ) 57 { 58 // Again, too close to avoid it properly. Try approaching the goal from the left or right. 59 left = to - v_right * r.boundingObject->m_radius * 2.5f; 60 right = to + v_right * r.boundingObject->m_radius * 2.5f; 61 } 62 else 63 { 64 // Dodge to the left or right of the obstacle. 65 // A distance of offsetDistance is sufficient to guarantee we'll make the turn. 66 67 CVector2D delta = r.position - from; 68 float length = delta.length(); 69 70 float offsetDistance = ( turningRadius * length / sqrt( length * length - turningRadius * turningRadius ) ); 71 left = r.position - v_right * offsetDistance; 72 right = r.position + v_right * offsetDistance; 73 } 61 74 favourLeft = false; 62 75 if( r.closestApproach < 0 ) 63 76 favourLeft = true; 64 77 65 78 // First we path to the left... 66 67 left = r.position - right * offsetDistance; 79 68 80 leftPre = new sparsePathTree( from, left, entity, destinationCollisionObject ); 69 81 leftPost = new sparsePathTree( left, to, entity, destinationCollisionObject ); … … 71 83 // Then we path to the right... 72 84 73 right = r.position + right * offsetDistance;74 85 rightPre = new sparsePathTree( from, right, entity, destinationCollisionObject ); 75 86 rightPost = new sparsePathTree( right, to, entity, destinationCollisionObject ); … … 88 99 { 89 100 bool done = false; 90 if( !leftImpossible ) 91 { 92 if( !done && ( leftPre->type & SPF_OPEN ) ) 93 done |= leftPre->slice(); 94 if( !done && ( leftPost->type & SPF_OPEN ) ) 95 done |= leftPost->slice(); 96 if( ( leftPre->type == SPF_IMPOSSIBLE ) || ( leftPost->type == SPF_IMPOSSIBLE ) ) 97 leftImpossible = true; 98 } 99 if( !rightImpossible && !done ) 100 { 101 if( !done && ( rightPre->type & SPF_OPEN ) ) 102 done |= rightPre->slice(); 103 if( !done && ( rightPost->type & SPF_OPEN ) ) 104 done |= rightPost->slice(); 105 if( ( rightPre->type == SPF_IMPOSSIBLE ) || ( rightPost->type == SPF_IMPOSSIBLE ) ) 106 rightImpossible = true; 107 } 101 while( !done ) 102 { 103 if( subtrees[nextSubtree]->type & SPF_OPEN ) 104 if( subtrees[nextSubtree]->slice() ) 105 done = true; 106 nextSubtree++; 107 nextSubtree %= 4; 108 } 109 if( ( leftPre->type == SPF_IMPOSSIBLE ) || ( leftPost->type == SPF_IMPOSSIBLE ) ) 110 leftImpossible = true; 111 if( ( rightPre->type == SPF_IMPOSSIBLE ) || ( rightPost->type == SPF_IMPOSSIBLE ) ) 112 rightImpossible = true; 108 113 if( leftImpossible && rightImpossible ) 109 114 { … … 150 155 void nodeSmooth( HEntity entity, std::vector<CVector2D>& nodelist ) 151 156 { 152 // All your CPU are belong to us.153 // But Jan wanted it ;)154 155 157 std::vector<CVector2D>::iterator it; 156 158 CVector2D next = nodelist.front(); 157 159 158 160 CEntityOrder node; 159 node.m_type = CEntityOrder::ORDER_GOTO_ NOPATHING;161 node.m_type = CEntityOrder::ORDER_GOTO_SMOOTHED; 160 162 node.m_data[0].location = next; 161 163 … … 174 176 CVector2D vbar = v.beta(); 175 177 float alpha = entity->m_turningRadius * ( ubar - vbar ).length() / ( u + v ).length(); 176 u *= alpha; 177 v *= alpha; 178 179 for( int t = NODESMOOTH_STEPS; t >= 0; t-- ) 180 { 181 float lambda = t / (float)NODESMOOTH_STEPS; 182 CVector2D arcpoint = current + v * lambda * lambda - u * ( 1 - lambda ) * ( 1 - lambda ); 183 node.m_data[0].location = arcpoint; 184 entity->m_orderQueue.push_front( node ); 185 } 186 178 node.m_data[0].location = current - u * alpha; 179 entity->m_orderQueue.push_front( node ); 187 180 next = current; 188 181 } 182 183 // If we try to apply turning constraints to getting onto this path, there's a reasonable 184 // risk the entity will deviate so far from the first path segment that the path becomes 185 // unwalkable for it. 186 entity->m_orderQueue.front().m_type = CEntityOrder::ORDER_GOTO_NOPATHING; 189 187 } 190 188 … … 192 190 { 193 191 std::vector<CVector2D> pathnodes; 194 sparsePathTree sparseEngine( CVector2D( entity->m_position.X, entity->m_position.Z ), destination, entity, getContainingObject( destination ) ); 192 CVector2D source( entity->m_position.X, entity->m_position.Z ); 193 sparsePathTree sparseEngine( source, destination, entity, getContainingObject( destination ) ); 195 194 while( sparseEngine.type & sparsePathTree::SPF_OPEN ) sparseEngine.slice(); 196 195 196 assert( sparseEngine.type & sparsePathTree::SPF_SOLVED ); // Shouldn't be any impossible cases yet. 197 197 198 if( sparseEngine.type & sparsePathTree::SPF_SOLVED ) 198 199 { 199 200 sparseEngine.pushResults( pathnodes ); 201 pathnodes.push_back( source ); 200 202 nodeSmooth( entity, pathnodes ); 201 203 } -
ps/trunk/source/simulation/PathfindSparse.h
r357 r379 48 48 CVector2D right; 49 49 bool favourLeft; 50 sparsePathTree* leftPre; 51 sparsePathTree* leftPost; 52 sparsePathTree* rightPre; 53 sparsePathTree* rightPost; 50 union 51 { 52 struct 53 { 54 sparsePathTree* leftPre; 55 sparsePathTree* leftPost; 56 sparsePathTree* rightPre; 57 sparsePathTree* rightPost; 58 }; 59 sparsePathTree* subtrees[4]; 60 }; 61 unsigned short nextSubtree; 54 62 sparsePathTree( const CVector2D& from, const CVector2D& to, HEntity entity, CBoundingObject* destinationCollisionObject ); 55 63 ~sparsePathTree();
Note:
See TracChangeset
for help on using the changeset viewer.
