void plObjectInVolumeDetector::ITrigger(plKey hitter, bool entering, bool immediate) { hsRefCnt_SafeUnRef(fSavedActivatorMsg); fSavedActivatorMsg = new plActivatorMsg; fSavedActivatorMsg->AddReceivers(fReceivers); if (fProxyKey) fSavedActivatorMsg->fHiteeObj = fProxyKey; else fSavedActivatorMsg->fHiteeObj = GetTarget()->GetKey(); fSavedActivatorMsg->fHitterObj = hitter; fSavedActivatorMsg->SetSender(GetKey()); if (entering) { DetectorLog("%s: Saving Entering volume - Evals=%d", GetKeyName().c_str(), fNumEvals); fSavedActivatorMsg->SetTriggerType(plActivatorMsg::kVolumeEnter); fLastEnterEval = fNumEvals; } else { DetectorLog("%s: Saving Exiting volume - Evals=%d", GetKeyName().c_str(), fNumEvals); fSavedActivatorMsg->SetTriggerType(plActivatorMsg::kVolumeExit); fLastExitEval = fNumEvals; } if (immediate) ISendSavedTriggerMsgs(); }
void plCameraRegionDetector::ITrigger(plKey hitter, bool entering, bool immediate) { if (fSavingSendMsg) DetectorLogRed("%s: Stale messages on ITrigger. This should never happen!", GetKeyName().c_str()); if (fIsInside && entering) DetectorLogRed("%s: Duplicate enter! Did we miss an exit?", GetKeyName().c_str()); else if (!fIsInside && !entering) DetectorLogRed("%s: Duplicate exit! Did we miss an enter?", GetKeyName().c_str()); fSavingSendMsg = true; fSavedMsgEnterFlag = entering; if (entering) { DetectorLog("%s: Saving camera Entering volume - Evals=%d", GetKeyName().c_str(),fNumEvals); fLastEnterEval = fNumEvals; } else { DetectorLog("%s: Saving camera Exiting volume - Evals=%d", GetKeyName().c_str(),fNumEvals); fLastExitEval = fNumEvals; } if (immediate) ISendSavedTriggerMsgs(); }
void plObjectInVolumeDetector::ISendSavedTriggerMsgs() { if (fSavedActivatorMsg) { if (fSavedActivatorMsg->fTriggerType == plActivatorMsg::kVolumeEnter) DetectorLog("%s: Sending Entering volume - Evals=%d", GetKeyName().c_str(), fNumEvals); else DetectorLog("%s: Sending Exiting volume - Evals=%d", GetKeyName().c_str(), fNumEvals); // we're saving the message to be dispatched later... plgDispatch::MsgSend(fSavedActivatorMsg); } fSavedActivatorMsg = nil; }
void plPXPhysicalControllerCore::IInformDetectors(bool entering,bool deferUntilNextSim=true) { static const NxU32 DetectorFlag= 1<<plSimDefs::kGroupDetector; if (fController) { #ifndef PLASMA_EXTERNAL_RELEASE DetectorLog("Informing from plPXPhysicalControllerCore::IInformDetectors"); #endif NxScene* scene = plSimulationMgr::GetInstance()->GetScene(fWorldKey); int kNumofShapesToStore=30; NxCapsule cap; GetWorldSpaceCapsule(cap); NxShape* shapes[30]; int numCollided=scene->overlapCapsuleShapes(cap,NX_ALL_SHAPES,kNumofShapesToStore,shapes,NULL,DetectorFlag,NULL,true); for (int i=0;i<numCollided;i++) { NxActor* myactor=&(shapes[i]->getActor()); if (myactor) { plPXPhysical* physical = (plPXPhysical*)myactor->userData; if (physical) { bool doReport = physical->DoReportOn(plSimDefs::kGroupAvatar); if(doReport) { plCollideMsg* msg = new plCollideMsg; msg->fOtherKey = fOwner; msg->fEntering = entering; msg->AddReceiver(physical->GetObjectKey()); if(!deferUntilNextSim) { DetectorLog("Sending an %s msg to %s" , entering? "entering":"exit", physical->GetObjectKey()->GetName().c_str()); msg->Send(); } else { DetectorLog("Queuing an %s msg to %s, which will be sent after the client update" , entering? "entering":"exit", physical->GetObjectKey()->GetName().c_str()); plgDispatch::Dispatch()->MsgQueue(msg); } } } } } DetectorLog("Done informing from plPXPhysicalControllerCore::IInformDetectors"); } }
void plObjectInVolumeAndFacingDetector::ICheckForTrigger() { plArmatureMod* armMod = plAvatarMgr::GetInstance()->GetLocalAvatar(); plSceneObject* avatar = armMod ? armMod->GetTarget(0) : nil; plSceneObject* target = GetTarget(); if (armMod && target) { hsVector3 playerView = avatar->GetCoordinateInterface()->GetLocalToWorld().GetAxis(hsMatrix44::kView); hsVector3 objView = target->GetCoordinateInterface()->GetLocalToWorld().GetAxis(hsMatrix44::kView); playerView.Normalize(); objView.Normalize(); float dot = playerView * objView; // hsStatusMessageF("Dot: %f Tolerance: %f", dot, fFacingTolerance); bool facing = dot >= fFacingTolerance; bool movingForward = false; if (fNeedWalkingForward) { // And are we walking towards it? plArmatureBrain* abrain = armMod->FindBrainByClass(plAvBrainHuman::Index()); //armMod->GetCurrentBrain(); plAvBrainHuman* brain = plAvBrainHuman::ConvertNoRef(abrain); if (brain && brain->IsMovingForward() && brain->fWalkingStrategy->IsOnGround()) movingForward = true; } else movingForward = true; if (facing && movingForward && !fTriggered) { DetectorLog("%s: Trigger InVolume&Facing", GetKeyName().c_str()); fTriggered = true; ISendTriggerMsg(avatar->GetKey(), true); } else if (!facing && fTriggered) { DetectorLog("%s: Untrigger InVolume&Facing", GetKeyName().c_str()); fTriggered = false; ISendTriggerMsg(avatar->GetKey(), false); } } }
void plObjectInVolumeDetector::IHandleEval(plEvalMsg*) { bookKeepingList::iterator it = fCollisionList.begin(); while (it != fCollisionList.end()) { plCollisionBookKeepingInfo* collisionInfo = *it; #ifdef USE_PHYSX_COLLISION_FLUTTER_WORKAROUND if (plSimulationMgr::GetInstance()->GetStepCount() - collisionInfo->fLastStep > 1) { #endif // USE_PHYSX_COLLISION_FLUTTER_WORKAROUND ResidentSet::iterator j = fCurrentResidents.find(collisionInfo->fHitter); bool wasInside = j != fCurrentResidents.end(); if (collisionInfo->fEntering != wasInside) { if (collisionInfo->fEntering) { fCurrentResidents.insert(collisionInfo->fHitter); DetectorLog("%s: Sending Volume Enter ActivatorMsg", GetKeyName().c_str()); ISendTriggerMsg(collisionInfo->fHitter, true); } else { fCurrentResidents.erase(j); DetectorLog("%s: Sending Volume Exit ActivatorMsg", GetKeyName().c_str()); ISendTriggerMsg(collisionInfo->fHitter, false); } } delete collisionInfo; #ifdef USE_PHYSX_COLLISION_FLUTTER_WORKAROUND it = fCollisionList.erase(it); } else { ++it; } #else ++it; #endif // USE_PHYSX_COLLISION_FLUTTER_WORKAROUND } }
void plCameraRegionDetector::ISendSavedTriggerMsgs() { if (fSavingSendMsg) { for (size_t i = 0; i < fMessages.size(); ++i) { hsRefCnt_SafeRef(fMessages[i]); if (fSavedMsgEnterFlag) { fMessages[i]->SetCmd(plCameraMsg::kEntering); DetectorLog("Entering cameraRegion: %s - Evals=%d -msg %d of %d\n", GetKeyName().c_str(),fNumEvals,i+1,fMessages.size()); fIsInside = true; } else { fMessages[i]->ClearCmd(plCameraMsg::kEntering); DetectorLog("Exiting cameraRegion: %s - Evals=%d -msg %d of %d\n", GetKeyName().c_str(),fNumEvals,i+1,fMessages.size()); fIsInside = false; } plgDispatch::MsgSend(fMessages[i]); } } fSavingSendMsg = false; }
void plCameraRegionDetector::IHandleEval(plEvalMsg*) { #ifdef USE_PHYSX_COLLISION_FLUTTER_WORKAROUND if (plSimulationMgr::GetInstance()->GetStepCount() - fLastStep > 1) { #endif if (fIsInside != fEntering) { fIsInside = fEntering; DetectorLog("%s CameraRegion: %s", fIsInside ? "Entering" : "Exiting", GetKeyName().c_str()); ISendTriggerMsg(); } plgDispatch::Dispatch()->UnRegisterForExactType(plEvalMsg::Index(), GetKey()); fWaitingForEval = false; #ifdef USE_PHYSX_COLLISION_FLUTTER_WORKAROUND } #endif }
bool plSubworldRegionDetector::MsgReceive(plMessage* msg) { plCollideMsg* pCollMsg = plCollideMsg::ConvertNoRef(msg); if (pCollMsg) { if (plNetClientApp::GetInstance()->GetLocalPlayerKey() != pCollMsg->fOtherKey) return true; plArmatureMod* avMod = IGetAvatarModifier(pCollMsg->fOtherKey); if (avMod) { DetectorLog("%s subworld detector %s", pCollMsg->fEntering ? "Entering" : "Exiting", GetKeyName().c_str()); if ((pCollMsg->fEntering && !fOnExit) || (!pCollMsg->fEntering && fOnExit)) { if (fSub) { plSceneObject* SO = plSceneObject::ConvertNoRef(fSub->ObjectIsLoaded()); if (SO) { DetectorLogSpecial("Switching to subworld %s", fSub->GetName().c_str()); plKey nilKey; plSubWorldMsg* msg = new plSubWorldMsg(GetKey(), avMod->GetKey(), fSub); msg->Send(); } } else { DetectorLogSpecial("Switching to main subworld"); plSubWorldMsg* msg = new plSubWorldMsg(GetKey(), avMod->GetKey(), nil); msg->Send(); } } } return true; } return plCollisionDetector::MsgReceive(msg); }