// APPLYANIMATIONS void plAGMasterMod::ApplyAnimations(double time, float elapsed) { plProfile_BeginLap(ApplyAnimation, this->GetKey()->GetUoid().GetObjectName().c_str()); // update any fades for (int i = 0; i < fAnimInstances.size(); i++) { fAnimInstances[i]->ProcessFade(elapsed); } AdvanceAnimsToTime(time); plProfile_EndLap(ApplyAnimation,this->GetKey()->GetUoid().GetObjectName().c_str()); }
// Called after the simulation has run....sends new positions to the various scene objects // *** want to do this in response to an update message.... void plPXPhysical::SendNewLocation(bool synchTransform, bool isSynchUpdate) { // we only send if: // - the body is active or forceUpdate is on // - the mass is non-zero // - the physical is not passive bool bodyActive = !fActor->isSleeping(); bool dynamic = fActor->isDynamic(); if ((bodyActive || isSynchUpdate) && dynamic)// && fInitialTransform) { plProfile_Inc(MaySendLocation); if (!GetProperty(plSimulationInterface::kPassive)) { hsMatrix44 curl2w = fCachedLocal2World; // we're going to cache the transform before sending so we can recognize if it comes back IGetTransformGlobal(fCachedLocal2World); if (!CompareMatrices(curl2w, fCachedLocal2World, .0001f)) { plProfile_Inc(LocationsSent); plProfile_BeginLap(PhysicsUpdates, GetKeyName().c_str()); // quick peek at the translation...last time it was corrupted because we applied a non-unit quaternion // hsAssert(real_finite(fCachedLocal2World.fMap[0][3]) && // real_finite(fCachedLocal2World.fMap[1][3]) && // real_finite(fCachedLocal2World.fMap[2][3]), "Bad transform outgoing"); if (fCachedLocal2World.GetTranslate().fZ < kMaxNegativeZPos) { SimLog("Physical %s fell to %.1f (%.1f is the max). Suppressing.", GetKeyName().c_str(), fCachedLocal2World.GetTranslate().fZ, kMaxNegativeZPos); // Since this has probably been falling for a while, and thus not getting any syncs, // make sure to save it's current pos so we'll know to reset it later DirtySynchState(kSDLPhysical, plSynchedObject::kBCastToClients); IEnable(false); } hsMatrix44 w2l; fCachedLocal2World.GetInverse(&w2l); plCorrectionMsg *pCorrMsg = new plCorrectionMsg(GetObjectKey(), fCachedLocal2World, w2l, synchTransform); pCorrMsg->Send(); if (fProxyGen) fProxyGen->SetTransform(fCachedLocal2World, w2l); plProfile_EndLap(PhysicsUpdates, GetKeyName().c_str()); } } } }
hsBool plFollowMod::MsgReceive(plMessage* msg) { plRenderMsg* rend = plRenderMsg::ConvertNoRef(msg); if( rend ) { plProfile_BeginLap(FollowMod, this->GetKey()->GetUoid().GetObjectName().c_str()); fLeaderL2W = rend->Pipeline()->GetCameraToWorld(); fLeaderW2L = rend->Pipeline()->GetWorldToCamera(); fLeaderSet = true; plProfile_EndLap(FollowMod, this->GetKey()->GetUoid().GetObjectName().c_str()); return true; } plListenerMsg* list = plListenerMsg::ConvertNoRef(msg); if( list ) { hsVector3 pos; pos.Set(list->GetPosition().fX, list->GetPosition().fY, list->GetPosition().fZ); hsVector3 neg = -pos; fLeaderL2W.MakeTranslateMat(&pos); fLeaderW2L.MakeTranslateMat(&neg); fLeaderSet = true; return true; } plGenRefMsg* ref = plGenRefMsg::ConvertNoRef(msg); if( ref ) { switch( ref->fType ) { case kRefLeader: if( ref->GetContext() & (plRefMsg::kOnCreate|plRefMsg::kOnRequest|plRefMsg::kOnReplace) ) fLeader = plSceneObject::ConvertNoRef(ref->GetRef()); else if( ref->GetContext() & (plRefMsg::kOnDestroy|plRefMsg::kOnRemove) ) fLeader = nil; return true; default: hsAssert(false, "Unknown ref type to FollowMod"); break; } } return plSingleModifier::MsgReceive(msg); }
void hsGMaterial::Eval(double secs, uint32_t frame) { plProfile_BeginLap(MaterialAnims, GetKeyName().c_str()); int i; for( i = 0; i < GetNumLayers(); i++ ) { if( fLayers[i] ) fLayers[i]->Eval(secs, frame, 0); } for( i = 0; i < GetNumPiggyBacks(); i++ ) { if( fPiggyBacks[i] ) fPiggyBacks[i]->Eval(secs, frame, 0); } plProfile_EndLap(MaterialAnims, GetKeyName().c_str()); }
bool pfGUIControlMod::MsgReceive( plMessage *msg ) { plRenderMsg* rend = plRenderMsg::ConvertNoRef( msg ); plDeviceRecreateMsg* device = plDeviceRecreateMsg::ConvertNoRef(msg); if (rend || device) { plPipeline* pipe = rend ? rend->Pipeline() : device->Pipeline(); plProfile_BeginLap(GUITime, this->GetKey()->GetUoid().GetObjectName().c_str()); ISetUpDynTextMap(pipe); plProfile_EndLap(GUITime, this->GetKey()->GetUoid().GetObjectName().c_str()); if (rend) plgDispatch::Dispatch()->UnRegisterForExactType(plRenderMsg::Index(), GetKey()); return true; } plGenRefMsg *refMsg = plGenRefMsg::ConvertNoRef( msg ); if( refMsg != nil ) { if( refMsg->fType == kRefDynTextMap ) { if( refMsg->GetContext() & ( plRefMsg::kOnCreate | plRefMsg::kOnRequest | plRefMsg::kOnReplace ) ) { fDynTextMap = plDynamicTextMap::ConvertNoRef( refMsg->GetRef() ); // These tell us when we need to (re-)initialize the DTM plgDispatch::Dispatch()->RegisterForExactType( plRenderMsg::Index(), GetKey() ); plgDispatch::Dispatch()->RegisterForExactType( plDeviceRecreateMsg::Index(), GetKey() ); } else { fDynTextMap = nullptr; plgDispatch::Dispatch()->UnRegisterForExactType( plDeviceRecreateMsg::Index(), GetKey() ); } return true; } else if( refMsg->fType == kRefDynTextLayer ) { if( refMsg->GetContext() & ( plRefMsg::kOnCreate | plRefMsg::kOnRequest | plRefMsg::kOnReplace ) ) fDynTextLayer = plLayerInterface::ConvertNoRef( refMsg->GetRef() ); else fDynTextLayer = nil; return true; } else if( refMsg->fType == kRefProxy ) { if( refMsg->GetContext() & ( plRefMsg::kOnCreate | plRefMsg::kOnRequest | plRefMsg::kOnReplace ) ) fProxy = plSceneObject::ConvertNoRef( refMsg->GetRef() ); else fProxy = nil; return true; } else if( refMsg->fType == kRefSkin ) { if( refMsg->GetContext() & ( plRefMsg::kOnCreate | plRefMsg::kOnRequest | plRefMsg::kOnReplace ) ) fSkin = pfGUISkin::ConvertNoRef( refMsg->GetRef() ); else fSkin = nil; return true; } } return plSingleModifier::MsgReceive( msg ); }
hsBool plViewFaceModifier::MsgReceive(plMessage* msg) { plRenderMsg* rend = plRenderMsg::ConvertNoRef(msg); if( rend ) { plProfile_BeginLap(ViewFace, this->GetKey()->GetUoid().GetObjectName().c_str()); if( HasFlag(kFaceCam) ) { fFacePoint = rend->Pipeline()->GetViewPositionWorld(); if( HasFlag(kOffset) ) { if( HasFlag(kOffsetLocal) ) { fFacePoint += rend->Pipeline()->GetViewAcrossWorld() * fOffset.fX; fFacePoint += rend->Pipeline()->GetViewUpWorld() * fOffset.fY; fFacePoint += rend->Pipeline()->GetViewDirWorld() * fOffset.fZ; } else { fFacePoint += fOffset; } } } else if( HasFlag(kFaceObj) ) { if( !fFaceObj ) return true; fFacePoint = fFaceObj->GetLocalToWorld().GetTranslate(); if( HasFlag(kOffset) ) { if( HasFlag(kOffsetLocal) ) fFacePoint += fFaceObj->GetLocalToWorld() * fOffset; else fFacePoint += fOffset; } } IFacePoint(rend->Pipeline(), fFacePoint); plProfile_EndLap(ViewFace, this->GetKey()->GetUoid().GetObjectName().c_str()); return true; } plArmatureUpdateMsg* armMsg = plArmatureUpdateMsg::ConvertNoRef(msg); if( armMsg && armMsg->IsLocal() ) { const plSceneObject* head = armMsg->fArmature->FindBone(plAvBrainHuman::Head); if( head ) { fFacePoint = head->GetLocalToWorld().GetTranslate(); if( HasFlag(kOffset) ) { if( HasFlag(kOffsetLocal) ) fFacePoint += head->GetLocalToWorld() * fOffset; else fFacePoint += fOffset; } } return true; } plListenerMsg* list = plListenerMsg::ConvertNoRef(msg); if( list ) { fFacePoint = list->GetPosition(); if( HasFlag(kOffset) ) { if( HasFlag(kOffsetLocal) ) { fFacePoint += (list->GetDirection() % list->GetUp()) * fOffset.fX; fFacePoint += list->GetDirection() * fOffset.fY; fFacePoint += list->GetUp() * fOffset.fZ; } else { fFacePoint += fOffset; } } return true; } plGenRefMsg* refMsg = plGenRefMsg::ConvertNoRef(msg); if( refMsg ) { if( refMsg->GetContext() & (plRefMsg::kOnCreate|plRefMsg::kOnRequest|plRefMsg::kOnReplace) ) IOnReceive(refMsg); else IOnRemove(refMsg); return true; } return plSingleModifier::MsgReceive(msg); }
bool plInputInterfaceMgr::MsgReceive( plMessage *msg ) { int i; plEvalMsg *pEvalMsg = plEvalMsg::ConvertNoRef( msg ); if( pEvalMsg ) { IEval( pEvalMsg->GetTimeStamp(), pEvalMsg->DelSeconds(), false ); return true; } plInputEventMsg *ieMsg = plInputEventMsg::ConvertNoRef( msg ); if( ieMsg != nil ) { const char *inputIEM = "InputEventMsg"; plProfile_BeginLap(Input, inputIEM); bool handled = false; uint32_t missedInputStartIdx = 0; plInputInterface *oldCurrentFocus = fCurrentFocus; // Current focus (if there is one) gets first crack if( fCurrentFocus ) { if( fCurrentFocus->IsEnabled() ) { handled = (fCurrentFocus->ProcessKeyBindings(ieMsg) || fCurrentFocus->InterpretInputEvent(ieMsg)); } } if (!handled) { // Walk our stack for( i = 0; i < fInterfaces.GetCount(); i++ ) { if( fInterfaces[ i ]->IsEnabled() && fInterfaces[ i ] != oldCurrentFocus) { // Try the key bindings first (common for all layers) if( fInterfaces[ i ]->ProcessKeyBindings( ieMsg ) || fInterfaces[ i ]->InterpretInputEvent( ieMsg )) { handled = true; break; } } } if( !handled ) { // Fell all the way through the stack...must've been a very uninteresting message... if( plKeyEventMsg::ConvertNoRef( ieMsg ) && fDefaultCatcher != nil ) { // But somebody loves those keys :) fDefaultCatcher->HandleKeyEvent( plKeyEventMsg::ConvertNoRef( ieMsg ) ); } } missedInputStartIdx = i + 1; } // Notify the rest of the interfaces in the stack that they missed the event ("lost focus", as it were) for (i = missedInputStartIdx; i < fInterfaces.GetCount(); i++) if (fInterfaces[i] != oldCurrentFocus) fInterfaces[i]->MissedInputEvent(ieMsg); // Now we re-walk to see who's the new interested party. Note that we have to re-walk // because a key down may have changed some layer's interest in the cursor if( !fForceCursorHidden ) { bool cursorHandled = false; if (fCurrentFocus) cursorHandled = ICheckCursor(fCurrentFocus); if (!cursorHandled) { for( i = 0; i < fInterfaces.GetCount(); i++ ) { if (ICheckCursor(fInterfaces[i])) { cursorHandled = true; break; } } if (!cursorHandled) { // NOBODY is interested in the mouse, so set to our default cursor IUpdateCursor( plInputInterface::kCursorUp ); fCursorOpacity = 1.f; plMouseDevice::SetCursorOpacity( fCursorOpacity ); } } } else { // Special debug flag to force the cursor to be hidden if( fCursorOpacity != 0.f ) { fCursorOpacity = 0.f; plMouseDevice::SetCursorOpacity( fCursorOpacity ); } } plProfile_EndLap(Input, inputIEM); return true; } plInputIfaceMgrMsg *mgrMsg = plInputIfaceMgrMsg::ConvertNoRef( msg ); if( mgrMsg != nil ) { if( mgrMsg->GetCommand() == plInputIfaceMgrMsg::kAddInterface ) { IAddInterface( mgrMsg->GetIFace() ); return true; } else if( mgrMsg->GetCommand() == plInputIfaceMgrMsg::kRemoveInterface ) { IRemoveInterface( mgrMsg->GetIFace() ); return true; } else if( mgrMsg->GetCommand() == plInputIfaceMgrMsg::kEnableClickables ) { fClickEnabled = true; } else if( mgrMsg->GetCommand() == plInputIfaceMgrMsg::kDisableClickables ) { fClickEnabled = false; } } plPlayerPageMsg *pPMsg = plPlayerPageMsg::ConvertNoRef( msg ); if( pPMsg != nil && !pPMsg->fUnload) { if( pPMsg->fPlayer == plNetClientMgr::GetInstance()->GetLocalPlayerKey() ) fReceivers.Append( pPMsg->fPlayer ); else { int idx = fReceivers.Find( pPMsg->fPlayer ); if( idx != fReceivers.kMissingIndex ) fReceivers.Remove( idx ); } } plCmdIfaceModMsg *pCMsg = plCmdIfaceModMsg::ConvertNoRef( msg ); if( pCMsg ) { if( pCMsg->Cmd( plCmdIfaceModMsg::kAdd ) ) { for( int i = 0; i < fReceivers.Count(); i++ ) { if( fReceivers[i] == pCMsg->GetSender() ) return true; } fReceivers.Append( pCMsg->GetSender() ); return true; } else if( pCMsg->Cmd( plCmdIfaceModMsg::kRemove ) ) { for( int i = 0; i < fReceivers.Count(); i++ ) { if( fReceivers[ i ] == pCMsg->GetSender() ) { fReceivers.Remove( i ); break; } } return true; } } plClientMsg *cMsg = plClientMsg::ConvertNoRef(msg); if (cMsg && cMsg->GetClientMsgFlag() == plClientMsg::kInitComplete) { // Backwards compatability hack: // We've loaded in the user prefs for input. If they bind movement // to an arrow, or numpad, and the other binding is free, automatically // bind the other one. plKeyMap *map = plAvatarInputInterface::GetInstance()->fControlMap; map->HandleAutoDualBinding(KEY_UP, KEY_NUMPAD8); map->HandleAutoDualBinding(KEY_DOWN, KEY_NUMPAD2); map->HandleAutoDualBinding(KEY_LEFT, KEY_NUMPAD4); map->HandleAutoDualBinding(KEY_RIGHT, KEY_NUMPAD6); plgDispatch::Dispatch()->UnRegisterForExactType( plClientMsg::Index(), GetKey() ); return true; } // Wasn't one we want. Was it one that one of our interfaces wanted? for( i = 0; i < fInterfaces.GetCount(); i++ ) { if( fInterfaces[ i ]->MsgReceive( msg ) ) return true; } // Nothing, pass on... return plSingleModifier::MsgReceive( msg ); }
bool plInputInterfaceMgr::IEval( double secs, float del, uint32_t dirty ) { const char *inputEval = "Eval"; plProfile_BeginLap(Input, inputEval); int i; // Let all our layers eval for( i = 0; i < fInterfaces.GetCount(); i++ ) fInterfaces[ i ]->IEval( secs, del, dirty ); // Handle our message queue now for( i = 0; i < fMessageQueue.Count(); i++ ) { // Can its layer handle it? if( !fMessageQueue[ i ]->GetSource()->IHandleCtrlCmd( fMessageQueue[ i ] ) ) { // Nope, just dispatch it like normal plControlEventMsg* pMsg = new plControlEventMsg; for (int j = 0; j < fReceivers.Count(); j++) pMsg->AddReceiver( fReceivers[ j ] ); pMsg->SetControlActivated( fMessageQueue[i]->fControlActivated ); pMsg->SetControlCode( fMessageQueue[i]->fControlCode ); pMsg->SetControlPct(fMessageQueue[i]->fPct); pMsg->SetTurnToPt( fMessageQueue[i]->fPt ); pMsg->SetCmdString(fMessageQueue[i]->GetCmdString()); pMsg->SetSender( GetKey() ); plgDispatch::MsgSend( pMsg ); /////////////////////////////////////////////////////// // send same msg over network to players /////////////////////////////////////////////////////// if (fMessageQueue[i]->fNetPropagateToPlayers) { pMsg = new plControlEventMsg; for (int j = 0; j < fReceivers.Count(); j++) if (fReceivers[j] == plNetClientApp::GetInstance()->GetLocalPlayerKey()) pMsg->AddReceiver( fReceivers[j] ); if (pMsg->GetNumReceivers()) { pMsg->SetControlActivated( fMessageQueue[i]->fControlActivated ); pMsg->SetControlCode( fMessageQueue[i]->fControlCode ); pMsg->SetControlPct(fMessageQueue[i]->fPct); pMsg->SetTurnToPt( fMessageQueue[i]->fPt ); pMsg->SetCmdString(fMessageQueue[i]->GetCmdString()); pMsg->SetSender( GetKey() ); pMsg->SetBCastFlag(plMessage::kNetPropagate | plMessage::kPropagateToModifiers | plMessage::kNetUseRelevanceRegions); // bcast only to other players who care about the region I'm in pMsg->SetBCastFlag(plMessage::kLocalPropagate, false); plgDispatch::MsgSend( pMsg ); } else delete pMsg; } } } // Clear the message queue for( i = 0; i < fMessageQueue.Count(); i++ ) delete fMessageQueue[ i ]; fMessageQueue.SetCount( 0 ); plProfile_EndLap(Input, inputEval); return true; }