예제 #1
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;
}
예제 #2
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;
}