public ThirdPersonController(ThirdPersonControllerDesc desc) { _character = desc.Character; _collitionController = desc.CollitionController; _walk = desc.Walk; _idle = desc.Idle; _turn90Speed = Numerics.PI / 2 / desc.TransitionTime; _turn180Speed = Numerics.PI / desc.TransitionTime; _cameraMaxDistance = desc.CameraMaxDistance; _cameraMinDistance = desc.CameraMinDistance; _cameraMaxPich = desc.CameraMaxPich; _cameraMinPich = desc.CameraMinPich; _camera = desc.Camera; _resetter = new BonesResetter(_character); _idleWalk = new AnimationTransition(_idle, _walk, desc.TransitionTime); _walkIdle = new AnimationTransition(_walk, _idle, desc.TransitionTime); _walk.FirstPlayback.Animation.Sample(_walk.FirstPlayback.Cursor.StartTime); _initialForwardPositon = _character.LocalPosition; _walk.FirstPlayback.Animation.Sample(_walk.FirstPlayback.Cursor.StartTime + desc.TransitionTime); _lastAnimPosition = _character.LocalPosition; _walkForwardSpeed = _character.LocalPosition - _initialForwardPositon; _resetter.Reset(); _initialHeading = _character.Heading; CreateStates(); _cameraBindedToCharacter = _camera.Affector == _character; }
public void BlendAnimation() { SceneTests.InitializeScene(); ContentImporter.Import(SceneManager.Scene, @"C:\Users\ansel\Documents\3dsmax\export\Lighting\armed.DAE") .OnSceneAttach(SceneManager.Scene); ContentImporter.ImportAnimation(SceneManager.Scene, @"C:\Users\ansel\Documents\3dsmax\export\Lighting\walk.DAE") .OnSceneAttach(SceneManager.Scene); var armed = SceneManager.Scene.AnimManager.Animations[0]; var walk = SceneManager.Scene.AnimManager.Animations[1]; Frame root = SceneManager.Scene.EnumerateNodesPosOrden().First(x => x.Type == FrameType.Bone); var resetter = new BonesResetter(root); var translation = root.LocalPosition; var cursorArmed = armed.GetCursor(0); var cursorWalk = walk.GetCursor(0); cursorArmed.Looping = AnimationLooping.Loop; cursorWalk.Looping = AnimationLooping.Loop; SceneManager.Scene.Dynamics.Add( new Dynamic(deltaT => { resetter.Reset(); walk.Update(deltaT, 0, 1, true); armed.Update(deltaT, 0, 1, true); root.LocalPosition = translation; root.CommitChanges(); }) ); }
public override void Update(float elapsedTime) { //store position previus animation var localPosition = _character.LocalPosition; //reset displacement _displacement = new Vector3(); //reset transforms for blending _resetter.Reset(); //update states base.Update(elapsedTime); //set character orientation character _character.Heading = _initialHeading + _heading; //clear the animation position _character.X = localPosition.X; _character.Z = localPosition.Z; if (_collitionController != null) { //apply displacement only on x,z Vector3 disp = _displacement; disp.Y = 0; //the moving of the character associated is defered until the physics scene updates //its state _collitionController.Move(disp, CollitionMask, 0.000001f, 1.0f); } else { _character.X += _displacement.X; _character.Z += _displacement.Z; //camera.Tx += displacement.X; //camera.Tz += displacement.Z; //camera.CommitChanges(); } _character.ComputeLocalPose(); _character.CommitChanges(); }
public void Transitions_Idle_Walk() { SceneTests.InitializeScene(); const float startTimeWalk = 34f / 30f; const float endTimeWalk = 63f / 30f; const float durationWalk = endTimeWalk - startTimeWalk; const float startTimeIdle = 0; const float endTimeIdle = 0; const float durationIdle = endTimeIdle; const float blendDuration = 0.25f; Vector3 speedVector = new Vector3(0, 0, -1f); var content = ContentImporter.Import(SceneManager.Scene, @"C:\Users\ansel\Documents\3dsmax\export\lighting_shadowed.DAE"); content.OnSceneAttach(SceneManager.Scene); Frame cameraNode = SceneManager.Scene.FindNode("camera1"); Frame root = SceneManager.Scene.EnumerateNodesPosOrden().First(x => x.Type == FrameType.Bone); BonesResetter resetter = new BonesResetter(root); Vector3 iniTrasnlation = root.LocalPosition; Vector3 translation = root.LocalPosition; var iniHeading = root.Heading; var animation = SceneManager.Scene.AnimManager.Animations[0]; animation.Sample(startTimeWalk); var iniKeyValue = root.LocalPosition; animation.Sample(endTimeWalk); var lastKeyValue = root.LocalPosition; Vector3 lastAnimTrans = root.LocalPosition; //new Vector3(); bool update = false; float deltaH = 0; Action <SecuenceNode, float> updateAction = (node, deltaT) => { if (!update) { lastAnimTrans = root.LocalPosition; update = true; return; } var cursor = node.Animations[0].Cursor; Vector3 disp; if (!cursor.TimeRestart) { disp = root.LocalPosition - lastAnimTrans; } else { disp = root.LocalPosition - (cursor.PlayDirection > 0 ? iniKeyValue : lastKeyValue); } disp = Vector3.TransformCoordinates(disp, Matrix.RotationY(deltaH)); translation += disp; lastAnimTrans = root.LocalPosition; }; SecuenceStateMachine states = new SecuenceStateMachine() .WithState(new SecuenceNode("idle", animation, startTimeIdle, durationIdle, AnimationLooping.Loop)) .WithState(new SecuenceNode("walk", animation, startTimeWalk, durationWalk, AnimationLooping.Loop) .Deactivating(node => update = false) .AfterUpdate(updateAction)) .WithTransition("idle", "walk", new SecuenceTransition(blendDuration) .FiredWhen(t => { var destNode = t.DestNode; if (Engine.KeyBoard.IsKeyPressed(Keys.Uparrow)) { destNode.PlayDirection = 1; update = false; return(true); } else if (Engine.KeyBoard.IsKeyPressed(Keys.Downarrow)) { destNode.PlayDirection = -1; update = false; return(true); } return(false); }) .WhenBlending((t, dt) => { Vector3 disp = new Vector3(); var cursor = t.DestNode.Animations[0].Cursor; if (Engine.KeyBoard.IsKeyPressed(Keys.Uparrow)) { disp = speedVector; } else { disp = -speedVector; } translation += Vector3.TransformCoordinates(disp, Matrix.RotationY(deltaH)); })) .WithTransition("walk", "idle", new SecuenceTransition(blendDuration) .FiredWhen(t => { if (!Engine.KeyBoard.IsKeyPressed(Keys.Uparrow) && !Engine.KeyBoard.IsKeyPressed(Keys.Downarrow)) { update = false; return(true); } return(false); }) .WhenBlending((t, dt) => { })); SceneManager.Scene.Dynamics.Add( new Dynamic(deltaT => { var oldposition = root.GlobalPosition; float rotSpeed = Numerics.ToRadians(90f); if (Engine.KeyBoard.IsKeyPressed(Keys.Leftarrow)) { deltaH -= rotSpeed * deltaT; } else if (Engine.KeyBoard.IsKeyPressed(Keys.Rightarrow)) { deltaH += rotSpeed * deltaT; } resetter.Reset(); states.Update(deltaT); root.X = translation.X; root.Z = translation.Z; root.Heading = iniHeading + deltaH; root.ComputeLocalPose(); root.CommitChanges(); var displacement = root.GlobalPosition - oldposition; cameraNode.X += displacement.X; cameraNode.Z += displacement.Z; cameraNode.CommitChanges(); }) ); }
public void Automata_Idle_Walk() { SceneTests.InitializeScene(); const float startTimeWalk = 34f / 30f; const float endTimeWalk = 63f / 30f; const float durationWalk = endTimeWalk - startTimeWalk; const float startTimeIdle = 0; const float endTimeIdle = 0; const float durationIdle = endTimeIdle; const float blendDuration = 0.25f; Vector3 speedVector = new Vector3(0, 0, -1f); ContentImporter.Import(SceneManager.Scene, @"C:\Users\ansel\Documents\3dsmax\export\lighting_shadowed.DAE") .OnSceneAttach(SceneManager.Scene); Frame cameraNode = SceneManager.Scene.FindNode("camera1"); Frame root = SceneManager.Scene.EnumerateNodesPosOrden().First(x => x.Type == FrameType.Bone); BonesResetter resetter = new BonesResetter(root); Vector3 translation = root.LocalPosition; var iniHeading = root.Heading; var animation = SceneManager.Scene.AnimManager.Animations[0]; animation.Sample(startTimeWalk); var iniKeyValue = root.LocalPosition; animation.Sample(endTimeWalk); var lastKeyValue = root.LocalPosition; Vector3 lastAnimTrans = root.LocalPosition; //new Vector3(); bool update = false; float deltaH = 0; KeyFrameAnimationPlayback idle = new KeyFrameAnimationPlayback(animation, startTimeIdle, durationIdle, AnimationLooping.Loop); KeyFrameAnimationPlayback walk = new KeyFrameAnimationPlayback(animation, startTimeWalk, durationWalk, AnimationLooping.Loop); AnimationTransition idleWalk = new AnimationTransition(idle, walk, blendDuration); AnimationTransition walkIdle = new AnimationTransition(walk, idle, blendDuration); var walkCursor = walk.GetCursor(animation); Action <float> updateAction = (deltaT) => { walk.Update(deltaT); if (!update) { lastAnimTrans = root.LocalPosition; update = true; return; } var cursor = walkCursor; if (!cursor.TimeRestart) { _disp = root.LocalPosition - lastAnimTrans; } else { _disp = root.LocalPosition - (cursor.PlayDirection > 0 ? iniKeyValue : lastKeyValue); } _disp = Vector3.TransformCoordinates(_disp, Matrix.RotationY(deltaH)); translation += _disp; lastAnimTrans = root.LocalPosition; }; Automata stateMachine = new Automata() .AddState("idle", x => idle.Update(x)) .AddState("idle-walk", dt => { idleWalk.Update(dt); _disp = new Vector3(); if (Engine.KeyBoard.IsKeyPressed(Keys.Uparrow)) { _disp = speedVector; } else { _disp = -speedVector; } _disp = Vector3.TransformCoordinates(_disp, Matrix.RotationY(deltaH)); }) .AddState("walk", updateAction) .AddState("walk-idle", x => walkIdle.Update(x)) .AddTransition("idle", "idle-walk", x => { if (Engine.KeyBoard.IsKeyPressed(Keys.Uparrow)) { walk.FirstPlayback.Cursor.PlayDirection = 1; update = false; return(true); } else if (Engine.KeyBoard.IsKeyPressed(Keys.Downarrow)) { walk.FirstPlayback.Cursor.PlayDirection = -1; update = false; return(true); } return(false); }) .AddTransition("idle-walk", "walk", x => idleWalk.TransitionComplete) .AddTransition("walk", "walk-idle", x => !Engine.KeyBoard.IsKeyPressed(Keys.Uparrow) && !Engine.KeyBoard.IsKeyPressed(Keys.Downarrow)) .AddTransition("walk-idle", "idle", x => walkIdle.TransitionComplete); SceneManager.Scene.Dynamics.Add(new Dynamic(deltaT => { //store position previus animation var localPosition = root.LocalPosition; _disp = new Vector3(); float rotSpeed = Numerics.ToRadians(90f); if (Engine.KeyBoard.IsKeyPressed(Keys.Leftarrow)) { deltaH -= rotSpeed * deltaT; } else if (Engine.KeyBoard.IsKeyPressed(Keys.Rightarrow)) { deltaH += rotSpeed * deltaT; } resetter.Reset(); stateMachine.Update(deltaT); //root.Tx = translation.X; //root.Tz = translation.Z; root.X = localPosition.X + _disp.X; root.Z = localPosition.Z + _disp.Z; root.Heading = iniHeading + deltaH; root.ComputeLocalPose(); root.CommitChanges(); //var displacement = root.GlobalPose.Translation - localPosition; //cameraNode.Tx += displacement.X; //cameraNode.Tz += displacement.Z; cameraNode.X += _disp.X; cameraNode.Z += _disp.Z; cameraNode.CommitChanges(); })); }