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 plSimulationMgr::AddCollisionMsg(plKey hitee, plKey hitter, bool enter)
{
    // First, make sure we have no dupes
    for (CollisionVec::iterator it = fCollideMsgs.begin(); it != fCollideMsgs.end(); ++it)
    {
        plCollideMsg* pMsg = *it;

        // Should only ever be one receiver.
        // Oh, it seems we should update the hit status. The latest might be different than the older...
        // Even in the same frame >.<
        if (pMsg->fOtherKey == hitter && pMsg->GetReceiver(0) == hitee)
        {
            pMsg->fEntering = enter;
            DetectorLogRed("DUPLICATE COLLISION: %s hit %s",
                (hitter ? hitter->GetName().c_str() : "(nil)"),
                (hitee ? hitee->GetName().c_str() : "(nil)"));
            return;
        }
    }

    // Still here? Then this must be a unique hit!
    plCollideMsg* pMsg = new plCollideMsg;
    pMsg->AddReceiver(hitee);
    pMsg->fOtherKey = hitter;
    pMsg->fEntering = enter;
    fCollideMsgs.push_back(pMsg);
}
///////////////////////////////////
///////////////////////////////////
/// plPanicLinkDetector
///////////////////////////////////
bool plPanicLinkRegion::MsgReceive(plMessage* msg)
{
    if (plCollideMsg* pCollMsg = plCollideMsg::ConvertNoRef(msg))
    {
        if (plNetClientApp::GetInstance()->GetLocalPlayerKey() != pCollMsg->fOtherKey)
            return true;

        if (pCollMsg->fEntering)
        {
            plArmatureMod* avMod = IGetAvatarModifier(pCollMsg->fOtherKey);
            if (avMod)
            {
                if (avMod->IsLinkedIn())
                {
                    hsPoint3 pos;
                    if (avMod->GetController())
                    {
                        avMod->GetController()->GetPositionSim(pos);
                        DetectorLogSpecial("Avatar is panic linking. Position %f,%f,%f and is %s", pos.fX, pos.fY, pos.fZ, avMod->GetController()->IsEnabled() ? "enabled" : "disabled");
                    }
                    avMod->PanicLink(fPlayLinkOutAnim);
                } else
                    DetectorLogRed("PANIC LINK %s before we actually linked in!", GetKey()->GetName().c_str());
            }
        }

        return true;
    }

    return plCollisionDetector::MsgReceive(msg);
}
Exemple #4
0
    virtual void onTrigger(NxShape& triggerShape, NxShape& otherShape, NxTriggerFlag status)
    {
        plKey otherKey = nil;
        bool doReport = false;

        // Get our trigger physical.  This should definitely have a plPXPhysical
        plPXPhysical* triggerPhys = (plPXPhysical*)triggerShape.getActor().userData;

        // Get the triggerer. If it doesn't have a plPXPhyscial, it's an avatar
        plPXPhysical* otherPhys = (plPXPhysical*)otherShape.getActor().userData;
        if (otherPhys)
        {
            otherKey = otherPhys->GetObjectKey();
            doReport = triggerPhys->DoReportOn((plSimDefs::Group)otherPhys->GetGroup());
        }
        else
        {
            plPXPhysicalControllerCore* controller = plPXPhysicalControllerCore::GetController(otherShape.getActor());
            if (controller)
            {
                otherKey = controller->GetOwner();
                doReport = triggerPhys->DoReportOn(plSimDefs::kGroupAvatar);
            }
        }

        if (doReport)
        {
            if (status & NX_TRIGGER_ON_ENTER)
            {
                if (plSimulationMgr::fExtraProfile)
                    DetectorLogRed("-->Send Collision %s enter",triggerPhys->GetObjectKey()->GetName().c_str());
                plSimulationMgr::GetInstance()->AddCollisionMsg(triggerPhys->GetObjectKey(), otherKey, true);
            }
            else if (status & NX_TRIGGER_ON_LEAVE)
            {
                if (plSimulationMgr::fExtraProfile)
                    DetectorLogRed("-->Send Collision %s exit",triggerPhys->GetObjectKey()->GetName().c_str());
                plSimulationMgr::GetInstance()->AddCollisionMsg(triggerPhys->GetObjectKey(), otherKey, false);
            }
        }
    }
    virtual void onTrigger(NxShape& triggerShape, NxShape& otherShape, NxTriggerFlag status)
    {
        // Get our trigger physical.  This should definitely have a plPXPhysical
        plPXPhysical* triggerPhys = (plPXPhysical*)triggerShape.getActor().userData;
        bool doReport = false;

        // Get the triggerer.  This may be an avatar, which doesn't have a
        // plPXPhysical, so we have to extract the necessary info.
        plKey otherKey = nil;
        hsPoint3 otherPos = plPXConvert::Point(otherShape.getGlobalPosition());

        if (plSimulationMgr::fExtraProfile)
            DetectorLogRed("-->%s %s (status=%x) other@(%f,%f,%f)",triggerPhys->GetObjectKey()->GetName().c_str(),status & NX_TRIGGER_ON_ENTER ? "enter" : "exit",status,otherPos.fX,otherPos.fY,otherPos.fZ);

        plPXPhysical* otherPhys = (plPXPhysical*)otherShape.getActor().userData;
        if (otherPhys)
        {
            otherKey = otherPhys->GetObjectKey();
            doReport = triggerPhys->DoReportOn((plSimDefs::Group)otherPhys->GetGroup());
            if (!doReport)
            {
                if (plSimulationMgr::fExtraProfile)
                    DetectorLogRed("<--Kill collision %s :failed group. US=%x OTHER=(%s)%x",triggerPhys->GetObjectKey()->GetName().c_str(),triggerPhys->GetGroup(),otherPhys->GetObjectKey()->GetName().c_str(),otherPhys->GetGroup());
            }
        }
        else
        {
            bool isController;
            plPXPhysicalControllerCore* controller = plPXPhysicalControllerCore::GetController(otherShape.getActor(),&isController);
            if (controller)
            {
                if (isController)
                {
#ifdef PHYSX_ONLY_TRIGGER_FROM_KINEMATIC
                    if (plSimulationMgr::fExtraProfile)
                        DetectorLogRed("<--Kill collision %s : ignoring controller events.",triggerPhys->GetObjectKey()->GetName().c_str());
                    return;
#else // else if trigger on both controller and kinematic
                    // only suppress controller collision 'enters' when disabled but let 'exits' continue
                    // ...this is because there are detector regions that are on the edge on ladders that the exit gets missed.
                    if ( ( !controller->IsEnabled() /*&& (status & NX_TRIGGER_ON_ENTER)*/ ) || controller->IsKinematic() )
                    {
                        if (plSimulationMgr::fExtraProfile)
                            DetectorLogRed("<--Kill collision %s : controller is not enabled.",triggerPhys->GetObjectKey()->GetName().c_str());
                        return;
                    }
#endif  // PHYSX_ONLY_TRIGGER_FROM_KINEMATIC
                }
#ifndef PHYSX_ONLY_TRIGGER_FROM_KINEMATIC  // if triggering only kinematics, then all should trigger
                else
                {
                    // only suppress kinematic collision 'enters' when disabled but let 'exits' continue
                    // ...this is because there are detector regions that are on the edge on ladders that the exit gets missed.
                    if ( !controller->IsKinematic() /*&& (status & NX_TRIGGER_ON_ENTER) */ )
                    {
                        if (plSimulationMgr::fExtraProfile)
                            DetectorLogRed("<--Kill collision %s : kinematic is not enabled.",triggerPhys->GetObjectKey()->GetName().c_str());
                        return;
                    }
                }
#endif  // PHYSX_ONLY_TRIGGER_FROM_KINEMATIC
                otherKey = controller->GetOwner();
                doReport = triggerPhys->DoReportOn(plSimDefs::kGroupAvatar);
                if (plSimulationMgr::fExtraProfile )
                {
                    if (!doReport)
                    {
                        DetectorLogRed("<--Kill collision %s :failed group. US=%x OTHER=(NotAvatar)",triggerPhys->GetObjectKey()->GetName().c_str(),triggerPhys->GetGroup());
                    }
                    else
                    {
                        hsPoint3 avpos;
                        controller->GetPositionSim(avpos);
                        DetectorLogRed("-->Avatar at (%f,%f,%f)",avpos.fX,avpos.fY,avpos.fZ);
                    }
                }
            }
        }

        if (doReport)
        {
#ifdef USE_PHYSX_CONVEXHULL_WORKAROUND
            if ( triggerPhys->DoDetectorHullWorkaround() )
            {
                if (status & NX_TRIGGER_ON_ENTER && triggerPhys->Should_I_Trigger(status & NX_TRIGGER_ON_ENTER, otherPos) )
                {
                    if (plSimulationMgr::fExtraProfile)
                        DetectorLogRed("-->Send Collision (CH) %s %s",triggerPhys->GetObjectKey()->GetName().c_str(),status & NX_TRIGGER_ON_ENTER ? "enter" : "exit");
                    plSimulationMgr::GetInstance()->AddCollisionMsg(triggerPhys->GetObjectKey(), otherKey, true);
                }
                else if (status & NX_TRIGGER_ON_ENTER)
                {
                    if (plSimulationMgr::fExtraProfile)
                        DetectorLogRed("<--Kill collision %s :failed Should I trigger",triggerPhys->GetObjectKey()->GetName().c_str());
                }
                if (status & NX_TRIGGER_ON_LEAVE && triggerPhys->Should_I_Trigger(status & NX_TRIGGER_ON_ENTER, otherPos) )
                {
                    if (plSimulationMgr::fExtraProfile)
                        DetectorLogRed("-->Send Collision (CH) %s %s",triggerPhys->GetObjectKey()->GetName().c_str(),status & NX_TRIGGER_ON_ENTER ? "enter" : "exit");
                    plSimulationMgr::GetInstance()->AddCollisionMsg(triggerPhys->GetObjectKey(), otherKey, false);
                }
                else if (status & NX_TRIGGER_ON_LEAVE)
                {
                    if (plSimulationMgr::fExtraProfile)
                        DetectorLogRed("<--Kill collision %s :failed Should I trigger",triggerPhys->GetObjectKey()->GetName().c_str());
                }
                if (!(status & NX_TRIGGER_ON_ENTER) && !(status & NX_TRIGGER_ON_LEAVE) )
                {
                    if (plSimulationMgr::fExtraProfile)
                        DetectorLogRed("<--Kill collision %s :failed event(CH)",triggerPhys->GetObjectKey()->GetName().c_str());
                }
            }
            else
            {
#endif  // USE_PHYSX_CONVEXHULL_WORKAROUND
                if (status & NX_TRIGGER_ON_ENTER)
                {
                    if (plSimulationMgr::fExtraProfile)
                        DetectorLogRed("-->Send Collision %s %s",triggerPhys->GetObjectKey()->GetName().c_str(),status & NX_TRIGGER_ON_ENTER ? "enter" : "exit");
                    plSimulationMgr::GetInstance()->AddCollisionMsg(triggerPhys->GetObjectKey(), otherKey, true);
                }
                if (status & NX_TRIGGER_ON_LEAVE)
                {
                    if (plSimulationMgr::fExtraProfile)
                        DetectorLogRed("-->Send Collision %s %s",triggerPhys->GetObjectKey()->GetName().c_str(),status & NX_TRIGGER_ON_ENTER ? "enter" : "exit");
                    plSimulationMgr::GetInstance()->AddCollisionMsg(triggerPhys->GetObjectKey(), otherKey, false);
                }
                if (!(status & NX_TRIGGER_ON_ENTER) && !(status & NX_TRIGGER_ON_LEAVE) )
                {
                    if (plSimulationMgr::fExtraProfile)
                        DetectorLogRed("<--Kill collision %s :failed event",triggerPhys->GetObjectKey()->GetName().c_str());
                }
#ifdef USE_PHYSX_CONVEXHULL_WORKAROUND
            }
#endif  // USE_PHYSX_CONVEXHULL_WORKAROUND
        }
    }