//----------------------------------------------------------------------------- // Purpose: notifies the keyframe that it has been cloned // inserts the clone into the correct place in the keyframe list // Input : *pClone - //----------------------------------------------------------------------------- void CMapKeyFrame::OnClone( CMapClass *pClone, CMapWorld *pWorld, const CMapObjectList &OriginalList, CMapObjectList &NewList ) { CMapClass::OnClone( pClone, pWorld, OriginalList, NewList ); CMapKeyFrame *pNewKey = dynamic_cast<CMapKeyFrame*>( pClone ); Assert( pNewKey != NULL ); if ( !pNewKey ) return; CMapEntity *pEntity = dynamic_cast<CMapEntity*>( m_pParent ); CMapEntity *pNewEntity = dynamic_cast<CMapEntity*>( pClone->GetParent() ); // insert the newly created keyframe into the sequence // point the clone's next at what we were pointing at const char *nextKey = pEntity->GetKeyValue( "NextKey" ); if ( nextKey ) { pNewEntity->SetKeyValue( "NextKey", nextKey ); } // create a new targetname for the clone char newName[128]; const char *oldName = pEntity->GetKeyValue( "targetname" ); if ( !oldName || oldName[0] == 0 ) oldName = "keyframe"; pWorld->GenerateNewTargetname( oldName, newName, sizeof( newName ), true, NULL ); pNewEntity->SetKeyValue( "targetname", newName ); // point the current keyframe at the clone pEntity->SetKeyValue( "NextKey", newName ); }
//----------------------------------------------------------------------------- // Purpose: // Input : dwNodeID - // Output : CMapEntity * //----------------------------------------------------------------------------- CMapEntity *CMapPath::CreateEntityForNode(DWORD dwNodeID) { int iIndex; CMapPathNode *pNode = NodeForID(dwNodeID, &iIndex); if (pNode == NULL) { return NULL; // no node, no entity! } CMapEntity *pEntity = new CMapEntity; for (int k = pNode->kv.GetFirst(); k != pNode->kv.GetInvalidIndex(); k=pNode->kv.GetNext( k ) ) { pEntity->SetKeyValue(pNode->kv.GetKey(k), pNode->kv.GetValue(k)); } // store target/targetname properties: CString str; str.Format("%s%02d", m_szName, iIndex); pEntity->SetKeyValue("targetname", str); int iNext = iIndex + 1; if(iNext != -1) { str.Format("%s%02d", m_szName, iNext); pEntity->SetKeyValue("target", str); } pEntity->SetClass(m_szClass); return pEntity; }
//----------------------------------------------------------------------------- // Purpose: Called when an object that we depend on has changed. //----------------------------------------------------------------------------- void CMapKeyFrame::OnNotifyDependent(CMapClass *pObject, Notify_Dependent_t eNotifyType) { CMapClass::OnNotifyDependent(pObject, eNotifyType); if ((pObject == m_pAnimator) && (eNotifyType == Notify_Removed)) { SetAnimator(NULL); } // // If our next keyframe was deleted, try to link to the one after it. // if ((pObject == m_pNextKeyFrame) && (eNotifyType == Notify_Removed)) { CMapEntity *pNextParent = m_pNextKeyFrame->GetParentEntity(); CMapEntity *pParent = GetParentEntity(); if ( pNextParent && pParent ) { const char *szNext = pNextParent->GetKeyValue("NextKey"); pParent->SetKeyValue("NextKey", szNext); } } m_bRebuildPath = true; }
//----------------------------------------------------------------------------- // Purpose: creates a new keyframe at the specified time // Input : time - // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- CMapEntity *CMapAnimator::CreateNewKeyFrame( float time ) { // work out where we are in the animation CMapKeyFrame *key; CMapKeyFrame *pPrevKey; float partialTime = GetKeyFramesAtTime( time, key, pPrevKey ); CMapEntity *pCurrentEnt = dynamic_cast<CMapEntity*>( key->Parent ); // check to see if we're direction on a key frame Vector posOffset( 0, 0, 0 ); if ( partialTime == 0 ) { // create this new key frame slightly after the current one, and offset posOffset[0] = 64; } // get our orientation and position at this time Vector vOrigin; QAngle angles; Quaternion qAngles; GetAnimationAtTime( key, pPrevKey, partialTime, vOrigin, qAngles, m_iPositionInterpolator, m_iRotationInterpolator ); QuaternionAngles( qAngles, angles ); // create the new map entity CMapDoc *pDoc = CMapDoc::GetActiveMapDoc(); CMapWorld *pWorld = pDoc->GetMapWorld(); CMapEntity *pNewEntity = new CMapEntity; Vector newPos; VectorAdd( vOrigin, posOffset, newPos ); pNewEntity->SetPlaceholder( TRUE ); pNewEntity->SetOrigin( newPos ); pNewEntity->SetClass( "keyframe_track" ); char buf[128]; sprintf( buf, "%f %f %f", angles[0], angles[1], angles[2] ); pNewEntity->SetKeyValue( "angles", buf ); // link it into the keyframe list // take over this existing next keyframe pointer const char *nextKeyName = pCurrentEnt->GetKeyValue( "NextKey" ); if ( nextKeyName ) { pNewEntity->SetKeyValue( "NextKey", nextKeyName ); } // create a new unique name for this ent char newName[128]; const char *oldName = pCurrentEnt->GetKeyValue( "targetname" ); if ( !oldName || oldName[0] == 0 ) oldName = "keyframe"; CMapEntity::GenerateNewTargetname( oldName, newName, 127 ); pNewEntity->SetKeyValue( "targetname", newName ); // point the current entity at the newly created one pCurrentEnt->SetKeyValue( "NextKey", newName ); // copy any relevant values const char *keyValue = pCurrentEnt->GetKeyValue( "parentname" ); if ( keyValue ) pNewEntity->SetKeyValue( "parentname", keyValue ); keyValue = pCurrentEnt->GetKeyValue( "MoveSpeed" ); if ( keyValue ) pNewEntity->SetKeyValue( "MoveSpeed", keyValue ); return(pNewEntity); }