//----------------------------------------------------------------------------- // Purpose: Iterates through an object, and all it's children, looking for an // entity with a matching key and value // Input : key - // value - // Output : CMapEntity - the entity found //----------------------------------------------------------------------------- CMapEntity *CMapClass::FindChildByKeyValue( LPCSTR key, LPCSTR value ) { if ( !key || !value ) return NULL; POSITION p = Children.GetHeadPosition(); while( p ) { CMapClass *pChild = Children.GetNext( p ); CMapEntity *e = pChild->FindChildByKeyValue( key, value ); if ( e ) return e; } return NULL; }
//----------------------------------------------------------------------------- // Purpose: Rebuilds the line path between keyframe entities // samples the interpolator function to get an approximation of the curve //----------------------------------------------------------------------------- void CMapAnimator::RebuildPath( void ) { CMapClass *pWorld = GetWorldObject( this ); if ( !pWorld ) { // Sometimes the object isn't linked back into the world yet when RebuildPath() // is called... we will be get called again when needed, but may cause an incorrect // (linear-only) path to get drawn temporarily. return; } // // Build the path forward from the head. Keep a list of nodes we've visited to // use in detecting circularities. // CMapObjectList VisitedList; CMapKeyFrame *pCurKey = this; while ( pCurKey != NULL ) { VisitedList.AddTail( pCurKey ); // // Attach ourselves as this keyframe's animator. // pCurKey->SetAnimator( this ); // // Get the entity parent of this keyframe so we can query keyvalues. // CMapEntity *pCurEnt = dynamic_cast<CMapEntity *>( pCurKey->GetParent() ); if ( !pCurEnt ) { return; } // // Find the next keyframe in the path. // CMapEntity *pNextEnt = pWorld->FindChildByKeyValue( "targetname", pCurEnt->GetKeyValue( "NextKey" ) ); CMapKeyFrame *pNextKey = NULL; if ( pNextEnt ) { pNextKey = pNextEnt->GetChildOfType( ( CMapKeyFrame * )NULL ); pCurKey->SetNextKeyFrame(pNextKey); } else { pCurKey->SetNextKeyFrame( NULL ); } pCurKey = pNextKey; // // If we detect a circularity, stop. // if ( VisitedList.Find( pCurKey ) ) { break; } } // // Now traverse the path again building the spline points, once again checking // the visited list for circularities. // VisitedList.RemoveAll(); pCurKey = this; CMapKeyFrame *pPrevKey = this; while ( pCurKey != NULL ) { VisitedList.AddTail( pCurKey ); pCurKey->BuildPathSegment(pPrevKey); pPrevKey = pCurKey; pCurKey = pCurKey->m_pNextKeyFrame; // // If we detect a circularity, stop. // if ( VisitedList.Find( pCurKey ) ) { break; } } }