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 SkeletonMappingSample(Microsoft.Xna.Framework.Game game) : base(game) { // Get dude model and start animation on the dude. var modelNode = ContentManager.Load <ModelNode>("Dude/Dude"); _dudeMeshNode = modelNode.GetSubtree().OfType <MeshNode>().First().Clone(); _dudeMeshNode.PoseLocal = new Pose(new Vector3F(-0.5f, 0, 0), Matrix33F.CreateRotationY(ConstantsF.Pi)); SampleHelper.EnablePerPixelLighting(_dudeMeshNode); GraphicsScreen.Scene.Children.Add(_dudeMeshNode); var animations = _dudeMeshNode.Mesh.Animations; var loopingAnimation = new AnimationClip <SkeletonPose>(animations.Values.First()) { LoopBehavior = LoopBehavior.Cycle, Duration = TimeSpan.MaxValue, }; AnimationService.StartAnimation(loopingAnimation, (IAnimatableProperty)_dudeMeshNode.SkeletonPose); // Get marine model - do not start any animations on the marine model. modelNode = ContentManager.Load <ModelNode>("Marine/PlayerMarine"); _marineMeshNode = modelNode.GetSubtree().OfType <MeshNode>().First().Clone(); _marineMeshNode.PoseLocal = new Pose(new Vector3F(0.5f, 0, 0), Matrix33F.CreateRotationY(ConstantsF.Pi)); SampleHelper.EnablePerPixelLighting(_marineMeshNode); GraphicsScreen.Scene.Children.Add(_marineMeshNode); CreateSkeletonMapper(); }
public AttachmentSample(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); // Play a looping 'Idle' animation. var animations = _meshNode.Mesh.Animations; var idleAnimation = animations["Idle"]; var loopingAnimation = new AnimationClip <SkeletonPose>(idleAnimation) { LoopBehavior = LoopBehavior.Cycle, Duration = TimeSpan.MaxValue, }; var animationController = AnimationService.StartAnimation(loopingAnimation, (IAnimatableProperty)_meshNode.SkeletonPose); animationController.UpdateAndApply(); animationController.AutoRecycle(); // Add weapon model to the scene graph under the node of the marine mesh. _weaponModelNode = ContentManager.Load <ModelNode>("Marine/Weapon/WeaponMachineGun").Clone(); _meshNode.Children = new SceneNodeCollection(); _meshNode.Children.Add(_weaponModelNode); }
public ClosedFormIKSample(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)); SampleHelper.EnablePerPixelLighting(_meshNode); GraphicsScreen.Scene.Children.Add(_meshNode); // Create the IK solver. The ClosedFormIKSolver uses an analytic solution to compute // IK for arbitrary long bone chains. It does not support bone rotation limits. _ikSolver = new ClosedFormIKSolver { SkeletonPose = _meshNode.SkeletonPose, // The chain starts at the upper arm. RootBoneIndex = 13, // The chain ends at the hand bone. TipBoneIndex = 15, // The offset from the hand center to the hand origin. TipOffset = new Vector3F(0.1f, 0, 0), }; }
public BindPoseSample(Microsoft.Xna.Framework.Game game) : base(game) { // Load dude model node. // 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 // and the *.drmdl can be used to specify how animations should be processed in // the content pipeline. // The *.drmat files define the used effects and effect parameters. The effects // must support mesh skinning. var sharedDudeModelNode = ContentManager.Load <ModelNode>("Dude/Dude"); // Clone the dude model because objects returned by the ContentManager // are shared instances, and we do not want manipulate or animate this shared instance. var dudeModelNode = sharedDudeModelNode.Clone(); // The loaded dude model is a scene graph which consists of a ModelNode // which has a single MeshNode as its child. _dudeMeshNode = (MeshNode)dudeModelNode.Children[0]; // We could also get the MeshNode by name: _dudeMeshNode = (MeshNode)dudeModelNode.GetSceneNode("him"); // Or using a more general LINQ query: _dudeMeshNode = dudeModelNode.GetSubtree().OfType <MeshNode>().First(); // Set the world space position and orientation of the dude. _dudeMeshNode.PoseLocal = new Pose(new Vector3(-1f, 0, 0)); // The imported Mesh of the Dude has a Skeleton, which defines the bone hierarchy. var skeleton = _dudeMeshNode.Mesh.Skeleton; // The imported MeshNode has a SkeletonPose, which defines the current animation pose // (transformations of the bones). The default skeleton pose is the bind pose // where all bone transformations are set to an identity transformation (no scale, // no rotation, no translation). var skeletonPose = _dudeMeshNode.SkeletonPose; // Load the marine model: var marineModelNode = ContentManager.Load <ModelNode>("Marine/PlayerMarine").Clone(); _marineMeshNode = marineModelNode.GetSubtree().OfType <MeshNode>().First(); _marineMeshNode.PoseLocal = new Pose(new Vector3(1f, 0, 0)); // Enable per-pixel lighting. SampleHelper.EnablePerPixelLighting(_dudeMeshNode); SampleHelper.EnablePerPixelLighting(_marineMeshNode); // Add the to the scene graph, so that they are drawn by the graphics screen. // We can add the ModelNodes directly to the scene. //GraphicsScreen.Scene.Children.Add(dudeModelNode); //GraphicsScreen.Scene.Children.Add(marineModelNode); // Alternatively, we can detach the MeshNodes from their parent nodes and // add them directly to the scene graph. The parent ModelNodes basically empty // nodes, which are only used to load and group other nodes. _dudeMeshNode.Parent.Children.Remove(_dudeMeshNode); GraphicsScreen.Scene.Children.Add(_dudeMeshNode); _marineMeshNode.Parent.Children.Remove(_marineMeshNode); GraphicsScreen.Scene.Children.Add(_marineMeshNode); }
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 CollisionDetectionOnlyRagdollSample(Microsoft.Xna.Framework.Game game) : base(game) { GraphicsScreen.DrawReticle = true; SetCamera(new Vector3F(0, 1, 6), 0, 0); // Add a game object which allows to shoot balls. _ballShooterObject = new BallShooterObject(Services); GameObjectService.Objects.Add(_ballShooterObject); 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 loopingAnimation = new AnimationClip <SkeletonPose>(animations.Values.First()) { LoopBehavior = LoopBehavior.Cycle, Duration = TimeSpan.MaxValue, }; AnimationService.StartAnimation(loopingAnimation, (IAnimatableProperty)_meshNode.SkeletonPose); // Create a ragdoll for the Dude model. _ragdoll = new Ragdoll(); DudeRagdollCreator.Create(_meshNode.SkeletonPose, _ragdoll, Simulation, 0.571f); // Set the world space pose of the whole ragdoll. _ragdoll.Pose = _meshNode.PoseWorld; // And copy the bone poses of the current skeleton pose. _ragdoll.UpdateBodiesFromSkeleton(_meshNode.SkeletonPose); foreach (var body in _ragdoll.Bodies) { if (body != null) { // Set all bodies to kinematic - they should not be affected by forces. body.MotionType = MotionType.Kinematic; // Disable collision response. body.CollisionResponseEnabled = false; } } // In this sample, we do not need joints, limits or motors. _ragdoll.DisableJoints(); _ragdoll.DisableLimits(); _ragdoll.DisableMotors(); // Add ragdoll rigid bodies to the simulation. _ragdoll.AddToSimulation(Simulation); }
private void InitializeModelAndRagdoll() { // Load Dude model. var contentManager = Services.GetInstance <ContentManager>(); var dudeModelNode = contentManager.Load <ModelNode>("Dude/Dude"); _meshNode = dudeModelNode.GetSubtree().OfType <MeshNode>().First().Clone(); _meshNode.PoseLocal = new Pose(new Vector3(0, 0, 0)); SampleHelper.EnablePerPixelLighting(_meshNode); GraphicsScreen.Scene.Children.Add(_meshNode); // Create a ragdoll for the Dude model. _ragdoll = new Ragdoll(); DudeRagdollCreator.Create(_meshNode.SkeletonPose, _ragdoll, Simulation, 0.571f); // Set the world space pose of the whole ragdoll. And copy the bone poses of the // current skeleton pose. _ragdoll.Pose = _meshNode.PoseWorld; _ragdoll.UpdateBodiesFromSkeleton(_meshNode.SkeletonPose); // Disable sleeping. foreach (var body in _ragdoll.Bodies) { if (body != null) { body.CanSleep = false; //body.CollisionResponseEnabled = false; } } // The pelvis bone (index 1) is updated directly from the Kinect hip center. _ragdoll.Bodies[1].MotionType = MotionType.Kinematic; // In this sample we use a passive ragdoll where we need joints to hold the // limbs together and limits to restrict angular movement. _ragdoll.EnableJoints(); _ragdoll.EnableLimits(); // Set all motors to constraint motors that only use damping. This adds a damping // effect to all ragdoll limbs. foreach (RagdollMotor motor in _ragdoll.Motors) { if (motor != null) { motor.Mode = RagdollMotorMode.Constraint; motor.ConstraintDamping = 100; motor.ConstraintSpring = 0; } } _ragdoll.EnableMotors(); // Add rigid bodies and the constraints of the ragdoll to the simulation. _ragdoll.AddToSimulation(Simulation); }
public SkeletonManipulationSample(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.5f, 0, 0)); SampleHelper.EnablePerPixelLighting(_meshNode); GraphicsScreen.Scene.Children.Add(_meshNode); }
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(); }
private void InitializeModels() { var contentManager = Services.GetInstance <ContentManager>(); var dudeModelNode = contentManager.Load <ModelNode>("Dude/Dude"); _meshNodeA = dudeModelNode.GetSubtree().OfType <MeshNode>().First().Clone(); _meshNodeA.PoseLocal = new Pose(new Vector3F(0, 0, 0)); SampleHelper.EnablePerPixelLighting(_meshNodeA); GraphicsScreen.Scene.Children.Add(_meshNodeA); var marineModelNode = contentManager.Load <ModelNode>("Marine/PlayerMarine"); _meshNodeB = marineModelNode.GetSubtree().OfType <MeshNode>().First().Clone(); _meshNodeB.PoseLocal = new Pose(new Vector3F(0, 0, 0)); SampleHelper.EnablePerPixelLighting(_meshNodeB); GraphicsScreen.Scene.Children.Add(_meshNodeB); }
public AutoRagdollShapesSample(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 loopingAnimation = new AnimationClip <SkeletonPose>(animations.Values.First()) { LoopBehavior = LoopBehavior.Cycle, Duration = TimeSpan.MaxValue, }; var animationController = AnimationService.StartAnimation(loopingAnimation, (IAnimatableProperty)_meshNode.SkeletonPose); animationController.AutoRecycle(); animationController.UpdateAndApply(); // Create a ragdoll for the Dude model. _ragdoll = CreateRagdoll(_meshNode); // Set the world space pose of the whole ragdoll. _ragdoll.Pose = _meshNode.PoseWorld; // And copy the bone poses of the current skeleton pose. _ragdoll.UpdateBodiesFromSkeleton(_meshNode.SkeletonPose); foreach (var body in _ragdoll.Bodies) { if (body != null) { // Set all bodies to kinematic - they should not be affected by forces. body.MotionType = MotionType.Kinematic; // Disable collision response. body.CollisionResponseEnabled = false; } } // Add ragdoll rigid bodies to the simulation. _ragdoll.AddToSimulation(Simulation); }
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 StressTestSample(Microsoft.Xna.Framework.Game game) : base(game) { // Load model. var modelNode = ContentManager.Load <ModelNode>("Marine/PlayerMarine"); var meshNode = modelNode.GetSubtree().OfType <MeshNode>().First(); SampleHelper.EnablePerPixelLighting(meshNode); // Create looping animations for all imported animations. Dictionary <string, SkeletonKeyFrameAnimation> animations = meshNode.Mesh.Animations; _animations = new ITimeline[animations.Count]; int index = 0; foreach (var animation in animations.Values) { _animations[index] = new AnimationClip <SkeletonPose>(animation) { LoopBehavior = LoopBehavior.Cycle, Duration = TimeSpan.MaxValue, }; index++; } // Create a lot of clones of the mesh node and start a new animation on each instance. _meshNodes = new MeshNode[NumberOfModels]; for (int i = 0; i < NumberOfModels; i++) { var rowLength = (int)Math.Sqrt(NumberOfModels); var x = (i % rowLength) - rowLength / 2; var z = -i / rowLength; var position = new Vector3F(x, 0, z) * 1.5f; _meshNodes[i] = meshNode.Clone(); _meshNodes[i].PoseWorld = new Pose(position); GraphicsScreen.Scene.Children.Add(_meshNodes[i]); AnimationService.StartAnimation(_animations[0], (IAnimatableProperty)_meshNodes[i].SkeletonPose) .AutoRecycle(); } }
public CompressionSample(Microsoft.Xna.Framework.Game game) : base(game) { var modelNode = ContentManager.Load <ModelNode>("Dude/Dude"); SampleHelper.EnablePerPixelLighting(modelNode); _meshNodeUncompressed = modelNode.GetSubtree().OfType <MeshNode>().First().Clone(); _meshNodeUncompressed.PoseLocal = new Pose(new Vector3F(-0.5f, 0, 0), Matrix33F.CreateRotationY(ConstantsF.Pi)); GraphicsScreen.Scene.Children.Add(_meshNodeUncompressed); _meshNodeCompressed = _meshNodeUncompressed.Clone(); _meshNodeCompressed.PoseLocal = new Pose(new Vector3F(0.5f, 0, 0), Matrix33F.CreateRotationY(ConstantsF.Pi)); GraphicsScreen.Scene.Children.Add(_meshNodeCompressed); Dictionary <string, SkeletonKeyFrameAnimation> animations = _meshNodeUncompressed.Mesh.Animations; _animation = animations.Values.First(); RestartAnimations(); }
public JacobianTransposeIKSample(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)); SampleHelper.EnablePerPixelLighting(_meshNode); GraphicsScreen.Scene.Children.Add(_meshNode); // Create the IK solver. The JacobianTranspose method can solve long bone chains with // limits. It allocates heap memory as is not recommended for performance critical // console or phone games. _ikSolver = new JacobianTransposeIKSolver { SkeletonPose = _meshNode.SkeletonPose, // The chain starts at the upper arm. RootBoneIndex = 13, // The chain ends at the hand bone. TipBoneIndex = 15, // The offset from the hand center to the hand origin. TipOffset = new Vector3F(0.1f, 0, 0), // This solver uses an iterative method and will make up to 100 iterations if necessary. NumberOfIterations = 100, // This parameter must be hand-tuned. Make it too large and the solver is unstable. // Make it too low and the solver needs a crazy amount of iterations. StepSize = 1, // A method that applies bone limits. LimitBoneTransforms = LimitBoneTransform, }; }
public CcdIKSample(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)); SampleHelper.EnablePerPixelLighting(_meshNode); GraphicsScreen.Scene.Children.Add(_meshNode); // Create the IK solver. The CCD method can solve long bone chains with // limits. _ikSolver = new CcdIKSolver { SkeletonPose = _meshNode.SkeletonPose, // The chain starts at the upper arm. RootBoneIndex = 13, // The chain ends at the hand bone. TipBoneIndex = 15, // The offset from the hand center to the hand origin. TipOffset = new Vector3F(0.1f, 0, 0), // We can set a bone gain less than 1 to get a "smoother" result in most cases - // at the cost of more iterations. //BoneGain = 0.9f, // This solver uses an iterative method and will make up to 100 iterations if necessary. NumberOfIterations = 10, // A method that applies bone limits. LimitBoneTransforms = LimitBoneTransform, }; }
public TwoJointIKSample(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 Vector3(0, 0, 0)); SampleHelper.EnablePerPixelLighting(_meshNode); GraphicsScreen.Scene.Children.Add(_meshNode); // Create the IK solver. The TwoJointIkSolver is usually used for arms and legs. // it modifies two bones and supports limits for the second bone. _ikSolver = new TwoJointIKSolver { SkeletonPose = _meshNode.SkeletonPose, // The chain starts at the upper leg. RootBoneIndex = 54, // The second bone modified bone is the lower leg. HingeBoneIndex = 55, // The chain ends at the foot bone. TipBoneIndex = 56, // The direction of the hinge axis (in bone space). HingeAxis = -Vector3.UnitZ, // The hinge limits. MinHingeAngle = 0, MaxHingeAngle = ConstantsF.PiOver2, // The offset from the ankle to the bottom of the foot. TipOffset = new Vector3(0.23f, 0, 0), }; }
public LookAtIKSample(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 loopingAnimation = new AnimationClip <SkeletonPose>(animations.Values.First()) { LoopBehavior = LoopBehavior.Cycle, Duration = TimeSpan.MaxValue, }; AnimationService.StartAnimation(loopingAnimation, (IAnimatableProperty)_meshNode.SkeletonPose); // Create LookAtIKSolvers for some spine bones, the neck and the head. _spine1IK = new LookAtIKSolver { SkeletonPose = _meshNode.SkeletonPose, BoneIndex = 3, // The bone space axis that points in look direction. Forward = Vector3F.UnitY, // The bone space axis that points in up direction Up = Vector3F.UnitX, // An arbitrary rotation limit. Limit = ConstantsF.PiOver4, // We use a weight of 1 for the head, and lower weights for all other bones. Thus, most // of the looking will be done by the head bone, and the influence on the other bones is // smaller. Weight = 0.2f, // It is important to set the EyeOffsets. If we do not set EyeOffsets, the IK solver // assumes that the eyes are positioned in the origin of the bone. // Approximate EyeOffsets are sufficient. EyeOffset = new Vector3F(0.8f, 0, 0), }; _spine2IK = new LookAtIKSolver { SkeletonPose = _meshNode.SkeletonPose, BoneIndex = 4, Forward = Vector3F.UnitY, Up = Vector3F.UnitX, Limit = ConstantsF.PiOver4, Weight = 0.2f, EyeOffset = new Vector3F(0.64f, 0, 0), }; _spine3IK = new LookAtIKSolver { SkeletonPose = _meshNode.SkeletonPose, BoneIndex = 5, Forward = Vector3F.UnitY, Up = Vector3F.UnitX, Limit = ConstantsF.PiOver4, Weight = 0.3f, EyeOffset = new Vector3F(0.48f, 0, 0), }; _neckIK = new LookAtIKSolver { SkeletonPose = _meshNode.SkeletonPose, BoneIndex = 6, Forward = Vector3F.UnitY, Up = Vector3F.UnitX, Limit = ConstantsF.PiOver4, Weight = 0.4f, EyeOffset = new Vector3F(0.32f, 0, 0), }; _headIK = new LookAtIKSolver { SkeletonPose = _meshNode.SkeletonPose, BoneIndex = 7, Forward = Vector3F.UnitY, Up = Vector3F.UnitX, EyeOffset = new Vector3F(0.16f, 0.16f, 0), Weight = 1.0f, Limit = ConstantsF.PiOver4, }; }
public PassiveRagdollSample(Microsoft.Xna.Framework.Game game) : base(game) { GraphicsScreen.DrawReticle = true; // Add game objects which allow to shoot balls and grab rigid bodies. _ballShooterObject = new BallShooterObject(Services) { Speed = 10 }; GameObjectService.Objects.Add(_ballShooterObject); _grabObject = new GrabObject(Services); GameObjectService.Objects.Add(_grabObject); var modelNode = ContentManager.Load <ModelNode>("Dude/Dude"); _meshNode = modelNode.GetSubtree().OfType <MeshNode>().First().Clone(); _meshNode.PoseLocal = new Pose(new Vector3F(0, 0, 0)); SampleHelper.EnablePerPixelLighting(_meshNode); GraphicsScreen.Scene.Children.Add(_meshNode); // Create a ragdoll for the Dude model. _ragdoll = new Ragdoll(); DudeRagdollCreator.Create(_meshNode.SkeletonPose, _ragdoll, Simulation, 0.571f); // Set the world space pose of the whole ragdoll. And copy the bone poses of the // current skeleton pose. _ragdoll.Pose = _meshNode.PoseWorld; _ragdoll.UpdateBodiesFromSkeleton(_meshNode.SkeletonPose); // Uncomment to disable dynamic movement (for debugging during ragdoll creation): //foreach (var body in _ragdoll.Bodies) // if (body != null) // body.MotionType = MotionType.Kinematic; // In this sample we use a passive ragdoll where we need joints to hold the // limbs together and limits to restrict angular movement. _ragdoll.EnableJoints(); _ragdoll.EnableLimits(); // Set all motors to constraint motors that only use damping. This adds a damping // effect to all ragdoll limbs. foreach (RagdollMotor motor in _ragdoll.Motors) { if (motor != null) { motor.Mode = RagdollMotorMode.Constraint; motor.ConstraintDamping = 5; motor.ConstraintSpring = 0; } } _ragdoll.EnableMotors(); // Add rigid bodies and the constraints of the ragdoll to the simulation. _ragdoll.AddToSimulation(Simulation); // Add a rigid body. var box = new RigidBody(new BoxShape(0.4f, 0.4f, 0.4f)) { Name = "Box", Pose = new Pose(new Vector3F(0, 3, 0)), }; Simulation.RigidBodies.Add(box); }
public KinematicRagdollSample(Microsoft.Xna.Framework.Game game) : base(game) { GraphicsScreen.DrawReticle = true; // Add game objects which allow to shoot balls and grab rigid bodies. _ballShooterObject = new BallShooterObject(Services) { Speed = 10 }; GameObjectService.Objects.Add(_ballShooterObject); _grabObject = new GrabObject(Services); GameObjectService.Objects.Add(_grabObject); 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 loopingAnimation = new AnimationClip <SkeletonPose>(animations.Values.First()) { LoopBehavior = LoopBehavior.Cycle, Duration = TimeSpan.MaxValue, }; var animationController = AnimationService.StartAnimation(loopingAnimation, (IAnimatableProperty)_meshNode.SkeletonPose); animationController.UpdateAndApply(); // Create a ragdoll for the Dude model. _ragdoll = new Ragdoll(); DudeRagdollCreator.Create(_meshNode.SkeletonPose, _ragdoll, Simulation, 0.571f); // Set the world space pose of the whole ragdoll. And copy the bone poses of the // current skeleton pose. _ragdoll.Pose = _meshNode.PoseWorld; _ragdoll.UpdateBodiesFromSkeleton(_meshNode.SkeletonPose); // Set all bodies to kinematic - they should not be affected by forces. foreach (var body in _ragdoll.Bodies) { if (body != null) { body.MotionType = MotionType.Kinematic; } } // Set all motors to velocity motors. Velocity motors change RigidBody.LinearVelocity // RigidBody.AngularVelocity to move the rigid bodies. foreach (RagdollMotor motor in _ragdoll.Motors) { if (motor != null) { motor.Mode = RagdollMotorMode.Velocity; } } _ragdoll.EnableMotors(); // In this sample, we do not need joints or limits. _ragdoll.DisableJoints(); _ragdoll.DisableLimits(); // Add ragdoll rigid bodies to the simulation. _ragdoll.AddToSimulation(Simulation); // Add a rigid body. var box = new RigidBody(new BoxShape(0.4f, 0.4f, 0.4f)) { Name = "Box", Pose = new Pose(new Vector3F(0, 3, 0)), }; Simulation.RigidBodies.Add(box); }
public IKPhysicsSample(Microsoft.Xna.Framework.Game game) : base(game) { GraphicsScreen.DrawReticle = true; // Add game objects which allows to grab rigid bodies. _grabObject = new GrabObject(Services); GameObjectService.Objects.Add(_grabObject); // Add Dude model. var modelNode = ContentManager.Load <ModelNode>("Dude/Dude"); _meshNode = modelNode.GetSubtree().OfType <MeshNode>().First().Clone(); _meshNode.PoseLocal = new Pose(new Vector3F(0, 0, 0)); SampleHelper.EnablePerPixelLighting(_meshNode); GraphicsScreen.Scene.Children.Add(_meshNode); // Create a ragdoll for the Dude model. _ragdoll = new Ragdoll(); DudeRagdollCreator.Create(_meshNode.SkeletonPose, _ragdoll, Simulation, 0.571f); // Set the initial world space pose of the whole ragdoll. And copy the bone poses of the // current skeleton pose. _ragdoll.Pose = _meshNode.PoseWorld; _ragdoll.UpdateBodiesFromSkeleton(_meshNode.SkeletonPose); // Enable constraints (joints and limits, no motors) _ragdoll.EnableJoints(); _ragdoll.EnableLimits(); _ragdoll.DisableMotors(); foreach (var body in _ragdoll.Bodies) { if (body != null) { // Disable rigid body sleeping. (If we leave it enabled, the simulation might // disable slow bodies before they reach their IK goal.) body.CanSleep = false; // Disable collisions response. body.CollisionResponseEnabled = false; } } // Add rigid bodies and the constraints of the ragdoll to the simulation. _ragdoll.AddToSimulation(Simulation); // Disable all force effects (default gravity and damping). Simulation.ForceEffects.Clear(); // Create constraints which hold selected bodies at their current position // relative to the world. // To constrain the position + orientation, we use a FixedJoint. foreach (var boneName in new[] { "Pelvis" }) { var ragdollBody = _ragdoll.Bodies[_meshNode.SkeletonPose.Skeleton.GetIndex(boneName)]; var ikJoint = new FixedJoint { AnchorPoseALocal = ragdollBody.Pose, BodyA = Simulation.World, AnchorPoseBLocal = Pose.Identity, BodyB = ragdollBody, CollisionEnabled = false, MaxForce = 1000, }; _ikJoints.Add(ikJoint); Simulation.Constraints.Add(ikJoint); } // To constrain only the position, we use a BallJoint. foreach (var boneName in new[] { "L_Hand", "R_Hand", "L_Ankle1", "R_Ankle" }) { var ragdollBody = _ragdoll.Bodies[_meshNode.SkeletonPose.Skeleton.GetIndex(boneName)]; var ikJoint = new BallJoint { AnchorPositionALocal = ragdollBody.Pose.Position, BodyA = Simulation.World, AnchorPositionBLocal = Vector3F.Zero, BodyB = ragdollBody, CollisionEnabled = false, MaxForce = 1000, }; _ikJoints.Add(ikJoint); Simulation.Constraints.Add(ikJoint); } }
public ActiveRagdollSample(Microsoft.Xna.Framework.Game game) : base(game) { GraphicsScreen.DrawReticle = true; // Add game objects which allow to shoot balls and grab rigid bodies. _ballShooterObject = new BallShooterObject(Services) { Speed = 10 }; GameObjectService.Objects.Add(_ballShooterObject); _grabObject = new GrabObject(Services); GameObjectService.Objects.Add(_grabObject); var modelNode = ContentManager.Load <ModelNode>("Dude/Dude"); _meshNode = modelNode.GetSubtree().OfType <MeshNode>().First().Clone(); _meshNode.PoseLocal = new Pose(new Vector3F(0, 0, 0)); SampleHelper.EnablePerPixelLighting(_meshNode); GraphicsScreen.Scene.Children.Add(_meshNode); // Create a copy of the dude's skeleton. _targetSkeletonPose = SkeletonPose.Create(_meshNode.Mesh.Skeleton); // Animate the _targetSkeletonPose. var animations = _meshNode.Mesh.Animations; var loopingAnimation = new AnimationClip <SkeletonPose>(animations.Values.First()) { LoopBehavior = LoopBehavior.Cycle, Duration = TimeSpan.MaxValue, }; AnimationService.StartAnimation(loopingAnimation, (IAnimatableProperty)_targetSkeletonPose); // Create a ragdoll for the Dude model. _ragdoll = new Ragdoll(); DudeRagdollCreator.Create(_targetSkeletonPose, _ragdoll, Simulation, 0.571f); // Set the world space pose of the whole ragdoll. And copy the bone poses of the // current skeleton pose. _ragdoll.Pose = _meshNode.PoseWorld; _ragdoll.UpdateBodiesFromSkeleton(_targetSkeletonPose); // In this sample we use an active ragdoll. We need joints because constraint ragdoll // motors only affect the body rotations. _ragdoll.EnableJoints(); // We disable limits. If limits are enabled, the ragdoll could get unstable if // the animation tries to move a limb beyond an allowed limit. (This happens if // a pose in the animation violates one of our limits.) _ragdoll.DisableLimits(); // Set all motors to constraint motors. Constraint motors are like springs that // rotate the limbs to a target position. foreach (RagdollMotor motor in _ragdoll.Motors) { if (motor != null) { motor.Mode = RagdollMotorMode.Constraint; motor.ConstraintDamping = 10000; motor.ConstraintSpring = 100000; } } _ragdoll.EnableMotors(); // Add rigid bodies and the constraints of the ragdoll to the simulation. _ragdoll.AddToSimulation(Simulation); // Add a rigid body. var box = new RigidBody(new BoxShape(0.4f, 0.4f, 0.4f)) { Name = "Box", Pose = new Pose(new Vector3F(0, 3, 0)), }; Simulation.RigidBodies.Add(box); }
public ProjectedShadowSample2(Microsoft.Xna.Framework.Game game) : base(game) { SampleFramework.IsMouseVisible = false; var delegateGraphicsScreen = new DelegateGraphicsScreen(GraphicsService) { RenderCallback = Render, }; GraphicsService.Screens.Insert(0, delegateGraphicsScreen); // The dude model uses a new ProjectedShadowSkinned.fx effect. This effect contains new // parameters 'ShadowMatrix' and 'ShadowColor' which are not yet supported. When an mesh is // loaded via the content manager, effect bindings are automatically created. This is done // by effect interpreters and effect binders. The graphics service uses several predefined // effect interpreter and binder classes to support the most common effect parameters. E.g. // the SceneEffectInterpreter and SceneEffectBinder handle parameters like 'World', 'View', // 'ViewProjection', 'CameraPosition', 'FogColor', etc. (see also class // SceneEffectParameterSemantics). // We can add new effect interpreters/binders or we can add an entry to an existing // interpreter/binder. Let's add entries to the standard SceneEffectInterpreter which creates // meta-data for the new parameters: var sceneEffectInterpreter = GraphicsService.EffectInterpreters.OfType <SceneEffectInterpreter>().First(); sceneEffectInterpreter.ParameterDescriptions.Add( "ShadowMatrix", (parameter, index) => new EffectParameterDescription(parameter, "ShadowMatrix", index, EffectParameterHint.Global)); sceneEffectInterpreter.ParameterDescriptions.Add( "ShadowColor", (parameter, index) => new EffectParameterDescription(parameter, "ShadowColor", index, EffectParameterHint.Global)); // Add entries to the standard SceneEffectBinder which create DelegateParameterBindings for // the new parameters. The delegate bindings use callback methods to compute the parameter // value. var sceneEffectBinder = GraphicsService.EffectBinders.OfType <SceneEffectBinder>().First(); sceneEffectBinder.MatrixBindings.Add( "ShadowMatrix", (effect, parameter, data) => new DelegateParameterBinding <Matrix>(effect, parameter, GetShadowMatrix)); sceneEffectBinder.Vector4Bindings.Add( "ShadowColor", (effect, parameter, data) => new DelegateParameterBinding <Vector4>(effect, parameter, GetShadowColor)); // Create a new empty scene. _scene = new Scene(); Services.Register(typeof(IScene), null, _scene); // Add a custom game object which controls the camera. _cameraObject = new CameraObject(Services); _cameraObject.ResetPose(new Vector3(-2, 2, 2), -ConstantsF.PiOver4, -0.4f); GameObjectService.Objects.Add(_cameraObject); // Add a default light setup (ambient light + 3 directional lights). var defaultLightsObject = new DefaultLightsObject(Services); GameObjectService.Objects.Add(defaultLightsObject); // Get the main directional light. _mainDirectionalLightNode = ((LightNode)_scene.GetSceneNode("KeyLight")); // Add a ground plane model to the scene graph. var grid = ContentManager.Load <ModelNode>("Ground/Ground").Clone(); grid.ScaleLocal = new Vector3(0.3f); _scene.Children.Add(grid); // Add a dude model to the scene graph. var dude = ContentManager.Load <ModelNode>("DudeWithProjectedShadow/Dude").Clone(); dude.PoseWorld = new Pose(Matrix.CreateRotationY(ConstantsF.Pi)); SampleHelper.EnablePerPixelLighting(dude); _scene.Children.Add(dude); // Start walk animation. StartDudeAnimation(dude); // Create the renderers. _meshRenderer = new MeshRenderer(); _shadowColor = new Vector4(0, 0, 0, 0.4f); }