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");
    }
}
示例#5
0
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);
        }
    }
}
示例#6
0
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;
}
示例#8
0
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
}
示例#9
0
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);
}