예제 #1
0
void hsMatrix44::MakeCameraMatrices(const hsPoint3& from, const hsPoint3& at, const hsVector3& up, hsMatrix44& worldToCamera, hsMatrix44& cameraToWorld)
{
    hsVector3 dirZ(&at, &from);

    hsVector3 dirX(dirZ % up);
    dirX.Normalize();

    hsVector3 dirY(dirX % dirZ);
    dirY.Normalize();

    worldToCamera.Reset(false);
    cameraToWorld.Reset(false);
    int i;
    for( i = 0; i < 3; i++ )
    {
        worldToCamera.fMap[0][i] = dirX[i];
        worldToCamera.fMap[1][i] = dirY[i];
        worldToCamera.fMap[2][i] = dirZ[i];

        cameraToWorld.fMap[i][0] = dirX[i];
        cameraToWorld.fMap[i][1] = dirY[i];
        cameraToWorld.fMap[i][2] = dirZ[i];
    }
    hsPoint3 trans = -from;
    worldToCamera.fMap[0][3] = dirX.InnerProduct(trans);
    worldToCamera.fMap[1][3] = dirY.InnerProduct(trans);
    worldToCamera.fMap[2][3] = dirZ.InnerProduct(trans);

    cameraToWorld.fMap[0][3] = from.fX;
    cameraToWorld.fMap[1][3] = from.fY;
    cameraToWorld.fMap[2][3] = from.fZ;
}
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();
}
예제 #4
0
void GetPositionAndRotation(hsMatrix44 transform, hsScalarTriple *position, hsQuat *rotation)
{
    hsPoint3 p = (hsPoint3)transform.GetTranslate();
    position->fX = p.fX; position->fY = p.fY; position->fZ = p.fZ;
    
    
    transform.RemoveScale();
    
    rotation->SetFromMatrix(&transform);
    rotation->Normalize();
    
    float angle;
    hsVector3 axis;
    
    rotation->GetAngleAxis(&angle, &axis);
}
예제 #5
0
static void ClearMatrix(hsMatrix44 &m)
{
    m.fMap[0][0] = 0.0f; m.fMap[0][1] = 0.0f; m.fMap[0][2] = 0.0f; m.fMap[0][3]  = 0.0f;
    m.fMap[1][0] = 0.0f; m.fMap[1][1] = 0.0f; m.fMap[1][2] = 0.0f; m.fMap[1][3]  = 0.0f;
    m.fMap[2][0] = 0.0f; m.fMap[2][1] = 0.0f; m.fMap[2][2] = 0.0f; m.fMap[2][3]  = 0.0f;
    m.fMap[3][0] = 0.0f; m.fMap[3][1] = 0.0f; m.fMap[3][2] = 0.0f; m.fMap[3][3]  = 0.0f;
    m.NotIdentity();
}
예제 #6
0
void plAnimatedMovementStrategy::IRecalcLinearVelocity(float elapsed, hsMatrix44 &prevMat, hsMatrix44 &curMat)
{
    hsPoint3 startPos(0.0f, 0.0f, 0.0f);                    // default position (at start of anim)
    hsPoint3 prevPos = prevMat.GetTranslate();              // position previous frame
    hsPoint3 nowPos = curMat.GetTranslate();                // position current frame

    hsVector3 prev2Now = (hsVector3)(nowPos - prevPos);     // frame-to-frame delta

    if (fabs(prev2Now.fX) < 0.0001f && fabs(prev2Now.fY) < 0.0001f && fabs(prev2Now.fZ) < 0.0001f)
    {
        fAnimLinearVel.Set(0.f, 0.f, 0.f);
    }
    else
    {
        hsVector3 start2Now = (hsVector3)(nowPos - startPos);    // start-to-frame delta

        float prev2NowMagSqr = prev2Now.MagnitudeSquared();
        float start2NowMagSqr = start2Now.MagnitudeSquared();

        float dot = prev2Now.InnerProduct(start2Now);

        // HANDLING ANIMATION WRAPPING:
        // the vector from the animation origin to the current frame should point in roughly
        // the same direction as the vector from the previous animation position to the
        // current animation position.
        //
        // If they don't agree (dot < 0,) then we probably mpst wrapped around.
        // The right answer would be to compare the current frame to the start of
        // the anim loop, but it's cheaper to cheat and use the previous frame's velocity.
        if (dot > 0.0f)
        {
            prev2Now /= elapsed;

            float xfabs = fabs(prev2Now.fX);
            float yfabs = fabs(prev2Now.fY);
            float zfabs = fabs(prev2Now.fZ);
            static const float maxVel = 20.0f;
            bool valid = xfabs < maxVel && yfabs < maxVel && zfabs < maxVel;

            if (valid)
            {
                fAnimLinearVel = prev2Now;
            }
        }
    }
}
예제 #7
0
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);
}
예제 #8
0
// GETTRANSFORM
void plPXPhysical::GetTransform(hsMatrix44& l2w, hsMatrix44& w2l)
{
    IGetTransformGlobal(l2w);
    l2w.GetInverse(&w2l);
}