Ejemplo n.º 1
0
// ICalcProbeLengths -------------------
// -----------------
void plAvBrainClimb::ICalcProbeLengths()
{
    // we assume that the up and down climbs go the same distance;
    // same for the left and right climbs
    plAGAnim *up = fAvMod->FindCustomAnim("ClimbUp");
    plAGAnim *left = fAvMod->FindCustomAnim("ClimbLeft");

    hsMatrix44 upMove, leftMove;

    hsAssert(up, "Couldn't find ClimbUp animation.");
    if(up)
    {
        GetStartToEndTransform(up, &upMove, nil, "Handle");
        fVerticalProbeLength = upMove.GetTranslate().fZ;
    } else
        fVerticalProbeLength = 4.0f;    // guess

    hsAssert(left, "Couldn't find ClimbLeft animation.");
    if(left)
    {
        GetStartToEndTransform(left, &leftMove, nil, "Handle");
        fHorizontalProbeLength = leftMove.GetTranslate().fX;
    } else
        fHorizontalProbeLength = 3.0f;  // guess
}
Ejemplo n.º 2
0
// IIsClosestAnim -------------------------------------------------------------------
// ---------------
bool IIsClosestAnim(const char *animName, hsMatrix44 &sitGoal, float &closestDist,
                    hsPoint3 curPosition, const plArmatureMod *avatar)
{
    plAGAnim *anim = avatar->FindCustomAnim(animName);
    if(anim)
    {
        hsMatrix44 animEndToStart;
        // The sit target is the position we want to be at the END of the sit animation.
        // We have several animations to choose from, each starting from a different
        // position.
        // This will look at one of those animations and figure out how far we are from
        // its starting position.
        // The first step is to get the transform from the end to the beginning of the
        // animation. That's what this next line is doing. It's a bit unintuitive
        // until you look at the parameter definitions.
        GetStartToEndTransform(anim, nil, &animEndToStart, "Handle");
        hsMatrix44 candidateGoal = sitGoal * animEndToStart;
        hsPoint3 distP = candidateGoal.GetTranslate() - curPosition;
        hsVector3 distV(distP.fX, distP.fY, distP.fZ);
        float dist = distP.Magnitude();
        if(closestDist == 0.0 || dist < closestDist)
        {
            closestDist = dist;
            return true;
        }
    } else {
        hsAssert(false, ST::format("Missing sit animation: {}", animName).c_str());
    }
    return false;
}
Ejemplo n.º 3
0
// START
// Adjust our goal time based on our duration and the current time
bool plAvSeekTask::Start(plArmatureMod *avatar, plArmatureBrain *brain, double time, float elapsed)
{
    fTargetTime = time + fDuration;     // clock starts now....
    fPhysicalAtStart = avatar->IsPhysicsEnabled();
    avatar->EnablePhysics(false);       // always turn physics off for seek
    plAvBrainHuman *huBrain = plAvBrainHuman::ConvertNoRef(brain);
    if(huBrain)
        huBrain->IdleOnly();
    
    ILimitPlayersInput(avatar);
    
    if (!fTarget || !fTarget->ObjectIsLoaded())
    {
        fCleanup = true;
        return true;
    }
    
    plSceneObject* seekTarget = plSceneObject::ConvertNoRef(fTarget->ObjectIsLoaded());
    hsMatrix44 targetL2W = seekTarget->GetLocalToWorld();
    const plCoordinateInterface* subworldCI = nil;
    if (avatar->GetController())
        subworldCI = avatar->GetController()->GetSubworldCI();
    if (subworldCI)
        targetL2W = subworldCI->GetWorldToLocal() * targetL2W;

    switch(fAlign)
    {
        // just match our handle to the target matrix
        case kAlignHandle:
            // targetL2Sim is already correct
            break;
        // match our handle to the target matrix at the end of the given animation
        case kAlignHandleAnimEnd:
            {
                hsMatrix44 adjustment;
                plAGAnim *anim = avatar->FindCustomAnim(fAnimName);
                GetStartToEndTransform(anim, nil, &adjustment, "Handle");   // actually getting end-to-start
                targetL2W = targetL2W * adjustment;
            }
            break;
        default:
            break;
    };

    GetPositionAndRotation(targetL2W, &fTargetPosition, &fTargetRotation);
    Process(avatar, brain, time, elapsed);
    return true;
}
Ejemplo n.º 4
0
// IUpdateObjective ----------------------------------------
// -----------------
hsBool plAvTaskSeek::IUpdateObjective(plArmatureMod *avatar)
{
    // This is an entirely valid case. It just means our goal is fixed.
    if (fSeekObject == nil)
        return true;

    // goal here is to express the target matrix in the avatar's PHYSICAL space
    hsMatrix44 targL2W = fSeekObject->GetLocalToWorld();
    const plCoordinateInterface* subworldCI = nil;
    if (avatar->GetController())
        subworldCI = avatar->GetController()->GetSubworldCI();
    if (subworldCI)
        targL2W = subworldCI->GetWorldToLocal() * targL2W;

    MakeMatrixUpright(targL2W);

    switch(fAlign)
    {
        // match our handle to the target matrix at the end of the given animation
        // This case isn't currently used but will be important someday. The idea
        // is that you have a target point and an animation, and you want to seek
        // the avatar to a point where he can start playing the animation and wind
        // up, after the animation completes, at the target location.
        // Hence "AlignHandleAnimEnd" = "align the avatar so the animation will
        // end on the target."
        case kAlignHandleAnimEnd:
            {
                hsMatrix44 adjustment;
                plAGAnim *anim = avatar->FindCustomAnim(fAnimName);
                // don't need to do this every frame; the animation doesn't change.
                // *** cache the adjustment;
                GetStartToEndTransform(anim, nil, &adjustment, _TEMP_CONVERT_FROM_LITERAL("Handle"));   // actually getting end-to-start
                // ... but we do still need to multiply by the (potentially changed) target
                targL2W = targL2W * adjustment;
            }
            break;
        case kAlignHandle:      // targetMat is already correct
        default:
            break;
    };

    GetPositionAndRotation(targL2W, &fSeekPos, &fSeekRot);

    return true;
}