// 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; }
// 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; }