public EasingSample(Microsoft.Xna.Framework.Game game) : base(game) { // Initialize array of easing functions. _easingFunctions = new EasingFunction[] { null, new BackEase { Amplitude = 0.5f }, new BounceEase { Bounces = 3, Bounciness = 3 }, new CircleEase(), new CubicEase(), new ElasticEase { Oscillations = 3, Springiness = 10 }, new ExponentialEase(), new LogarithmicEase(), new HermiteEase(), new PowerEase { Power = 2 }, new QuadraticEase(), new QuinticEase(), new SineEase() }; // Create and start a horizontal from/to animation. Rectangle bounds = GraphicsService.GraphicsDevice.Viewport.TitleSafeArea; _fromToAnimation = new SingleFromToByAnimation { From = bounds.Left + 200, To = bounds.Right - 200, Duration = TimeSpan.FromSeconds(1.5), EasingFunction = _easingFunctions[_selectedEasingFunctionIndex], }; _animationController = AnimationService.StartAnimation(_fromToAnimation, _animatableFloat); _animationController.UpdateAndApply(); }
public BoneJiggleSample(Microsoft.Xna.Framework.Game game) : base(game) { var modelNode = ContentManager.Load<ModelNode>("Dude/Dude"); _meshNode = modelNode.GetSubtree().OfType<MeshNode>().First().Clone(); _meshNode.PoseLocal = new Pose(new Vector3F(0, 0, 0), Matrix33F.CreateRotationY(ConstantsF.Pi)); SampleHelper.EnablePerPixelLighting(_meshNode); GraphicsScreen.Scene.Children.Add(_meshNode); var animations = _meshNode.Mesh.Animations; var walkAnimation = new AnimationClip<SkeletonPose>(animations.Values.First()) { LoopBehavior = LoopBehavior.Cycle, Duration = TimeSpan.MaxValue, }; _walkAnimationController = AnimationService.StartAnimation(walkAnimation, (IAnimatableProperty)_meshNode.SkeletonPose); _walkAnimationController.AutoRecycle(); // Create a BoneJiggler instance for the head bone (bone index 7). _boneJiggler = new BoneJiggler(_meshNode.SkeletonPose, 7, new Vector3F(1.1f, 0, 0)) { Spring = 100, Damping = 3, }; }
public SkinnedEffectSample(Microsoft.Xna.Framework.Game game) : base(game) { SampleFramework.IsMouseVisible = false; GraphicsScreen.ClearBackground = true; GraphicsScreen.BackgroundColor = Color.CornflowerBlue; SetCamera(new Vector3F(1, 1, 3), 0.2f, 0); // Create a sky mesh and add an instance of this mesh to the scene. var skyMesh = ProceduralSkyDome.CreateMesh(GraphicsService, ContentManager.Load<Texture2D>("sky")); _sky = new MeshNode(skyMesh); _sky.Name = "Sky"; // Always set a name - very useful for debugging! GraphicsScreen.Scene.Children.Add(_sky); // Load the skinned model. This model is processed using the DigitalRune Model // Processor - not the default XNA model processor! // In the folder that contains dude.fbx, there are several XML files (*.drmdl and *.drmat) // which define the materials of the model. These material description files are // automatically processed by the DigitalRune Model Processor. Please browse // to the content folder and have a look at the *.drmdl and *.drmat files. var dudeModel = ContentManager.Load<ModelNode>("Dude/Dude"); dudeModel = dudeModel.Clone(); dudeModel.PoseWorld = new Pose(Matrix33F.CreateRotationY(ConstantsF.Pi)); GraphicsScreen.Scene.Children.Add(dudeModel); // The dude model consists of a single mesh. var dudeMeshNode = dudeModel.GetSubtree().OfType<MeshNode>().First(); var mesh = dudeMeshNode.Mesh; /* // The dude mesh consists of different materials (head, eyes, torso, ...). // We could change some of the material properties... foreach (var material in mesh.Materials) { // Get all SkinnedEffectBindings which wrap the XNA SkinnedEffect. // A material can consist of several effects - one effect for each render pass. // (Per default there is only one render pass called "Default".) foreach (var effectBinding in material.EffectBindings.OfType<SkinnedEffectBinding>()) { // We could change effect parameters here, for example: effectBinding.PreferPerPixelLighting = true; } } */ // The DigitalRune Model Processor also loads animations. // Start the first animation of the dude and let it loop forever. // (We keep the animation controller to be able to stop the animation in // Dispose() below.) var timeline = new TimelineClip(mesh.Animations.Values.First()) { Duration = TimeSpan.MaxValue, LoopBehavior = LoopBehavior.Cycle, }; _animationController = AnimationService.StartAnimation(timeline, (IAnimatableProperty)dudeMeshNode.SkeletonPose); }
public override void Update(GameTime gameTime) { base.Update(gameTime); if (InputService.IsPressed(Keys.Space, false)) { if (_state == 1) { // Fade-in the vertical animation, replacing the previous animations. _state = 2; _currentAnimationController = AnimationService.StartAnimation( _verticalAnimation, _animatedPosition, AnimationTransitions.Replace(TimeSpan.FromSeconds(0.5))); // Replace all previous animations using a fade-in of 0.5 seconds. _currentAnimationController.AutoRecycle(); } else { // Fade-in the horizontal animation, replacing the previous animations. _state = 1; _currentAnimationController = AnimationService.StartAnimation( _horizontalAnimation, _animatedPosition, AnimationTransitions.Replace(TimeSpan.FromSeconds(0.5))); _currentAnimationController.AutoRecycle(); } } if (InputService.IsPressed(Keys.Back, false)) { if (_state == 0) { // Fade-in the horizontal animation. _state = 1; _currentAnimationController = AnimationService.StartAnimation( _horizontalAnimation, _animatedPosition, AnimationTransitions.Replace(TimeSpan.FromSeconds(0.5))); _currentAnimationController.AutoRecycle(); } else { // Fade-out the current animation. _state = 0; _currentAnimationController.Stop(TimeSpan.FromSeconds(0.5)); // Fade-out over 0.5 seconds. } } }
public MixingSample(Microsoft.Xna.Framework.Game game) : base(game) { var modelNode = ContentManager.Load<ModelNode>("Marine/PlayerMarine"); _meshNode = modelNode.GetSubtree().OfType<MeshNode>().First().Clone(); SampleHelper.EnablePerPixelLighting(_meshNode); GraphicsScreen.Scene.Children.Add(_meshNode); var animations = _meshNode.Mesh.Animations; _runAnimation = new AnimationClip<SkeletonPose>(animations["Run"]) { LoopBehavior = LoopBehavior.Cycle, Duration = TimeSpan.MaxValue, }; _idleAnimation = new AnimationClip<SkeletonPose>(animations["Idle"]) { LoopBehavior = LoopBehavior.Cycle, Duration = TimeSpan.MaxValue, }; // Create a 'Shoot' animation that only affects the upper body. var shootAnimation = animations["Shoot"]; // The SkeletonKeyFrameAnimations allows to set a weight for each bone channel. // For the 'Shoot' animation, we set the weight to 0 for all bones that are // not descendants of the second spine bone (bone index 2). That means, the // animation affects only the upper body bones and is disabled on the lower // body bones. for (int i = 0; i < _meshNode.Mesh.Skeleton.NumberOfBones; i++) { if (!SkeletonHelper.IsAncestorOrSelf(_meshNode.SkeletonPose, 2, i)) shootAnimation.SetWeight(i, 0); } var loopedShootingAnimation = new AnimationClip<SkeletonPose>(shootAnimation) { LoopBehavior = LoopBehavior.Cycle, Duration = TimeSpan.MaxValue, }; // Start 'Idle' animation. _idleAnimationController = AnimationService.StartAnimation(_idleAnimation, (IAnimatableProperty)_meshNode.SkeletonPose); _idleAnimationController.AutoRecycle(); // Start looping the 'Shoot' animation. We use a Compose transition. This will add the // 'Shoot' animation to the animation composition chain and keeping all other playing // animations. // The 'Idle' animation animates the whole skeleton. The 'Shoot' animation replaces // the 'Idle' animation on the bones of the upper body. AnimationService.StartAnimation(loopedShootingAnimation, (IAnimatableProperty)_meshNode.SkeletonPose, AnimationTransitions.Compose() ).AutoRecycle(); }
public CrossFadeSample(Microsoft.Xna.Framework.Game game) : base(game) { Rectangle bounds = GraphicsService.GraphicsDevice.Viewport.TitleSafeArea; // Set the base value of the _animatedPosition. When the animations are stopped, // _animatedPosition will return to this value. _animatedPosition.Value = new Vector2(bounds.Center.X, bounds.Center.Y); // Create an oscillating horizontal animation. Vector2FromToByAnimation fromToAnimation = new Vector2FromToByAnimation { From = new Vector2(200, bounds.Center.Y), To = new Vector2(bounds.Right - 200, bounds.Center.Y), Duration = TimeSpan.FromSeconds(2), EasingFunction = new CubicEase { Mode = EasingMode.EaseInOut }, }; _horizontalAnimation = new AnimationClip<Vector2>(fromToAnimation) { LoopBehavior = LoopBehavior.Oscillate, Duration = TimeSpan.MaxValue, }; // Create an oscillating vertical animation. fromToAnimation = new Vector2FromToByAnimation { From = new Vector2(bounds.Center.X, 100), To = new Vector2(bounds.Center.X, bounds.Bottom - 100), Duration = TimeSpan.FromSeconds(2), EasingFunction = new CubicEase { Mode = EasingMode.EaseInOut }, }; _verticalAnimation = new AnimationClip<Vector2>(fromToAnimation) { LoopBehavior = LoopBehavior.Oscillate, Duration = TimeSpan.MaxValue, }; // Start the horizontal movement. AnimationService.StartAnimation() returns an // AnimationController. We keep this AnimationController because it is needed to fade-out // the animation. _state = 1; _currentAnimationController = AnimationService.StartAnimation(_horizontalAnimation, _animatedPosition); _currentAnimationController.UpdateAndApply(); // When the animation is stopped, all intermediate animation objects should be recycled. _currentAnimationController.AutoRecycle(); }
private void OnClosing(object sender, CancelEventArgs eventArgs) { if (!_closing && ClosingAnimation != null) { // Start the closing animation. _transitionOutController = _animationService.StartAnimation(ClosingAnimation, this); // Remember that we are closing. (The ClosingAnimation is playing.) _closing = true; // Cancel the close operation. We want to keep this window opened until the closing // animation is finished. eventArgs.Cancel = true; } }
public AdditiveAnimationSample(Microsoft.Xna.Framework.Game game) : base(game) { Rectangle bounds = GraphicsService.GraphicsDevice.Viewport.TitleSafeArea; // ----- Create and start the base animation. Vector2FromToByAnimation leftRightAnimation = new Vector2FromToByAnimation { TargetProperty = "Position", From = new Vector2(bounds.Left + 100, bounds.Center.Y), To = new Vector2(bounds.Right - 100, bounds.Center.Y), Duration = TimeSpan.FromSeconds(2), EasingFunction = new HermiteEase { Mode = EasingMode.EaseInOut }, }; AnimationClip<Vector2> baseAnimation = new AnimationClip<Vector2>(leftRightAnimation) { LoopBehavior = LoopBehavior.Oscillate, Duration = TimeSpan.MaxValue, }; _baseAnimationController = AnimationService.StartAnimation(baseAnimation, _animatablePosition); _baseAnimationController.UpdateAndApply(); // ----- Create and start the additive animation. Vector2FromToByAnimation upDownAnimation = new Vector2FromToByAnimation { TargetProperty = "Position", From = new Vector2(0, 50), To = new Vector2(0, -50), Duration = TimeSpan.FromSeconds(0.5), EasingFunction = new SineEase { Mode = EasingMode.EaseInOut }, // Set IsAdditive flag. IsAdditive = true, }; AnimationClip<Vector2> additiveAnimation = new AnimationClip<Vector2>(upDownAnimation) { LoopBehavior = LoopBehavior.Oscillate, Duration = TimeSpan.MaxValue, }; // Start animation using "Compose". _additiveAnimationController = AnimationService.StartAnimation( additiveAnimation, _animatablePosition, AnimationTransitions.Compose()); _additiveAnimationController.UpdateAndApply(); }
public override void Update(GameTime gameTime) { // <Space> --> Cross-fade to 'Aim-and-Shoot' animation. if (InputService.IsPressed(Keys.Space, false)) { // Start the new animation using a Replace transition with a fade-in time. _aimAndShootAnimationController = AnimationService.StartAnimation( _aimAndShootAnimation, (IAnimatableProperty)_skeletonPose, AnimationTransitions.Replace(TimeSpan.FromSeconds(0.1))); _aimAndShootAnimationController.AutoRecycle(); } // <Up> --> Cross-fade to 'Run' animation - unless the 'Aim-and-Shoot' animation is playing // or the 'Run' animation is already playing. if (_aimAndShootAnimationController.State != AnimationState.Playing && _runAnimationController.State != AnimationState.Playing && InputService.IsDown(Keys.Up)) { _runAnimationController = AnimationService.StartAnimation( _runAnimation, (IAnimatableProperty)_skeletonPose, AnimationTransitions.Replace(TimeSpan.FromSeconds(0.2))); _runAnimationController.AutoRecycle(); } if (_aimAndShootAnimationController.State != AnimationState.Playing) { // If none of the animations are playing, or if the user releases the <Up> key, // then restart the 'Idle' animation. if (_runAnimationController.State != AnimationState.Playing && _idleAnimationController.State != AnimationState.Playing || _runAnimationController.State == AnimationState.Playing && InputService.IsUp(Keys.Up)) { _idleAnimationController = AnimationService.StartAnimation( _idleAnimation, (IAnimatableProperty)_skeletonPose, AnimationTransitions.Replace(TimeSpan.FromSeconds(0.2))); _idleAnimationController.AutoRecycle(); } } base.Update(gameTime); }
public DudeWalkingSample(Microsoft.Xna.Framework.Game game) : base(game) { var modelNode = ContentManager.Load<ModelNode>("Dude/Dude"); var meshNode = modelNode.GetSubtree().OfType<MeshNode>().First().Clone(); meshNode.PoseLocal = new Pose(new Vector3F(0, 0, 0), Matrix33F.CreateRotationY(ConstantsF.Pi)); SampleHelper.EnablePerPixelLighting(meshNode); GraphicsScreen.Scene.Children.Add(meshNode); // The imported animations are stored in the mesh. Dictionary<string, SkeletonKeyFrameAnimation> animations = meshNode.Mesh.Animations; // The Dude model contains only one animation, which is a SkeletonKeyFrameAnimation with // a walk cycle. SkeletonKeyFrameAnimation walkAnimation = animations.Values.First(); // Wrap the walk animation in an animation clip that loops the animation forever. AnimationClip<SkeletonPose> loopingAnimation = new AnimationClip<SkeletonPose>(walkAnimation) { LoopBehavior = LoopBehavior.Cycle, Duration = TimeSpan.MaxValue, }; // Start the animation and keep the created AnimationController. // We must cast the SkeletonPose to IAnimatableProperty because SkeletonPose implements // IAnimatableObject and IAnimatableProperty. We must tell the AnimationService if we want // to animate an animatable property of the SkeletonPose (IAnimatableObject), or if we want to // animate the whole SkeletonPose (IAnimatableProperty). _animationController = AnimationService.StartAnimation(loopingAnimation, (IAnimatableProperty)meshNode.SkeletonPose); // The animation will be applied the next time AnimationManager.ApplyAnimations() is called // in the main loop. ApplyAnimations() is called before this method is called, therefore // the model will be rendered in the bind pose in this frame and in the first animation key // frame in the next frame - this creates an annoying visual popping effect. // We can avoid this if we call AnimationController.UpdateAndApply(). This will immediately // change the model pose to the first key frame pose. _animationController.UpdateAndApply(); // (Optional) Enable Auto-Recycling: // After the animation is stopped, the animation service will recycle all // intermediate data structures. _animationController.AutoRecycle(); }
public CharacterCrossFadeSample(Microsoft.Xna.Framework.Game game) : base(game) { var modelNode = ContentManager.Load<ModelNode>("Marine/PlayerMarine"); _meshNode = modelNode.GetSubtree().OfType<MeshNode>().First().Clone(); SampleHelper.EnablePerPixelLighting(_meshNode); GraphicsScreen.Scene.Children.Add(_meshNode); Dictionary<string, SkeletonKeyFrameAnimation> animations = _meshNode.Mesh.Animations; // Create a looping 'Idle' animation. _idleAnimation = new AnimationClip<SkeletonPose>(animations["Idle"]) { LoopBehavior = LoopBehavior.Cycle, Duration = TimeSpan.MaxValue, }; // Create a looping 'Run' animation. _runAnimation = new AnimationClip<SkeletonPose>(animations["Run"]) { LoopBehavior = LoopBehavior.Cycle, Duration = TimeSpan.MaxValue, }; // Combine the 'Aim' and 'Shoot' animation. The 'Aim' animation should start immediately. // The 'Shoot' animation should start after 0.3 seconds. // (Animations can be combined by creating timeline groups. All timelines/animations // in a timeline group are played simultaneously. AnimationClips can be used to // arrange animations on a timeline. The property Delay, for example, can be used to // set the begin time.) _aimAndShootAnimation = new TimelineGroup(); _aimAndShootAnimation.Add(animations["Aim"]); _aimAndShootAnimation.Add(new AnimationClip<SkeletonPose>(animations["Shoot"]) { Delay = TimeSpan.FromSeconds(0.3) }); // Start 'Idle' animation. We use a Replace transition with a fade-in. _idleAnimationController = AnimationService.StartAnimation( _idleAnimation, (IAnimatableProperty)_meshNode.SkeletonPose, AnimationTransitions.Replace(TimeSpan.FromSeconds(0.5))); _idleAnimationController.AutoRecycle(); }
public override void Update(GameTime gameTime) { if (InputService.IsDown(Keys.Up)) { if (!_isRunning) { _isRunning = true; // Start 'Run' animation. We use a Replace transition and replace the 'Idle' // animation which is the first in the animation composition chain. Since we only // replace one specific animation, the 'Shoot' animation will stay in the composition // chain and keep playing. _runAnimationController = AnimationService.StartAnimation( _runAnimation, (IAnimatableProperty)_skeletonPose, AnimationTransitions.Replace(_idleAnimationController.AnimationInstance, TimeSpan.FromSeconds(0.3))); _runAnimationController.AutoRecycle(); } } else { if (_isRunning) { _isRunning = false; // Start 'Idle' animation and replace the 'Run' animation. _idleAnimationController = AnimationService.StartAnimation( _idleAnimation, (IAnimatableProperty)_skeletonPose, AnimationTransitions.Replace(_runAnimationController.AnimationInstance, TimeSpan.FromSeconds(0.3))); _idleAnimationController.AutoRecycle(); } } base.Update(gameTime); }
// OnLoad() is called when the GameObject is added to the IGameObjectService. protected override void OnLoad() { var contentManager = _services.GetInstance<ContentManager>(); _modelNode = contentManager.Load<ModelNode>(_assetName).Clone(); _modelNode.PoseWorld = _defaultPose; SampleHelper.EnablePerPixelLighting(_modelNode); var scene = _services.GetInstance<IScene>(); scene.Children.Add(_modelNode); // Create looping animation. var meshNode = (MeshNode)_modelNode.Children[0]; // The dude model has a single mesh node as its child. var animations = meshNode.Mesh.Animations; var animationClip = new AnimationClip<SkeletonPose>(animations.Values.First()) { LoopBehavior = LoopBehavior.Cycle, // Repeat animation... Duration = TimeSpan.MaxValue, // ...forever. }; // Start animation. var animationService = _services.GetInstance<IAnimationService>(); AnimationController = animationService.StartAnimation(animationClip, (IAnimatableProperty)meshNode.SkeletonPose); AnimationController.UpdateAndApply(); }
protected override void LoadContent() { _model = Game.Content.Load<Model>("PlayerMarine"); var additionalData = (Dictionary<string, object>)_model.Tag; var skeleton = (Skeleton)additionalData["Skeleton"]; _skeletonPose = SkeletonPose.Create(skeleton); var animations = (Dictionary<string, SkeletonKeyFrameAnimation>)additionalData["Animations"]; // Create a looping 'Idle' animation. _idleAnimation = new AnimationClip<SkeletonPose>(animations["Idle"]) { LoopBehavior = LoopBehavior.Cycle, Duration = TimeSpan.MaxValue, }; // Create a looping 'Run' animation. _runAnimation = new AnimationClip<SkeletonPose>(animations["Run"]) { LoopBehavior = LoopBehavior.Cycle, Duration = TimeSpan.MaxValue, }; // Combine the 'Aim' and 'Shoot' animation. The 'Aim' animation should start immediately. // The 'Shoot' animation should start after 0.3 seconds. // (Animations can be combined by creating timeline groups. All timelines/animations // in a timeline group are played simultaneously. AnimationClips can be used to // arrange animations on a timeline. The property Delay, for example, can be used to // set the begin time.) _aimAndShootAnimation = new TimelineGroup(); _aimAndShootAnimation.Add(animations["Aim"]); _aimAndShootAnimation.Add(new AnimationClip<SkeletonPose>(animations["Shoot"]) { Delay = TimeSpan.FromSeconds(0.3) }); // Start 'Idle' animation. We use a Replace transition with a fade-in. _idleAnimationController = AnimationService.StartAnimation( _idleAnimation, (IAnimatableProperty)_skeletonPose, AnimationTransitions.Replace(TimeSpan.FromSeconds(0.5))); _idleAnimationController.AutoRecycle(); base.LoadContent(); }
private void StartDudeAnimation(ModelNode dude) { // The dude model contains a single mesh node. var meshNode = (MeshNode)dude.Children[0]; // The imported animation data (skeleton and animations) is stored with the mesh. var animations = meshNode.Mesh.Animations; // The MeshNodes of skinned models has a SkeletonPose which can be animated. // Let's start the first animation. var timeline0 = new TimelineClip(animations.Values.First()) { LoopBehavior = LoopBehavior.Cycle, // Loop animation... Duration = TimeSpan.MaxValue, // ...forever. }; _animationController = AnimationService.StartAnimation(timeline0, (IAnimatableProperty)meshNode.SkeletonPose); _animationController.UpdateAndApply(); }
// Start/stop morphing and skeletal animation. private void PlayAnimation(bool play) { if (play) { // ----- Start _morphingAnimationController = AnimationService.StartAnimation(_morphingAnimation, _sintel.MorphWeights); _skeletalAnimationController = AnimationService.StartAnimation(_skeletalAnimation, (IAnimatableProperty)_sintel.SkeletonPose); } else { // ----- Stop _morphingAnimationController.Stop(TimeSpan.FromSeconds(1)); _morphingAnimationController.AutoRecycle(); _skeletalAnimationController.Stop(TimeSpan.FromSeconds(1)); _skeletalAnimationController.AutoRecycle(); } // Disable UI controls during animation. foreach (var slider in _sliders) slider.IsEnabled = !play; _isPlaying = play; }
private void OnExitButtonClicked(object sender, EventArgs eventArgs) { // Animate all buttons within the StackPanel to opacity 0 and offset (-300, 0). var stackPanel = (StackPanel)_menuWindow.Content; _menuExitAnimationController = AnimateTo(stackPanel.Children, 0, new Vector2F(-300, 0)); // When the last animation finishes, exit the game. _menuExitAnimationController.Completed += (s, e) => { // Here, we would exit the game. //Game.Exit(); // In this project we switch to the next sample instead. SampleFramework.LoadNextSample(); }; // Disable all buttons. The user should not be able to click a button while // the fade-out animation is playing. DisableMenuItems(); }
public override void Update(GameTime gameTime) { if (_avatarPose == null) { if (_avatarRenderer.State == AvatarRendererState.Ready) { _avatarPose = new AvatarPose(_avatarRenderer); _targetPose = SkeletonPose.Create(_avatarPose.SkeletonPose.Skeleton); // Create a ragdoll for the avatar. _ragdoll = Ragdoll.CreateAvatarRagdoll(_avatarPose, Simulation); // Set the world space pose of the whole ragdoll. And copy the bone poses // of the current skeleton pose. _ragdoll.Pose = _pose; _ragdoll.UpdateBodiesFromSkeleton(_avatarPose.SkeletonPose); // To simplify collision checks, we need a simple way to determine whether // a rigid body belongs to the ragdoll. // --> Set RigidBody.UserData = _ragdoll. // (Alternatively we could also set specific names for the rigid bodies, // or we could assign the collision objects to a certain collision group.) foreach (var body in _ragdoll.Bodies) if (body != null) body.UserData = _ragdoll; // Add rigid bodies and constraints to the simulation. _ragdoll.AddToSimulation(Simulation); // Start by playing the key frame animation. SwitchMode(RagdollMode.Mode1); // The facial expression can be applied directly to the _avatarPose. _animationController0 = AnimationService.StartAnimation(_expressionAnimation, _avatarPose); // The skeletal animation is applied to the _targetPose. The _targetPose // is used to drive the ragdoll. (See end of method.) _animationController1 = AnimationService.StartAnimation(_skeletonAnimation, (IAnimatableProperty<SkeletonPose>)_targetPose); } return; } if (InputService.IsPressed(Buttons.A, false, LogicalPlayerIndex.One)) SwitchMode(RagdollMode.Mode1); else if (InputService.IsPressed(Buttons.B, false, LogicalPlayerIndex.One)) SwitchMode(RagdollMode.Mode2); else if (InputService.IsPressed(Buttons.X, false, LogicalPlayerIndex.One)) SwitchMode(RagdollMode.Mode3); else if (InputService.IsPressed(Buttons.Y, false, LogicalPlayerIndex.One)) SwitchMode(RagdollMode.Mode4); if (_mode == RagdollMode.Mode1 || _mode == RagdollMode.Mode2) { // The ragdoll plays a certain animation. Check whether the character was // hit by a ball. foreach (var contactConstraint in Simulation.ContactConstraints) { if (contactConstraint.BodyA.UserData == _ragdoll && contactConstraint.BodyB.Name.StartsWith("Ball") || contactConstraint.BodyB.UserData == _ragdoll && contactConstraint.BodyA.Name.StartsWith("Ball")) { // Switch to the "Passive Ragdoll" mode and let the character collapse. SwitchMode(RagdollMode.Mode3); // Hint: You can read contactConstraint.LinearConstraintImpulse.Length to // determine the strength of the impact. } } } switch (_mode) { case RagdollMode.Mode1: // In mode 1 we update the rigid bodies directly. _ragdoll.UpdateBodiesFromSkeleton(_targetPose); break; case RagdollMode.Mode2: // Compute how much time the simulation will advance in the next Update(). TimeSpan nextSimulationTimeStep; int numberOfSubTimeSteps; Simulation.GetNextTimeStep(gameTime.ElapsedGameTime, out nextSimulationTimeStep, out numberOfSubTimeSteps); // In mode 2 velocity motors update the rigid bodies. _ragdoll.DriveToPose(_targetPose, (float)nextSimulationTimeStep.TotalSeconds); break; case RagdollMode.Mode3: // In mode 3 we don't have to update the rigid bodies. break; case RagdollMode.Mode4: // In mode 4 constraint motors control the joints of the ragdoll. // (The second parameter is only required for velocity motors.) _ragdoll.DriveToPose(_targetPose, 0); break; } // Copy the skeleton pose. (_avatarPose stores the skeleton pose which is // being rendered.) _ragdoll.UpdateSkeletonFromBodies(_avatarPose.SkeletonPose); _debugRenderer.Clear(); _debugRenderer.DrawText("\n"); _debugRenderer.DrawText(_statusMessage); // Render rigid bodies. foreach (var body in Simulation.RigidBodies) if (!(body.Shape is EmptyShape)) // Do not draw dummy bodies which might be used by the ragdoll. _debugRenderer.DrawObject(body, Color.Black, true, false); }
public void PlayAnimation(string name) { if (CurrentAnimation == name) return; StopAnimation(); CurrentAnimation = name; // Start selected animation. var meshNode = ModelNode.GetDescendants().OfType<MeshNode>().First(); var mesh = meshNode.Mesh; var animation = mesh.Animations[name]; var loopingAnimation = new TimelineClip(animation) { Duration = TimeSpan.MaxValue, LoopBehavior = LoopBehavior.Cycle, }; _animationController = _animationService.StartAnimation(loopingAnimation, (IAnimatableProperty)meshNode.SkeletonPose); // Update view model IsPlaying flags. foreach (var animationPropertyViewModel in _animationPropertyViewModels) if (animationPropertyViewModel.Name == CurrentAnimation) animationPropertyViewModel.IsPlaying = true; }
private void ExitSubMenuScreen() { // Animate all buttons within the StackPanel to opacity 0 and offset (300, 0). var stackPanel = (StackPanel)_subMenuWindow.Content; _subMenuExitAnimationController = AnimateTo(stackPanel.Children, 0, new Vector2F(300, 0)); // When the last animation finishes, trigger the "MenuToSubMenu" transition. _subMenuExitAnimationController.Completed += (s, e) => _stateMachine.States.ActiveState.Transitions["SubMenuToMenu"].Fire(); _subMenuExitAnimationIsPlaying = true; // Disable all buttons. The user should not be able to click a button while // the fade-out animation is playing. foreach (var button in stackPanel.Children) button.IsEnabled = false; }
protected override void LoadContent() { // Load model and start a looping animation. _model = Game.Content.Load<Model>("Dude"); var additionalData = (Dictionary<string, object>)_model.Tag; var skeleton = (Skeleton)additionalData["Skeleton"]; _skeletonPose = SkeletonPose.Create(skeleton); var animations = (Dictionary<string, SkeletonKeyFrameAnimation>)additionalData["Animations"]; var walkAnimation = new AnimationClip<SkeletonPose>(animations.Values.First()) { LoopBehavior = LoopBehavior.Cycle, Duration = TimeSpan.MaxValue, }; _walkAnimationController = AnimationService.StartAnimation(walkAnimation, (IAnimatableProperty)_skeletonPose); _walkAnimationController.AutoRecycle(); // Create a BoneJiggler instance for the head bone (bone index 7). _boneJiggler = new BoneJiggler(_skeletonPose, 7, new Vector3F(1.1f, 0, 0)) { Spring = 100, Damping = 3, }; base.LoadContent(); }
// Animates the buttons to slide out to the left. public void PlayExitAnimation() { // An animation that animates the RenderTranslation of a UIControl: Vector2FFromToByAnimation animation = new Vector2FFromToByAnimation { TargetProperty = "RenderTranslation", To = new Vector2F(-400, 0), Duration = TimeSpan.FromSeconds(0.8), EasingFunction = new HermiteEase { Mode = EasingMode.EaseInOut }, }; // We apply this animation to all buttons. Each animation should be started with a // different delay. // To add a delay we wrap the animation in TimelineClips. The TimelineClips can be // grouped together in a TimelineGroup. const float delay = 0.05f; TimelineGroup timelineGroup = new TimelineGroup { new TimelineClip(animation) { Delay = TimeSpan.FromSeconds(6 * delay), TargetObject = "Button0" }, new TimelineClip(animation) { Delay = TimeSpan.FromSeconds(5 * delay), TargetObject = "Button1" }, new TimelineClip(animation) { Delay = TimeSpan.FromSeconds(4 * delay), TargetObject = "Button2" }, new TimelineClip(animation) { Delay = TimeSpan.FromSeconds(3 * delay), TargetObject = "Button3" }, new TimelineClip(animation) { Delay = TimeSpan.FromSeconds(2 * delay), TargetObject = "Button4" }, new TimelineClip(animation) { Delay = TimeSpan.FromSeconds(1 * delay), TargetObject = "Button5" }, new TimelineClip(animation) { Delay = TimeSpan.FromSeconds(0 * delay), TargetObject = "Button6" }, }; // The animation should hold the animation value after it is finished (the buttons should // not jump back onto the screen). timelineGroup.FillBehavior = FillBehavior.Hold; // Start the animation and keep the animation controller. We need it to query the // state of the animation in Update(). #if !XBOX && !WP7 _exitAnimationController = AnimationService.StartAnimation(timelineGroup, _buttonStackPanel.Children.OfType<Button>()); #else _exitAnimationController = AnimationService.StartAnimation(timelineGroup, _buttonStackPanel.Children.OfType<Button>().Cast<IAnimatableObject>()); #endif }
protected override void LoadContent() { _model = Game.Content.Load<Model>("Soldier"); var additionalData = (Dictionary<string, object>)_model.Tag; var skeleton = (Skeleton)additionalData["Skeleton"]; _skeletonPose = SkeletonPose.Create(skeleton); // Get the animations from the additional data. var animations = (Dictionary<string, SkeletonKeyFrameAnimation>)additionalData["Animations"]; // The Dude model contains only one animation, which is a SkeletonKeyFrameAnimation with // a walk cycle. SkeletonKeyFrameAnimation walkAnimation = animations.Values.First(); // Wrap the walk animation in an animation clip that loops the animation forever. AnimationClip<SkeletonPose> loopingAnimation = new AnimationClip<SkeletonPose>(walkAnimation) { LoopBehavior = LoopBehavior.Cycle, Duration = TimeSpan.MaxValue, }; // Start the animation and keep the created AnimationController. // We must cast the SkeletonPose to IAnimatableProperty because SkeletonPose implements // IAnimatableObject and IAnimatableProperty. We must tell the AnimationService if we want // to animate an animatable property of the SkeletonPose (IAnimatableObject), or if we want to // animate the whole SkeletonPose (IAnimatableProperty). _animationController = AnimationService.StartAnimation(loopingAnimation, (IAnimatableProperty)_skeletonPose); // The animation will be applied the next time AnimationManager.ApplyAnimations() is called // in the main loop. ApplyAnimations() is called before this method is called, therefore // the model will be rendered in the bind pose in this frame and in the first animation key // frame in the next frame - this creates an annoying visual popping effect. // We can avoid this if we call AnimationController.UpdateAndApply(). This will immediately // change the model pose to the first key frame pose. _animationController.UpdateAndApply(); // (Optional) Enable Auto-Recycling: // After the animation is stopped, the animation service will recycle all // intermediate data structures. _animationController.AutoRecycle(); base.LoadContent(); }
public override void Update(GameTime gameTime) { if (_avatarPose == null) { if (_avatarRenderer.State == AvatarRendererState.Ready) { _avatarPose = new AvatarPose(_avatarRenderer); // Start stand animation. _standAnimationController = AnimationService.StartAnimation(_standAnimation, _avatarPose); _standAnimationController.AutoRecycle(); } } else { // When the user presses buttons, we cross-fade to the custom animations. if (InputService.IsPressed(Buttons.A, false, LogicalPlayerIndex.One)) { _actionAnimationController = AnimationService.StartAnimation( _jumpAnimation, _avatarPose, AnimationTransitions.Replace(TimeSpan.FromSeconds(0.3))); _actionAnimationController.AutoRecycle(); } if (InputService.IsPressed(Buttons.B, false, LogicalPlayerIndex.One)) { _actionAnimationController = AnimationService.StartAnimation( _punchAnimation, _avatarPose, AnimationTransitions.Replace(TimeSpan.FromSeconds(0.3))); _actionAnimationController.AutoRecycle(); } if (InputService.IsPressed(Buttons.X, false, LogicalPlayerIndex.One)) { _actionAnimationController = AnimationService.StartAnimation( _kickAnimation, _avatarPose, AnimationTransitions.Replace(TimeSpan.FromSeconds(0.3))); _actionAnimationController.AutoRecycle(); } if (InputService.IsPressed(Buttons.Y, false, LogicalPlayerIndex.One)) { _actionAnimationController = AnimationService.StartAnimation( _faintAnimation, _avatarPose, AnimationTransitions.Replace(TimeSpan.FromSeconds(0.3))); _actionAnimationController.AutoRecycle(); } // The left trigger controls the speed of the walk cycle. float leftTrigger = Math.Abs(InputService.GetGamePadState(LogicalPlayerIndex.One).Triggers.Left); _walkAnimationController.Speed = leftTrigger * 2; if (_walkAnimationController.State != AnimationState.Playing) { // The walk cycle is not playing. // --> Start walk animation if left trigger is pressed. if (leftTrigger > 0) { _walkAnimationController = AnimationService.StartAnimation( _walkAnimation, _avatarPose, AnimationTransitions.Replace(TimeSpan.FromSeconds(0.3))); _walkAnimationController.AutoRecycle(); } } else { // The walk cycle is playing. // --> Cross-fade to stand animation if left trigger is not pressed. if (leftTrigger == 0) { _standAnimationController = AnimationService.StartAnimation( _standAnimation, _avatarPose, AnimationTransitions.Replace(TimeSpan.FromSeconds(0.3))); _standAnimationController.AutoRecycle(); } } // If none of the animations is playing, then restart the stand animation. if (_standAnimationController.State != AnimationState.Playing && _actionAnimationController.State != AnimationState.Playing && _walkAnimationController.State != AnimationState.Playing) { _standAnimationController = AnimationService.StartAnimation( _standAnimation, _avatarPose, AnimationTransitions.Replace(TimeSpan.FromSeconds(0.3))); _standAnimationController.AutoRecycle(); } } }
public void Attack(int ID) { var AnimateService = ServiceLocator.Current.GetInstance<IAnimationService>(); _animationController = AnimateService.StartAnimation(Map[ID]._animations[1], (IAnimatableProperty)Map[ID]._skeleton); _animationController.UpdateAndApply(); _animationController.AutoRecycle(); }
public override void Update(GameTime gameTime) { base.Update(gameTime); if (_avatarPose == null) { if (_avatarRenderer.State == AvatarRendererState.Ready) { _avatarPose = new AvatarPose(_avatarRenderer); _targetPose = SkeletonPose.Create(_avatarPose.SkeletonPose.Skeleton); // Create a ragdoll for the avatar. _ragdoll = Ragdoll.CreateAvatarRagdoll(_avatarPose, Simulation); // Set the world space pose of the whole ragdoll. And copy the bone poses // of the current skeleton pose. _ragdoll.Pose = _pose; _ragdoll.UpdateBodiesFromSkeleton(_avatarPose.SkeletonPose); // To simplify collision checks, we need a simple way to determine whether // a rigid body belongs to the ragdoll. // --> Set RigidBody.UserData = _ragdoll. // (Alternatively we could also set specific names for the rigid bodies, // or we could assign the collision objects to a certain collision group.) foreach (var body in _ragdoll.Bodies) if (body != null) body.UserData = _ragdoll; // Add rigid bodies and constraints to the simulation. _ragdoll.AddToSimulation(Simulation); // Start by playing the key frame animation. SwitchMode(RagdollMode.Mode1); // The facial expression can be applied directly to the _avatarPose. _animationController0 = AnimationService.StartAnimation(_expressionAnimation, _avatarPose); // The skeletal animation is applied to the _targetPose. The _targetPose // is used to drive the ragdoll. (See end of method.) _animationController1 = AnimationService.StartAnimation(_skeletonAnimation, (IAnimatableProperty<SkeletonPose>)_targetPose); } return; } if (InputService.IsPressed(Buttons.A, false, PlayerIndex.One)) SwitchMode(RagdollMode.Mode1); else if (InputService.IsPressed(Buttons.B, false, PlayerIndex.One)) SwitchMode(RagdollMode.Mode2); else if (InputService.IsPressed(Buttons.X, false, PlayerIndex.One)) SwitchMode(RagdollMode.Mode3); else if (InputService.IsPressed(Buttons.Y, false, PlayerIndex.One)) SwitchMode(RagdollMode.Mode4); if (_mode == RagdollMode.Mode1 || _mode == RagdollMode.Mode2) { // The ragdoll plays a certain animation. Check whether the character was // hit by a ball. foreach (var contactConstraint in Simulation.ContactConstraints) { if (contactConstraint.BodyA.UserData == _ragdoll && contactConstraint.BodyB.Name.StartsWith("Ball") || contactConstraint.BodyB.UserData == _ragdoll && contactConstraint.BodyA.Name.StartsWith("Ball")) { // Switch to the "Passive Ragdoll" mode and let the character collapse. SwitchMode(RagdollMode.Mode3); // Hint: You can read contactConstraint.LinearConstraintImpulse.Length to // determine the strength of the impact. } } } switch (_mode) { case RagdollMode.Mode1: // In mode 1 we update the rigid bodies directly. _ragdoll.UpdateBodiesFromSkeleton(_targetPose); break; case RagdollMode.Mode2: // In mode 2 velocity motors update the rigid bodies. _ragdoll.DriveToPose(_targetPose, gameTime.ElapsedGameTime); break; case RagdollMode.Mode3: // In mode 3 we don't have to update the rigid bodies. break; case RagdollMode.Mode4: // In mode 4 constraint motors control the joints of the ragdoll. _ragdoll.DriveToPose(_targetPose, gameTime.ElapsedGameTime); break; } // Copy the skeleton pose. (_avatarPose stores the skeleton pose which is // being rendered.) _ragdoll.UpdateSkeletonFromBodies(_avatarPose.SkeletonPose); }
protected override void LoadContent() { _model = Game.Content.Load<Model>("PlayerMarine"); var additionalData = (Dictionary<string, object>)_model.Tag; var skeleton = (Skeleton)additionalData["Skeleton"]; _skeletonPose = SkeletonPose.Create(skeleton); var animations = (Dictionary<string, SkeletonKeyFrameAnimation>)additionalData["Animations"]; _runAnimation = new AnimationClip<SkeletonPose>(animations["Run"]) { LoopBehavior = LoopBehavior.Cycle, Duration = TimeSpan.MaxValue, }; _idleAnimation = new AnimationClip<SkeletonPose>(animations["Idle"]) { LoopBehavior = LoopBehavior.Cycle, Duration = TimeSpan.MaxValue, }; // Create a 'Shoot' animation that only affects the upper body. var shootAnimation = animations["Shoot"]; // The SkeletonKeyFrameAnimations allows to set a weight for each bone channel. // For the 'Shoot' animation, we set the weight to 0 for all bones that are // not descendants of the second spine bone (bone index 2). That means, the // animation affects only the upper body bones and is disabled on the lower // body bones. for (int i = 0; i < skeleton.NumberOfBones; i++) { if (!SkeletonHelper.IsAncestorOrSelf(_skeletonPose, 2, i)) shootAnimation.SetWeight(i, 0); } var loopedShootingAnimation = new AnimationClip<SkeletonPose>(shootAnimation) { LoopBehavior = LoopBehavior.Cycle, Duration = TimeSpan.MaxValue, }; // Start 'Idle' animation. _idleAnimationController = AnimationService.StartAnimation(_idleAnimation, (IAnimatableProperty)_skeletonPose); _idleAnimationController.AutoRecycle(); // Start looping the 'Shoot' animation. We use a Compose transition. This will add the // 'Shoot' animation to the animation composition chain and keeping all other playing // animations. // The 'Idle' animation animates the whole skeleton. The 'Shoot' animation replaces // the 'Idle' animation on the bones of the upper body. AnimationService.StartAnimation( loopedShootingAnimation, (IAnimatableProperty)_skeletonPose, AnimationTransitions.Compose()) .AutoRecycle(); base.LoadContent(); }
/// <summary> /// Called every frame when "Start" state is active. /// </summary> private void OnUpdateStartScreen(object sender, StateEventArgs eventArgs) { if (_exitAnimationIsPlaying) return; bool transitionToMenu = false; // Check if the user presses A or START on any connected gamepad. for (var controller = PlayerIndex.One; controller <= PlayerIndex.Four; controller++) { if (InputService.IsDown(Buttons.A, controller) || InputService.IsDown(Buttons.Start, controller)) { // A or START was pressed. Assign this controller to the first "logical player". InputService.SetLogicalPlayer(LogicalPlayerIndex.One, controller); transitionToMenu = true; } } if (InputService.IsDown(MouseButtons.Left) || InputService.IsDown(Keys.Enter) || InputService.IsDown(Keys.Escape) || InputService.IsDown(Keys.Space)) { // The users has pressed the left mouse button or a key on the keyboard. if (!InputService.GetLogicalPlayer(LogicalPlayerIndex.One).HasValue) { // No controller has been assigned to the first "logical player". Maybe // there is no gamepad connected. // --> Just guess which controller is the primary player and continue. InputService.SetLogicalPlayer(LogicalPlayerIndex.One, PlayerIndex.One); } transitionToMenu = true; } if (transitionToMenu) { // Play a fade-out animation which changes the opacity from its current // value to 0. var fadeOutAnimation = new SingleFromToByAnimation { To = 0, // Animate the opacity from the current value to 0 Duration = TimeSpan.FromSeconds(0.5), // over a duration of 0.5 seconds. }; var opacityProperty = _startTextBlock.Properties.Get<float>(TextBlock.OpacityPropertyId).AsAnimatable(); _exitAnimationController = AnimationService.StartAnimation(fadeOutAnimation, opacityProperty); // When the fade-out animation finished trigger the transition from the "Start" // screen to the "Menu" screen. _exitAnimationController.Completed += (s, e) => _stateMachine.States.ActiveState.Transitions["StartToMenu"].Fire(); _exitAnimationIsPlaying = true; } }
public SceneSample(Microsoft.Xna.Framework.Game game) : base(game) { SampleFramework.IsMouseVisible = false; var delegateGraphicsScreen = new DelegateGraphicsScreen(GraphicsService) { RenderCallback = Render, }; GraphicsService.Screens.Insert(0, delegateGraphicsScreen); // Add a custom game object which controls the camera. _cameraObject = new CameraObject(Services); GameObjectService.Objects.Add(_cameraObject); // Create a new empty scene. _scene = new Scene(); // Add the camera node to the scene. _scene.Children.Add(_cameraObject.CameraNode); // Load a model. This model uses the DigitalRune Model Processor. Several XML // files (*.drmdl and *.drmat) in the folder of dude.fbx define the materials and other properties. // The DigitalRune Model Processor also imports the animations of the dude model. var model = ContentManager.Load<ModelNode>("Dude/Dude"); // Add two clones of the model to the scene. _model0 = model.Clone(); _model1 = model.Clone(); _scene.Children.Add(_model0); _scene.Children.Add(_model1); // The dude model contains a single mesh node. var meshNode0 = (MeshNode)_model0.Children[0]; var meshNode1 = (MeshNode)_model1.Children[0]; // The imported animation data (skeleton and animations) is stored with the mesh. var animations = meshNode0.Mesh.Animations; // The MeshNodes of skinned models has a SkeletonPose which can be animated. // Let's start the first animation. var timeline0 = new TimelineClip(animations.Values.First()) { LoopBehavior = LoopBehavior.Cycle, // Loop animation... Duration = TimeSpan.MaxValue, // ...forever. }; _animationController0 = AnimationService.StartAnimation(timeline0, (IAnimatableProperty)meshNode0.SkeletonPose); _animationController0.UpdateAndApply(); var timeline1 = new TimelineClip(animations.Values.First()) { LoopBehavior = LoopBehavior.Cycle, Duration = TimeSpan.MaxValue, // Start second animation at a different animation time to add some variety. Delay = TimeSpan.FromSeconds(-1), }; _animationController1 = AnimationService.StartAnimation(timeline1, (IAnimatableProperty)meshNode1.SkeletonPose); _animationController1.UpdateAndApply(); // Add some lights to the scene which have the same properties as the lights // of BasicEffect.EnableDefaultLighting(). InitializeDefaultXnaLights(_scene); _meshRenderer = new MeshRenderer(); var spriteFont = UIContentManager.Load<SpriteFont>("UI Themes/BlendBlue/Default"); _debugRenderer = new DebugRenderer(GraphicsService, spriteFont); }
/// <summary> /// Called when a "Sub Menu" button is clicked. /// </summary> private void OnSubMenuButtonClicked(object sender, EventArgs eventArgs) { // Animate all buttons within the StackPanel to opacity 0 and offset (-300, 0). var stackPanel = (StackPanel)_menuWindow.Content; _menuExitAnimationController = AnimateTo(stackPanel.Children, 0, new Vector2F(-300, 0)); // When the last animation finishes, trigger the "MenuToSubMenu" transition. _menuExitAnimationController.Completed += (s, e) => _stateMachine.States.ActiveState.Transitions["MenuToSubMenu"].Fire(); // Disable all buttons. The user should not be able to click a button while // the fade-out animation is playing. DisableMenuItems(); }