void plPXPhysicalControllerCore::ISetKinematicLoc(const hsMatrix44& l2w)
{
    hsPoint3 kPos;
    // Update our subworld position and rotation
    const plCoordinateInterface* subworldCI = GetSubworldCI();
    if (subworldCI)
    {
        const hsMatrix44& w2s = subworldCI->GetWorldToLocal();
        hsMatrix44 l2s = w2s * l2w;

        l2s.GetTranslate(&kPos);
    }
    else
    {
        l2w.GetTranslate(&kPos);
    }

    hsMatrix44 w2l;
    l2w.GetInverse(&w2l);
    if (fProxyGen)
        fProxyGen->SetTransform(l2w, w2l);

    // add z offset
    kPos.fZ += kPhysZOffset;
    // Update the physical position of kinematic
    if (fKinematicActor->readBodyFlag(NX_BF_KINEMATIC))
        fKinematicActor->moveGlobalPosition(plPXConvert::Point(kPos));
    else
        fKinematicActor->setGlobalPosition(plPXConvert::Point(kPos));
}
void plPXPhysicalControllerCore::ISetGlobalLoc(const hsMatrix44& l2w)
{
    fLastGlobalLoc = l2w;
    // Update our subworld position and rotation
    const plCoordinateInterface* subworldCI = GetSubworldCI();
    if (subworldCI)
    {
        const hsMatrix44& w2s = fPrevSubworldW2L;
        hsMatrix44 l2s = w2s * l2w;

        l2s.GetTranslate(&fLocalPosition);
        fLocalRotation.SetFromMatrix44(l2s);
    }
    else
    {
        l2w.GetTranslate(&fLocalPosition);
        fLocalRotation.SetFromMatrix44(l2w);
    }
    hsMatrix44 w2l;
    l2w.GetInverse(&w2l);
    if (fProxyGen)
        fProxyGen->SetTransform(l2w, w2l);
    // Update the physical position
    NxExtendedVec3 nxPos(fLocalPosition.fX, fLocalPosition.fY, fLocalPosition.fZ + kPhysZOffset);
    fController->setPosition(nxPos);
    IMatchKinematicToController();
}
void plPXPhysical::ISetTransformGlobal(const hsMatrix44& l2w)
{
    hsAssert(fActor->isDynamic(), "Shouldn't move a static actor");

    // If we wake up normal dynamic actors, they might explode.
    // However, kinematics won't update if they are asleep. Thankfully, kinematics don't
    //          explode, move, or cause spontaneous nuclear warfare.
    if (fActor->readBodyFlag(NX_BF_KINEMATIC))
        fActor->wakeUp();

    NxMat34 mat;

    if (fWorldKey)
    {
        plSceneObject* so = plSceneObject::ConvertNoRef(fWorldKey->ObjectIsLoaded());
        hsAssert(so, "Scene object not loaded while accessing subworld.");
        // physical to subworld (simulation space)
        hsMatrix44 p2s = so->GetCoordinateInterface()->GetWorldToLocal() * l2w;
        plPXConvert::Matrix(p2s, mat);
        if (fProxyGen)
        {
            hsMatrix44 w2l;
            p2s.GetInverse(&w2l);
            fProxyGen->SetTransform(p2s, w2l);
        }
    }
    // No need to localize
    else
    {
        plPXConvert::Matrix(l2w, mat);
        if (fProxyGen)
        {
            hsMatrix44 w2l;
            l2w.GetInverse(&w2l);
            fProxyGen->SetTransform(l2w, w2l);
        }
    }

    // This used to check for the kPhysAnim flag, however animated detectors
    // are also kinematic but not kPhysAnim, therefore, this would break on PhysX
    // SDKs (yes, I'm looking at you, 2.6.4) that actually obey the ***GlobalPose 
    // rules set forth in the SDK documentation.
    if (fActor->readBodyFlag(NX_BF_KINEMATIC))
        fActor->moveGlobalPose(mat);
    else
        fActor->setGlobalPose(mat);
}
// GETTRANSFORM
void plPXPhysical::GetTransform(hsMatrix44& l2w, hsMatrix44& w2l)
{
    IGetTransformGlobal(l2w);
    l2w.GetInverse(&w2l);
}