예제 #1
0
        /// <summary>
        /// Adds an AngularLimit between the specified bones.
        /// </summary>
        /// <param name="skeletonPose">The skeleton pose.</param>
        /// <param name="ragdoll">The ragdoll.</param>
        /// <param name="parent">The parent bone.</param>
        /// <param name="child">The child bone.</param>
        /// <param name="minimum">The minimum limits for each constraint axis (x/y/z).</param>
        /// <param name="maximum">The maximum limits for each constraint axis (x/y/z).</param>
        /// <remarks>
        /// The constraint anchor orientation is the orientation of the child bone.
        /// </remarks>
        private static void AddAngularLimit(SkeletonPose skeletonPose, Ragdoll ragdoll, int parent, int child, Vector3F minimum, Vector3F maximum)
        {
            var skeleton     = skeletonPose.Skeleton;
            var childBody    = ragdoll.Bodies[child];
            var childOffset  = ragdoll.BodyOffsets[child];
            var parentBody   = ragdoll.Bodies[parent];
            var parentOffset = ragdoll.BodyOffsets[parent];

            var parentBindPoseAbsolute = (Pose)skeleton.GetBindPoseAbsoluteInverse(parent).Inverse;
            var childBindPoseAbsolute  = (Pose)skeleton.GetBindPoseAbsoluteInverse(child).Inverse;
            var bindPoseRelative       = parentBindPoseAbsolute.Inverse * childBindPoseAbsolute;

            var limit = new AngularLimit
            {
                BodyA = parentBody,
                BodyB = childBody,
                AnchorOrientationALocal = parentOffset.Orientation.Transposed * bindPoseRelative.Orientation,
                AnchorOrientationBLocal = childOffset.Orientation.Transposed,
                Minimum        = minimum,
                Maximum        = maximum,
                ErrorReduction = new Vector3F(0.2f),
                Softness       = new Vector3F(0.001f)
            };

            ragdoll.Limits.Add(limit);
        }
예제 #2
0
        public override void Update(GameTime gameTime)
        {
            _debugRenderer.Clear();

            if (_avatarPose == null)
            {
                // Must wait till renderer is ready. Before that we do not get skeleton info.
                if (_avatarRenderer.State == AvatarRendererState.Ready)
                {
                    // Create AvatarPose.
                    _avatarPose = new AvatarPose(_avatarRenderer);

                    // A 'bone transform' is the transformation of a bone relative to its bind pose.
                    // Bone transforms define the pose of a skeleton.

                    // Rotate arm of avatar.
                    SkeletonPose skeletonPose  = _avatarPose.SkeletonPose;
                    int          shoulderIndex = skeletonPose.Skeleton.GetIndex("ShoulderLeft");
                    skeletonPose.SetBoneTransform(shoulderIndex, new SrtTransform(QuaternionF.CreateRotationZ(-0.9f)));

                    // The class SkeletonHelper provides some useful extension methods.
                    // One is SetBoneRotationAbsolute() which sets the orientation of a bone relative
                    // to model space.
                    // Rotate elbow to make the lower arm point forward.
                    int elbowIndex = skeletonPose.Skeleton.GetIndex("ElbowLeft");
                    SkeletonHelper.SetBoneRotationAbsolute(skeletonPose, elbowIndex, QuaternionF.CreateRotationY(ConstantsF.PiOver2));

                    // Draw avatar skeleton for debugging.
                    _debugRenderer.DrawSkeleton(skeletonPose, _pose, Vector3F.One, 0.02f, Color.Orange, true);
                }
            }
        }
예제 #3
0
        // Update the skeleton pose using the data from Kinect.
        private void UpdateKinectSkeletonPose(Body body, SkeletonPose skeletonPose)
        {
            if (body == null || !body.IsTracked)
            {
                return;
            }

            for (int i = 0; i < skeletonPose.Skeleton.NumberOfBones; i++)
            {
                var joint = Bones[i].JointType;
                if (body.Joints[joint].TrackingState != TrackingState.NotTracked)
                {
                    // The joint position in "Kinect space".
                    var kinectPosition = body.Joints[joint].Position;

                    // Convert Kinect joint position to a Vector3.
                    // z is negated because in XNA the camera forward vectors is -z, but the Kinect
                    // forward vector is +z.
                    Vector3 position = new Vector3(kinectPosition.X, kinectPosition.Y, -kinectPosition.Z);

                    // Apply scale and offset.
                    position = position * Scale + Offset;

                    var orientation = Quaternion.Identity; // TODO: Use orientations of body.JointOrientations.

                    skeletonPose.SetBonePoseAbsolute(i, new SrtTransform(orientation, position));
                }
            }
        }
예제 #4
0
        /// <summary>
        /// Adds a BallJoint between the specified bones.
        /// </summary>
        /// <param name="skeletonPose">The skeleton pose.</param>
        /// <param name="ragdoll">The ragdoll.</param>
        /// <param name="parent">The parent.</param>
        /// <param name="child">The child.</param>
        private static void AddJoint(SkeletonPose skeletonPose, Ragdoll ragdoll, int parent, int child)
        {
            // Get bodies and offsets for the bones.
            var skeleton     = skeletonPose.Skeleton;
            var childBody    = ragdoll.Bodies[child];
            var childOffset  = ragdoll.BodyOffsets[child];
            var parentBody   = ragdoll.Bodies[parent];
            var parentOffset = ragdoll.BodyOffsets[parent];

            // Get bind poses of the bones in model space.
            var parentBindPoseAbsolute = (Pose)skeleton.GetBindPoseAbsoluteInverse(parent).Inverse;
            var childBindPoseAbsolute  = (Pose)skeleton.GetBindPoseAbsoluteInverse(child).Inverse;

            // The child pose relative to the parent bone.
            var bindPoseRelative = parentBindPoseAbsolute.Inverse * childBindPoseAbsolute;

            // Add BallJoint that connects the two bones. The position of the joint is the
            // origin of the child bone.
            BallJoint joint = new BallJoint
            {
                BodyA                = parentBody,
                BodyB                = childBody,
                CollisionEnabled     = false,
                AnchorPositionALocal = (parentOffset.Inverse * bindPoseRelative).Position,
                AnchorPositionBLocal = childOffset.Inverse.Position,
                ErrorReduction       = 0.2f,
                Softness             = 0.0001f,
            };

            ragdoll.Joints.Add(joint);
        }
예제 #5
0
        /// <inheritdoc/>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="value"/> or <paramref name="property"/> is <see langword="null"/>.
        /// </exception>
        /// <exception cref="ArgumentException">
        /// The value of <paramref name="property"/> must not be <see langword="null"/>.
        /// </exception>
        public void Set(ref SkeletonPose value, IAnimatableProperty <SkeletonPose> property)
        {
            if (value == null)
            {
                throw new ArgumentNullException("value");
            }
            if (property == null)
            {
                throw new ArgumentNullException("property");
            }

            var animationValue = property.AnimationValue;

            if (animationValue == null)
            {
                if (property.HasBaseValue)
                {
                    // The SkeletonPose will be recycled in Reset().
                    Create(ref value, out animationValue);
                    property.AnimationValue = animationValue;
                }
                else
                {
                    throw new ArgumentException("The value of the property must not be null. This exception usually occurs when an IAnimatableProperty<SkeletonPose> is being animated, but the value of the property is null. A SkeletonPose must be set before the property can be animated.");
                }
            }

            SkeletonHelper.Copy(value, animationValue);
        }
예제 #6
0
        /// <summary>
        /// Drives the controlled body.
        /// </summary>
        /// <param name="skeletonPose">The target skeleton pose.</param>
        /// <param name="deltaTime">The time step.</param>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="skeletonPose" /> is <see langword="null"/>.
        /// </exception>
        internal void DriveToPose(SkeletonPose skeletonPose, float deltaTime)
        {
            if (skeletonPose == null)
            {
                throw new ArgumentNullException("skeletonPose");
            }

            Debug.Assert(Ragdoll != null, "Motor must not be called when Ragdoll property is null.");
            Debug.Assert(Ragdoll.Simulation != null, "Ragdoll was not added to a simulation.");

            if (!Enabled)
            {
                return;
            }

            if (Mode == RagdollMotorMode.Velocity)
            {
                // ----- Velocity motor
                Debug.Assert(_quaternionMotor.Simulation == null, "Velocity motors should not be added to the simulation.");
                if (BoneIndex >= Ragdoll.Bodies.Count)
                {
                    return;
                }

                var body = Ragdoll.Bodies[BoneIndex];
                if (body == null)
                {
                    return;
                }

                var childOffset = (BoneIndex < Ragdoll.BodyOffsets.Count) ? Ragdoll.BodyOffsets[BoneIndex] : Pose.Identity;
                var childPose   = Ragdoll.Pose * ((Pose)skeletonPose.GetBonePoseAbsolute(BoneIndex)) * childOffset;

                // Wake the body up. It should move, even if we move it very slowly.
                body.WakeUp();

                // Set velocities.
                body.LinearVelocity  = AnimationHelper.ComputeLinearVelocity(body.Pose.Position, childPose.Position, deltaTime);
                body.AngularVelocity = AnimationHelper.ComputeAngularVelocity(body.Pose.Orientation, childPose.Orientation, deltaTime);
            }
            else
            {
                // ----- Constraint motor
                if (_quaternionMotor.Simulation == null)
                {
                    // The motor was not added to the simulation. (Invalid configuration)
                    return;
                }

                var parentOffset = (ParentIndex < Ragdoll.BodyOffsets.Count) ? Ragdoll.BodyOffsets[ParentIndex] : Pose.Identity;
                var parentPose   = Ragdoll.Pose * ((Pose)skeletonPose.GetBonePoseAbsolute(ParentIndex)) * parentOffset;

                var childOffset = (BoneIndex < Ragdoll.BodyOffsets.Count) ? Ragdoll.BodyOffsets[BoneIndex] : Pose.Identity;
                var childPose   = Ragdoll.Pose * ((Pose)skeletonPose.GetBonePoseAbsolute(BoneIndex)) * childOffset;

                // Set the relative motor target.
                var rotationMatrix = parentPose.Orientation.Transposed * childPose.Orientation;
                _quaternionMotor.TargetOrientation = Quaternion.CreateFromRotationMatrix(rotationMatrix);
            }
        }
        protected override void LoadContent()
        {
            // Get dude model and start animation on the dude.
              _dudeModel = Game.Content.Load<Model>("Dude");
              var additionalData = (Dictionary<string, object>)_dudeModel.Tag;
              var skeleton = (Skeleton)additionalData["Skeleton"];
              _dudeSkeletonPose = SkeletonPose.Create(skeleton);
              var animations = (Dictionary<string, SkeletonKeyFrameAnimation>)additionalData["Animations"];
              var loopingAnimation = new AnimationClip<SkeletonPose>(animations.Values.First())
              {
            LoopBehavior = LoopBehavior.Cycle,
            Duration = TimeSpan.MaxValue,
              };
              AnimationService.StartAnimation(loopingAnimation, (IAnimatableProperty)_dudeSkeletonPose);

              // Get marine model - do not start any animations on the marine model.
              _marineModel = Game.Content.Load<Model>("PlayerMarine");
              additionalData = (Dictionary<string, object>)_marineModel.Tag;
              skeleton = (Skeleton)additionalData["Skeleton"];
              _marineSkeletonPose = SkeletonPose.Create(skeleton);

              CreateSkeletonMapper();

              base.LoadContent();
        }
예제 #8
0
        /// <summary>
        /// Updates the poses of the bodies, so that the bodies match the bone transforms of the given
        /// skeleton pose.
        /// </summary>
        /// <param name="skeletonPose">The skeleton pose.</param>
        /// <remarks>
        /// The poses of the rigid bodies are changed instantly. The bodies will "teleport" instantly to
        /// the target positions. They will not interact correctly with other physics objects. The
        /// velocities of the rigid bodies are set to zero. The bodies will be positioned relative to
        /// the world space pose defined by <see cref="Pose"/>.
        /// </remarks>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="skeletonPose" /> is <see langword="null"/>.
        /// </exception>
        public void UpdateBodiesFromSkeleton(SkeletonPose skeletonPose) // = Teleport of bodies.
        {
            if (skeletonPose == null)
            {
                throw new ArgumentNullException("skeletonPose");
            }

            var skeleton = skeletonPose.Skeleton;

            for (int i = 0; i < Bodies.Count && i < skeleton.NumberOfBones; i++)
            {
                var body = Bodies[i];
                if (body == null)
                {
                    continue;
                }

                Pose offset   = (i < BodyOffsets.Count) ? BodyOffsets[i] : Pose.Identity;
                Pose bodyPose = Pose * ((Pose)skeletonPose.GetBonePoseAbsolute(i)) * offset;

                body.Pose            = bodyPose;
                body.LinearVelocity  = Vector3F.Zero;
                body.AngularVelocity = Vector3F.Zero;
            }
        }
예제 #9
0
        public BoneJiggler(SkeletonPose skeletonPose, int boneIndex, Vector3 offset)
        {
            if (skeletonPose == null)
            {
                throw new ArgumentNullException("skeletonPose");
            }
            if (boneIndex < 0 || boneIndex > skeletonPose.Skeleton.NumberOfBones)
            {
                throw new ArgumentOutOfRangeException("boneIndex");
            }
            if (offset.IsNumericallyZero)
            {
                throw new ArgumentException("Parameter offset must not be a zero vector.");
            }

            SkeletonPose = skeletonPose;

            BoneIndex = boneIndex;
            Offset    = offset;

            Spring  = 100f;
            Damping = 1f;

            Reset();
        }
예제 #10
0
        protected override void OnUpdate(RenderContext context)
        {
            var meshNode = context.SceneNode as MeshNode;

            if (meshNode != null)
            {
                Value = meshNode.SkeletonPose;
                if (Value != null)
                {
                    if (Value.Skeleton.NumberOfBones > Parameter.Elements.Count)
                    {
                        Value = null;

                        var message = string.Format(
                            CultureInfo.InvariantCulture,
                            "Cannot update skeleton pose effect parameter binding: " +
                            "The skeleton has {0} bones. The effect supports only {1} bones.",
                            meshNode.SkeletonPose.Skeleton.NumberOfBones,
                            Parameter.Elements.Count);
                        throw new GraphicsException(message);
                    }

                    Value.Update();
                }
            }
            else
            {
                Value = null;
            }
        }
예제 #11
0
        /// <summary>
        /// Updates the pose of a single body, so that the bodies match the bone transforms of the given
        /// bone.
        /// </summary>
        /// <param name="skeletonPose">The skeleton pose.</param>
        /// <param name="boneIndex">The index of the bone.</param>
        /// <remarks>
        /// See also <see cref="UpdateBodiesFromSkeleton(SkeletonPose)"/>.
        /// </remarks>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="skeletonPose" /> is <see langword="null"/>.
        /// </exception>
        public void UpdateBodyFromSkeleton(SkeletonPose skeletonPose, int boneIndex)
        {
            if (skeletonPose == null)
            {
                throw new ArgumentNullException("skeletonPose");
            }

            if (boneIndex < 0 || boneIndex >= Bodies.Count)
            {
                return;
            }

            var body = Bodies[boneIndex];

            if (body == null)
            {
                return;
            }

            Pose offset   = (boneIndex < BodyOffsets.Count) ? BodyOffsets[boneIndex] : Pose.Identity;
            Pose bodyPose = Pose * ((Pose)skeletonPose.GetBonePoseAbsolute(boneIndex)) * offset;

            body.Pose            = bodyPose;
            body.LinearVelocity  = Vector3F.Zero;
            body.AngularVelocity = Vector3F.Zero;
        }
예제 #12
0
        public KinectWrapper(Game game)
            : base(game)
        {
            // one sensor is currently supported
            _kinectSensor = KinectSensor.GetDefault();

            // open the reader for the body frames
            _bodyFrameReader = _kinectSensor.BodyFrameSource.OpenReader();

            // open the sensor
            _kinectSensor.Open();

            _bodyFrameReader.FrameArrived += OnKinectBodyFrameArrived;

            Offset = new Vector3(0, 0.3f, 0);
            Scale  = new Vector3(1, 1, 1);

            // Create a skeleton that defines the bone hierarchy and rest pose.
            var skeleton = new Skeleton(
                Bones.Select(b => b.ParentIndex).ToArray(),                        // Parent indices
                Bones.Select(b => b.Name).ToArray(),                               // Bone names
                Enumerable.Repeat(SrtTransform.Identity, Bones.Length).ToArray()); // Bind poses = all Identity transforms

            // Create a SkeletonPose for each player.
            SkeletonPoseA = SkeletonPose.Create(skeleton);
            SkeletonPoseB = SkeletonPose.Create(skeleton);
        }
예제 #13
0
        public ModelContainer(Model modelpass, Pose posepass, SkeletonPose skeletonpass)
        {
            _model = modelpass;
            _pose = posepass;
            _skeleton = skeletonpass;

            var additionalData = (Dictionary<string,object>)_model.Tag;
            var animations = (Dictionary<string, SkeletonKeyFrameAnimation>)additionalData["Animations"];
            int index = 0;

            _animations = new ITimeline[animations.Count];

                _animations[0] = new AnimationClip<SkeletonPose>(animations["First"])
                {
                    LoopBehavior = LoopBehavior.Cycle,
                    Duration = TimeSpan.MaxValue
                };
                index++;

                _animations[1] = new AnimationClip<SkeletonPose>(animations["Second"]);

                _animations[2] = new AnimationClip<SkeletonPose>(animations["Second"])
                {
                    LoopBehavior = LoopBehavior.Cycle,
                    Duration = TimeSpan.MaxValue
                };
        }
예제 #14
0
        /// <inheritdoc/>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="value0"/>, <paramref name="value1"/> or <paramref name="result"/> is
        /// <see langword="null"/>.
        /// </exception>
        public void Add(ref SkeletonPose value0, ref SkeletonPose value1, ref SkeletonPose result)
        {
            if (value0 == null)
            {
                throw new ArgumentNullException("value0");
            }
            if (value1 == null)
            {
                throw new ArgumentNullException("value1");
            }
            if (result == null)
            {
                throw new ArgumentNullException("result");
            }

            var boneTransforms0  = value0.BoneTransforms;
            var boneTransforms1  = value1.BoneTransforms;
            var resultTransforms = result.BoneTransforms;

            for (int i = 0; i < resultTransforms.Length; i++)
            {
                resultTransforms[i] = boneTransforms1[i] * boneTransforms0[i];
            }

            result.Invalidate();
        }
예제 #15
0
        /// <inheritdoc/>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="source"/>, <paramref name="target"/> or <paramref name="result"/> is
        /// <see langword="null"/>.
        /// </exception>
        public void Interpolate(ref SkeletonPose source, ref SkeletonPose target, float parameter, ref SkeletonPose result)
        {
            if (source == null)
            {
                throw new ArgumentNullException("source");
            }
            if (target == null)
            {
                throw new ArgumentNullException("target");
            }
            if (result == null)
            {
                throw new ArgumentNullException("result");
            }

            var sourceTransforms = source.BoneTransforms;
            var targetTransforms = target.BoneTransforms;
            var resultTransforms = result.BoneTransforms;

            for (int i = 0; i < resultTransforms.Length; i++)
            {
                SrtTransform.Interpolate(ref sourceTransforms[i], ref targetTransforms[i], parameter, ref resultTransforms[i]);
            }

            result.Invalidate();
        }
예제 #16
0
        //--------------------------------------------------------------
        /// <summary>
        /// Initializes a new instance of the <see cref="SkeletonMapper"/> class.
        /// </summary>
        /// <param name="skeletonPoseA">The first skeleton pose. Can be <see langword="null"/>.</param>
        /// <param name="skeletonPoseB">The second skeleton pose. Can be <see langword="null"/>.</param>
        public SkeletonMapper(SkeletonPose skeletonPoseA, SkeletonPose skeletonPoseB)
        {
            _skeletonPoseA = skeletonPoseA;
              _skeletonPoseB = skeletonPoseB;

              BoneMappers = new BoneMapperCollection();
              BoneMappers.CollectionChanged += OnBoneMappersChanged;
        }
예제 #17
0
 /// <inheritdoc/>
 public void Recycle(ref SkeletonPose value)
 {
     if (value != null)
     {
         value.Recycle();
         value = null;
     }
 }
        /// <inheritdoc/>
        protected override void CloneCore(EffectParameterBinding source)
        {
            // Clone EffectParameterBinding properties.
              base.CloneCore(source);

              // Clone SkeletonPoseParameterBinding properties.
              var sourceTyped = (SkeletonPoseParameterBinding)source;
              Value = sourceTyped.Value;
        }
예제 #19
0
        // Note:
        // SkeletonPose.Invalidate() needs to be called when the internal BoneTransforms
        // are changed. Invalidate() only has an effect if the SkeletonPose has a
        // SkeletonBoneAccessor. Newly created SkeletonPose do not have a SkeletonBoneAccessor.
        // --> Calling Invalidate() should not have a performance impact. Except for the
        //     Set() method. Set() is called in AnimationManager.Apply() where the animation
        //     value is copied into the actual SkeletonPose, which might use a SkeletonBoneAccessor.
        //     Set() is the only method where Invalidate() is mandatory. However, the
        //     SkeletonPoseTraits might be used outside of the animation service. Invalidate()
        //     should be called in all methods to be safe.


        /// <inheritdoc/>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="reference"/> is <see langword="null"/>.
        /// </exception>
        public void Create(ref SkeletonPose reference, out SkeletonPose value)
        {
            if (reference == null)
            {
                throw new ArgumentNullException("reference", "The reference value must not be null. This exception usually occurs when an IAnimatableProperty<SkeletonPose> is being animated, but the value of the property is null. A SkeletonPose must be set before the property can be animated.");
            }

            value = SkeletonPose.Create(reference.Skeleton);
        }
예제 #20
0
        /// <inheritdoc/>
        protected override void CloneCore(EffectParameterBinding source)
        {
            // Clone EffectParameterBinding properties.
            base.CloneCore(source);

            // Clone SkeletonPoseParameterBinding properties.
            var sourceTyped = (SkeletonPoseParameterBinding)source;

            Value = sourceTyped.Value;
        }
예제 #21
0
 public int Add(Model _model,Pose _pose,SkeletonPose _skel )
 {
     Map.Add(NumModels, new ICT309Game.Container.ModelContainer(_model, _pose, _skel));
     Models.Add(_model);
     Poses.Add(_pose);
     SkeletonPoses.Add(_skel);
     NumModels++;
        // Map[0]._model = _model;
        // Walk(NumModels-1);
     idle(NumModels - 1);
     return NumModels - 1;
 }
예제 #22
0
        /// <inheritdoc/>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="value"/> is <see langword="null"/>.
        /// </exception>
        public void BeginBlend(ref SkeletonPose value)
        {
            if (value == null)
            {
                throw new ArgumentNullException("value");
            }

            // Set bone transforms to zero.
            var transforms = value.BoneTransforms;

            Array.Clear(transforms, 0, transforms.Length);
        }
예제 #23
0
        private void InitializeSkeletonPoses()
        {
            // Create a list of the bone/joint names of a Kinect skeleton.
            int numberOfJoints = Enum.GetNames(typeof(JointType)).Length;
            var boneNames      = new string[numberOfJoints];

            for (int i = 0; i < numberOfJoints; i++)
            {
                boneNames[i] = ((JointType)i).ToString();
            }

            // Create list with one entry per bone. Each entry is the index of the parent bone.
            var boneParents = new[]
            {
                -1,
                (int)JointType.HipCenter,
                (int)JointType.Spine,
                (int)JointType.ShoulderCenter,
                (int)JointType.ShoulderCenter,
                (int)JointType.ShoulderLeft,
                (int)JointType.ElbowLeft,
                (int)JointType.WristLeft,
                (int)JointType.ShoulderCenter,
                (int)JointType.ShoulderRight,
                (int)JointType.ElbowRight,
                (int)JointType.WristRight,
                (int)JointType.HipCenter,
                (int)JointType.HipLeft,
                (int)JointType.KneeLeft,
                (int)JointType.AnkleLeft,
                (int)JointType.HipCenter,
                (int)JointType.HipRight,
                (int)JointType.KneeRight,
                (int)JointType.AnkleRight,
            };

            // Create a list of the bind pose transformations of all bones. Since we do not
            // get such information from Kinect, we position all bones in the local origin.
            var boneBindPoses = new SrtTransform[numberOfJoints];

            for (int i = 0; i < numberOfJoints; i++)
            {
                boneBindPoses[i] = SrtTransform.Identity;
            }

            // Create a skeleton that defines the bone hierarchy and rest pose.
            var skeleton = new DRSkeleton(boneParents, boneNames, boneBindPoses);

            // Create a SkeletonPose for each player.
            SkeletonPoseA = SkeletonPose.Create(skeleton);
            SkeletonPoseB = SkeletonPose.Create(skeleton);
        }
예제 #24
0
        internal PrettySkeletonPose([NotNull] SkeletonPose pose)
        {
            var transformCount = pose.m_X.Length;
            var transforms     = new RawTransform[transformCount];

            for (var i = 0; i < transformCount; i += 1)
            {
                var t = new RawTransform(pose.m_X[i]);
                transforms[i] = t;
            }

            Transforms = transforms;
        }
예제 #25
0
        // Copies the quaternions of all bones to the specified array.
        private void SkeletonPoseToArray(float[] values)
        {
            var numberOfBones = SkeletonPose.Skeleton.NumberOfBones;

            for (int i = 0; i < numberOfBones; i++)
            {
                QuaternionF quaternion = SkeletonPose.GetBoneTransform(i).Rotation;
                values[i * 4 + 0] = quaternion.W;
                values[i * 4 + 1] = quaternion.X;
                values[i * 4 + 2] = quaternion.Y;
                values[i * 4 + 3] = quaternion.Z;
            }
        }
예제 #26
0
        public void Update(float deltaTime, Matrix world)
        {
            if (deltaTime <= 0)
            {
                return;
            }

            // Reset bone transform.
            SkeletonPose.SetBoneTransform(BoneIndex, SrtTransform.Identity);

            // Get new fixed point position in world space.
            var bonePoseAbsolute   = SkeletonPose.GetBonePoseAbsolute(BoneIndex);
            var bonePoseWorld      = world * bonePoseAbsolute;
            var fixedPointPosition = bonePoseWorld.TransformPosition(Offset);

            // If we haven't set the fixed point position before, then store the position
            // and we are done.
            if (_fixedPointPosition.IsNaN)
            {
                _fixedPointPosition = fixedPointPosition;
                return;
            }

            // New position and velocity of fixed point.
            _fixedPointVelocity = (fixedPointPosition - _fixedPointPosition) / deltaTime;
            _fixedPointPosition = fixedPointPosition;

            // If the particle position was not set before, then we only store the current values.
            // The real work starts in the next frame.
            if (_particlePosition.IsNaN)
            {
                _particlePosition = _fixedPointPosition;
                _particleVelocity = _fixedPointVelocity;
                return;
            }

            // Compute the spring force between the particle and the fixed point.
            var force = Spring * (_fixedPointPosition - _particlePosition) + Damping * (_fixedPointVelocity - _particleVelocity);

            // Update velocity and position of the particle using symplectic Euler.
            _particleVelocity = _particleVelocity + force * deltaTime;
            _particlePosition = _particlePosition + _particleVelocity * deltaTime;

            // Convert particle position back to bone space.
            var particleLocal = bonePoseWorld.Inverse.TransformPosition(_particlePosition);

            // Create rotation between the fixed point vector and the particle vector.
            var boneTransform = new SrtTransform(Quaternion.CreateFromRotationMatrix(Offset, particleLocal));

            SkeletonPose.SetBoneTransform(BoneIndex, boneTransform);
        }
        /// <summary>
        /// converts SkeletonPose enum into spoken words
        /// </summary>
        /// <param name="pose"></param>
        /// <returns></returns>
        private string SkeletonPoseToSpokenString(SkeletonPose pose)
        {
            // split CamelCase into words:
            string          sPose          = pose.ToString();
            Regex           upperCaseRegex = new Regex(@"[A-Z]{1}[a-z]*");
            MatchCollection matches        = upperCaseRegex.Matches(sPose);
            List <string>   words          = new List <string>();

            foreach (Match match in matches)
            {
                words.Add(match.Value);
            }
            return(string.Join(" ", words.ToArray()));
        }
예제 #28
0
        protected override void LoadContent()
        {
            _model = Game.Content.Load<Model>("Dude");
              var additionalData = (Dictionary<string, object>)_model.Tag;

              var skeleton = (Skeleton)additionalData["Skeleton"];
              _skeletonPoseUncompressed = SkeletonPose.Create(skeleton);
              _skeletonPoseCompressed = SkeletonPose.Create(skeleton);

              var animations = (Dictionary<string, SkeletonKeyFrameAnimation>)additionalData["Animations"];
              _animation = animations.Values.First();

              RestartAnimations();

              base.LoadContent();
        }
예제 #29
0
        /// <inheritdoc/>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="value"/> is <see langword="null"/>.
        /// </exception>
        public void EndBlend(ref SkeletonPose value)
        {
            if (value == null)
            {
                throw new ArgumentNullException("value");
            }

            var transforms = value.BoneTransforms;

            for (int i = 0; i < transforms.Length; i++)
            {
                transforms[i].Rotation.Normalize();
            }

            value.Invalidate();
        }
예제 #30
0
        /// <inheritdoc/>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="value"/> or <paramref name="nextValue"/> is <see langword="null"/>.
        /// </exception>
        public void BlendNext(ref SkeletonPose value, ref SkeletonPose nextValue, float normalizedWeight)
        {
            if (value == null)
            {
                throw new ArgumentNullException("value");
            }
            if (nextValue == null)
            {
                throw new ArgumentNullException("nextValue");
            }

            var transforms     = value.BoneTransforms;
            var nextTransforms = nextValue.BoneTransforms;

            for (int i = 0; i < transforms.Length; i++)
            {
                var rotation     = transforms[i].Rotation;
                var nextRotation = nextTransforms[i].Rotation;

                // Get angle between quaternions:
                //float cosθ = Quaternion.Dot(rotation, nextRotation);
                float cosθ = rotation.W * nextRotation.W + rotation.X * nextRotation.X + rotation.Y * nextRotation.Y + rotation.Z * nextRotation.Z;

                // Invert one quaternion if we would move along the long arc of interpolation.
                if (cosθ < 0)
                {
                    // Blend with inverted quaternion!
                    rotation.W = rotation.W - normalizedWeight * nextRotation.W;
                    rotation.X = rotation.X - normalizedWeight * nextRotation.X;
                    rotation.Y = rotation.Y - normalizedWeight * nextRotation.Y;
                    rotation.Z = rotation.Z - normalizedWeight * nextRotation.Z;
                }
                else
                {
                    // Blend with normal quaternion.
                    rotation.W = rotation.W + normalizedWeight * nextRotation.W;
                    rotation.X = rotation.X + normalizedWeight * nextRotation.X;
                    rotation.Y = rotation.Y + normalizedWeight * nextRotation.Y;
                    rotation.Z = rotation.Z + normalizedWeight * nextRotation.Z;
                }

                transforms[i].Rotation     = rotation;
                transforms[i].Scale       += normalizedWeight * nextTransforms[i].Scale;
                transforms[i].Translation += normalizedWeight * nextTransforms[i].Translation;
            }
        }
예제 #31
0
        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();
        }
예제 #32
0
    public BoneJiggler(SkeletonPose skeletonPose, int boneIndex, Vector3F offset)
    {
      if (skeletonPose == null)
        throw new ArgumentNullException("skeletonPose");
      if (boneIndex < 0 || boneIndex > skeletonPose.Skeleton.NumberOfBones)
        throw new ArgumentOutOfRangeException("boneIndex");
      if (offset.IsNumericallyZero)
        throw new ArgumentException("Parameter offset must not be a zero vector.");

      SkeletonPose = skeletonPose;

      BoneIndex = boneIndex;
      Offset = offset;

      Spring = 100f;
      Damping = 1f;

      Reset();
    }
예제 #33
0
        public void DriveToPose(SkeletonPose skeletonPose, float deltaTime)
        {
            if (skeletonPose == null)
            {
                throw new ArgumentNullException("skeletonPose");
            }
            if (Simulation == null)
            {
                throw new InvalidOperationException("Ragdoll was not added to a simulation. Call AddToSimulation() before calling DriveToPose().");
            }

            foreach (var motor in Motors)
            {
                if (motor != null)
                {
                    motor.DriveToPose(skeletonPose, deltaTime);
                }
            }
        }
예제 #34
0
        private QuaternionF GetBoneOrientation(KinectSkeleton skeletonData, SkeletonPose skeletonPose, int boneIndex)
        {
            // Get first child bone. (Kinect stores the bone orientations in the child joints.)
            int childIndex = -1;

            if (skeletonPose.Skeleton.GetNumberOfChildren(boneIndex) > 0)
            {
                childIndex = skeletonPose.Skeleton.GetChild(boneIndex, 0);
            }

            if (childIndex == -1)
            {
                return(QuaternionF.Identity);
            }

            var q = skeletonData.BoneOrientations[(JointType)childIndex].AbsoluteRotation.Quaternion;

            // Convert to DigitalRune quaternion and mirror z axis.
            return(new QuaternionF(-q.W, q.X, q.Y, -q.Z));
        }
예제 #35
0
        /// <summary>
        /// Updates the bone transforms of the skeleton pose, so that the bones match the ragdoll
        /// bodies.
        /// </summary>
        /// <param name="skeletonPose">The skeleton pose that is modified.</param>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="skeletonPose" /> is <see langword="null"/>.
        /// </exception>
        public void UpdateSkeletonFromBodies(SkeletonPose skeletonPose)
        {
            if (skeletonPose == null)
            {
                throw new ArgumentNullException("skeletonPose");
            }

            var skeleton = skeletonPose.Skeleton;

            for (int i = 0; i < Bodies.Count && i < skeleton.NumberOfBones; i++)
            {
                var body = Bodies[i];
                if (body == null)
                {
                    continue;
                }

                Pose offset           = (i < BodyOffsets.Count) ? BodyOffsets[i] : Pose.Identity;
                Pose bonePoseAbsolute = Pose.Inverse * body.Pose * offset.Inverse;
                skeletonPose.SetBonePoseAbsolute(i, bonePoseAbsolute);
            }
        }
예제 #36
0
        private void UpdateKinectSkeletonPose(KinectSkeleton skeletonData, SkeletonPose skeletonPose)
        {
            if (skeletonData == null)
            {
                return;
            }

            // Update the skeleton pose using the data from Kinect.
            for (int i = 0; i < skeletonPose.Skeleton.NumberOfBones; i++)
            {
                var joint = (JointType)i;
                if (skeletonData.Joints[joint].TrackingState != JointTrackingState.NotTracked)
                {
                    // The joint position in "Kinect space".
                    SkeletonPoint kinectPosition = skeletonData.Joints[joint].Position;

                    // Convert Kinect joint position to a Vector3F.
                    // z is negated because in XNA the camera forward vectors is -z, but the Kinect
                    // forward vector is +z.
                    Vector3F position = new Vector3F(kinectPosition.X, kinectPosition.Y, -kinectPosition.Z);

                    // Apply scale and offset.
                    position = position * Scale + Offset;

                    var orientation = QuaternionF.Identity;

                    // Optional:
                    // The newer Kinect SDKs also compute bone orientations. We do not need these values
                    // because the current samples use only the joint positions to derive bone rotations.
                    //if (joint != JointType.HipCenter)   // Motion retargeting seems to work better if the hip center bone is not rotated.
                    //{
                    //  orientation = GetBoneOrientation(skeletonData, skeletonPose, i);
                    //}

                    skeletonPose.SetBonePoseAbsolute(i, new SrtTransform(orientation, position));
                }
            }
        }
예제 #37
0
        internal void OnAssetLoaded(object sender, EventArgs eventArgs)
        {
            // Create MeshNode.SkeletonPoses for all mesh.Skeletons.
            // (Skeletons can be shared and for each skeleton we create only one SkeletonPose.)
            Dictionary <Skeleton, SkeletonPose> skeletons = new Dictionary <Skeleton, SkeletonPose>();

            foreach (var meshNode in this.GetSubtree().OfType <MeshNode>())
            {
                var skeleton = meshNode.Mesh.Skeleton;
                if (skeleton != null)
                {
                    // Get existing skeleton pose or create a new one.
                    SkeletonPose skeletonPose;
                    if (!skeletons.TryGetValue(skeleton, out skeletonPose))
                    {
                        skeletonPose = SkeletonPose.Create(skeleton);
                        skeletons.Add(skeleton, skeletonPose);
                    }

                    meshNode.SkeletonPose = skeletonPose;
                }
            }
        }
예제 #38
0
        protected override void LoadContent()
        {
            _marine = Game.Content.Load<Model>("PlayerMarine");
              var additionalData = (Dictionary<string, object>)_marine.Tag;
              var skeleton = (Skeleton)additionalData["Skeleton"];
              _skeletonPose = SkeletonPose.Create(skeleton);

              // Play a looping 'Idle' animation.
              var animations = (Dictionary<string, SkeletonKeyFrameAnimation>)additionalData["Animations"];
              var idleAnimation = animations["Idle"];
              var loopingAnimation = new AnimationClip<SkeletonPose>(idleAnimation)
              {
            LoopBehavior = LoopBehavior.Cycle,
            Duration = TimeSpan.MaxValue,
              };
              var animationController = AnimationService.StartAnimation(loopingAnimation, (IAnimatableProperty)_skeletonPose);
              animationController.UpdateAndApply();
              animationController.AutoRecycle();

              _weapon = Game.Content.Load<Model>("WeaponMachineGun");

              base.LoadContent();
        }
예제 #39
0
        // Initializes the bone rotations using the quaternions of the specified array.
        private void ArrayToSkeletonPose(float[] values)
        {
            var numberOfBones = SkeletonPose.Skeleton.NumberOfBones;

            for (int i = 0; i < numberOfBones; i++)
            {
                QuaternionF quaternion = new QuaternionF(
                    values[i * 4 + 0],
                    values[i * 4 + 1],
                    values[i * 4 + 2],
                    values[i * 4 + 3]);

                // The quaternions were filtered using component-wise linear interpolation. This
                // is only an approximation which denormalizes the quaternions.
                // --> Renormalize the quaternions.
                quaternion.TryNormalize();

                // Exchange the rotation in the bone transform.
                var boneTransform = SkeletonPose.GetBoneTransform(i);
                boneTransform.Rotation = quaternion;
                SkeletonPose.SetBoneTransform(i, boneTransform);
            }
        }
예제 #40
0
        /// <summary>
        /// Adds an AngularLimit between the specified bones.
        /// </summary>
        /// <param name="skeletonPose">The skeleton pose.</param>
        /// <param name="ragdoll">The ragdoll.</param>
        /// <param name="parent">The parent bone.</param>
        /// <param name="child">The childbone .</param>
        /// <param name="minimum">The minimum limits for each constraint axis (x/y/z).</param>
        /// <param name="maximum">The maximum limits for each constraint axis (x/y/z).</param>
        /// <remarks>
        /// The constraint anchor orientation is the orientation of the child bone.
        /// </remarks>
        private static void AddAngularLimit(SkeletonPose skeletonPose, Ragdoll ragdoll, int parent, int child, Vector3F minimum, Vector3F maximum)
        {
            var skeleton = skeletonPose.Skeleton;
              var childBody = ragdoll.Bodies[child];
              var childOffset = ragdoll.BodyOffsets[child];
              var parentBody = ragdoll.Bodies[parent];
              var parentOffset = ragdoll.BodyOffsets[parent];

              var parentBindPoseAbsolute = (Pose)skeleton.GetBindPoseAbsoluteInverse(parent).Inverse;
              var childBindPoseAbsolute = (Pose)skeleton.GetBindPoseAbsoluteInverse(child).Inverse;
              var bindPoseRelative = parentBindPoseAbsolute.Inverse * childBindPoseAbsolute;

              var limit = new AngularLimit
              {
            BodyA = parentBody,
            BodyB = childBody,
            AnchorOrientationALocal = parentOffset.Orientation.Transposed * bindPoseRelative.Orientation,
            AnchorOrientationBLocal = childOffset.Orientation.Transposed,
            Minimum = minimum,
            Maximum = maximum,
            ErrorReduction = new Vector3F(0.2f),
            Softness = new Vector3F(0.001f)
              };
              ragdoll.Limits.Add(limit);
        }
예제 #41
0
        /// <summary>
        /// Initializes the ragdoll for the given skeleton pose.
        /// </summary>
        /// <param name="skeletonPose">The skeleton pose.</param>
        /// <param name="ragdoll">The ragdoll.</param>
        /// <param name="simulation">The simulation in which the ragdoll will be used.</param>
        public static void Create(SkeletonPose skeletonPose, Ragdoll ragdoll, Simulation simulation)
        {
            var skeleton = skeletonPose.Skeleton;

              const float totalMass = 80; // The total mass of the ragdoll.
              const int numberOfBodies = 17;

              // Get distance from foot to head as a measure for the size of the ragdoll.
              int head = skeleton.GetIndex("Head");
              int footLeft = skeleton.GetIndex("L_Ankle1");
              var headPosition = skeletonPose.GetBonePoseAbsolute(head).Translation;
              var footPosition = skeletonPose.GetBonePoseAbsolute(footLeft).Translation;
              var headToFootDistance = (headPosition - footPosition).Length;

              // We use the same mass properties for all bodies. This is not realistic but more stable
              // because large mass differences or thin bodies (arms!) are less stable.
              // We use the mass properties of sphere proportional to the size of the model.
              var massFrame = MassFrame.FromShapeAndMass(new SphereShape(headToFootDistance / 8), Vector3F.One, totalMass / numberOfBodies, 0.1f, 1);

              var material = new UniformMaterial();

              #region ----- Add Bodies and Body Offsets -----

              var numberOfBones = skeleton.NumberOfBones;
              ragdoll.Bodies.AddRange(Enumerable.Repeat<RigidBody>(null, numberOfBones));
              ragdoll.BodyOffsets.AddRange(Enumerable.Repeat(Pose.Identity, numberOfBones));

              var pelvis = skeleton.GetIndex("Pelvis");
              ragdoll.Bodies[pelvis] = new RigidBody(new BoxShape(0.3f, 0.4f, 0.55f), massFrame, material);
              ragdoll.BodyOffsets[pelvis] = new Pose(new Vector3F(0.0f, 0, 0));

              var backLower = skeleton.GetIndex("Spine");
              ragdoll.Bodies[backLower] = new RigidBody(new BoxShape(0.36f, 0.4f, 0.55f), massFrame, material);
              ragdoll.BodyOffsets[backLower] = new Pose(new Vector3F(0.18f, 0, 0));

              var backUpper = skeleton.GetIndex("Spine2");
              ragdoll.Bodies[backUpper] = new RigidBody(new BoxShape(0.5f, 0.4f, 0.65f), massFrame, material);
              ragdoll.BodyOffsets[backUpper] = new Pose(new Vector3F(0.25f, 0, 0));

              var neck = skeleton.GetIndex("Neck");
              ragdoll.Bodies[neck] = new RigidBody(new CapsuleShape(0.12f, 0.3f), massFrame, material);
              ragdoll.BodyOffsets[neck] = new Pose(new Vector3F(0.15f, 0, 0), QuaternionF.CreateRotationZ(ConstantsF.PiOver2));
              ragdoll.Bodies[neck].CollisionObject.Enabled = false;

              ragdoll.Bodies[head] = new RigidBody(new SphereShape(0.2f), massFrame, material);
              ragdoll.BodyOffsets[head] = new Pose(new Vector3F(0.15f, 0.02f, 0));

              var armUpperLeft = skeleton.GetIndex("L_UpperArm");
              ragdoll.Bodies[armUpperLeft] = new RigidBody(new CapsuleShape(0.12f, 0.6f), massFrame, material);
              ragdoll.BodyOffsets[armUpperLeft] = new Pose(new Vector3F(0.2f, 0, 0), QuaternionF.CreateRotationZ(ConstantsF.PiOver2));

              var armLowerLeft = skeleton.GetIndex("L_Forearm");
              ragdoll.Bodies[armLowerLeft] = new RigidBody(new CapsuleShape(0.08f, 0.5f), massFrame, material);
              ragdoll.BodyOffsets[armLowerLeft] = new Pose(new Vector3F(0.2f, 0, 0), QuaternionF.CreateRotationZ(ConstantsF.PiOver2));

              var handLeft = skeleton.GetIndex("L_Hand");
              ragdoll.Bodies[handLeft] = new RigidBody(new BoxShape(0.2f, 0.06f, 0.15f), massFrame, material);
              ragdoll.BodyOffsets[handLeft] = new Pose(new Vector3F(0.1f, 0, 0));

              var armUpperRight = skeleton.GetIndex("R_UpperArm");
              ragdoll.Bodies[armUpperRight] = new RigidBody(new CapsuleShape(0.12f, 0.6f), massFrame, material);
              ragdoll.BodyOffsets[armUpperRight] = new Pose(new Vector3F(0.2f, 0, 0), QuaternionF.CreateRotationZ(ConstantsF.PiOver2));

              var armLowerRight = skeleton.GetIndex("R_Forearm");
              ragdoll.Bodies[armLowerRight] = new RigidBody(new CapsuleShape(0.08f, 0.5f), massFrame, material);
              ragdoll.BodyOffsets[armLowerRight] = new Pose(new Vector3F(0.2f, 0, 0), QuaternionF.CreateRotationZ(ConstantsF.PiOver2));

              var handRight = skeleton.GetIndex("R_Hand");
              ragdoll.Bodies[handRight] = new RigidBody(new BoxShape(0.2f, 0.06f, 0.15f), massFrame, material);
              ragdoll.BodyOffsets[handRight] = new Pose(new Vector3F(0.1f, 0, 0));

              var legUpperLeft = skeleton.GetIndex("L_Thigh1");
              ragdoll.Bodies[legUpperLeft] = new RigidBody(new CapsuleShape(0.16f, 0.8f), massFrame, material);
              ragdoll.BodyOffsets[legUpperLeft] = new Pose(new Vector3F(0.4f, 0, 0), QuaternionF.CreateRotationZ(ConstantsF.PiOver2));

              var legLowerLeft = skeleton.GetIndex("L_Knee2");
              ragdoll.Bodies[legLowerLeft] = new RigidBody(new CapsuleShape(0.12f, 0.65f), massFrame, material);
              ragdoll.BodyOffsets[legLowerLeft] = new Pose(new Vector3F(0.32f, 0, 0), QuaternionF.CreateRotationZ(ConstantsF.PiOver2));

              //var footLeft = skeleton.GetIndex("L_Ankle1");
              ragdoll.Bodies[footLeft] = new RigidBody(new BoxShape(0.20f, 0.5f, 0.3f), massFrame, material);
              ragdoll.BodyOffsets[footLeft] = new Pose(new Vector3F(0.16f, 0.15f, 0));

              var legUpperRight = skeleton.GetIndex("R_Thigh");
              ragdoll.Bodies[legUpperRight] = new RigidBody(new CapsuleShape(0.16f, 0.8f), massFrame, material);
              ragdoll.BodyOffsets[legUpperRight] = new Pose(new Vector3F(0.4f, 0, 0), QuaternionF.CreateRotationZ(ConstantsF.PiOver2));

              var legLowerRight = skeleton.GetIndex("R_Knee");
              ragdoll.Bodies[legLowerRight] = new RigidBody(new CapsuleShape(0.12f, 0.65f), massFrame, material);
              ragdoll.BodyOffsets[legLowerRight] = new Pose(new Vector3F(0.32f, 0, 0), QuaternionF.CreateRotationZ(ConstantsF.PiOver2));

              var footRight = skeleton.GetIndex("R_Ankle");
              ragdoll.Bodies[footRight] = new RigidBody(new BoxShape(0.20f, 0.5f, 0.3f), massFrame, material);
              ragdoll.BodyOffsets[footRight] = new Pose(new Vector3F(0.16f, 0.15f, 0));
              #endregion

              #region ----- Set Collision Filters -----

              // Collisions between connected bodies will be disabled in AddJoint(). (A BallJoint
              // has a property CollisionEnabled which decides whether connected bodies can
              // collide.)
              // But we need to disable some more collision between bodies that are not directly
              // connected but still too close to each other.
              var filter = (ICollisionFilter)simulation.CollisionDomain.CollisionDetection.CollisionFilter;
              filter.Set(ragdoll.Bodies[backUpper].CollisionObject, ragdoll.Bodies[head].CollisionObject, false);
              filter.Set(ragdoll.Bodies[armUpperRight].CollisionObject, ragdoll.Bodies[backLower].CollisionObject, false);
              filter.Set(ragdoll.Bodies[armUpperLeft].CollisionObject, ragdoll.Bodies[backLower].CollisionObject, false);
              filter.Set(ragdoll.Bodies[legUpperLeft].CollisionObject, ragdoll.Bodies[legUpperRight].CollisionObject, false);
              #endregion

              #region ----- Add Joints -----

              AddJoint(skeletonPose, ragdoll, pelvis, backLower);
              AddJoint(skeletonPose, ragdoll, backLower, backUpper);
              AddJoint(skeletonPose, ragdoll, backUpper, neck);
              AddJoint(skeletonPose, ragdoll, neck, head);
              AddJoint(skeletonPose, ragdoll, backUpper, armUpperLeft);
              AddJoint(skeletonPose, ragdoll, armUpperLeft, armLowerLeft);
              AddJoint(skeletonPose, ragdoll, armLowerLeft, handLeft);
              AddJoint(skeletonPose, ragdoll, backUpper, armUpperRight);
              AddJoint(skeletonPose, ragdoll, armUpperRight, armLowerRight);
              AddJoint(skeletonPose, ragdoll, armLowerRight, handRight);
              AddJoint(skeletonPose, ragdoll, pelvis, legUpperLeft);
              AddJoint(skeletonPose, ragdoll, legUpperLeft, legLowerLeft);
              AddJoint(skeletonPose, ragdoll, legLowerLeft, footLeft);
              AddJoint(skeletonPose, ragdoll, pelvis, legUpperRight);
              AddJoint(skeletonPose, ragdoll, legUpperRight, legLowerRight);
              AddJoint(skeletonPose, ragdoll, legLowerRight, footRight);
              #endregion

              #region ----- Add Limits -----

              // Choosing limits is difficult.
              // We create hinge limits with AngularLimits in the back and in the knee.
              // For all other joints we use TwistSwingLimits with symmetric cones.

              AddAngularLimit(skeletonPose, ragdoll, pelvis, backLower, new Vector3F(0, 0, -0.3f), new Vector3F(0, 0, 0.3f));
              AddAngularLimit(skeletonPose, ragdoll, backLower, backUpper, new Vector3F(0, 0, -0.3f), new Vector3F(0, 0, 0.4f));
              AddAngularLimit(skeletonPose, ragdoll, backUpper, neck, new Vector3F(0, 0, -0.3f), new Vector3F(0, 0, 0.3f));
              AddTwistSwingLimit(ragdoll, neck, head, Matrix33F.Identity, Matrix33F.Identity, new Vector3F(-0.1f, -0.5f, -0.7f), new Vector3F(0.1f, 0.5f, 0.7f));

              var parentBindPoseAbsolute = (Pose)skeleton.GetBindPoseAbsoluteInverse(backUpper).Inverse;
              var childBindPoseAbsolute = (Pose)skeleton.GetBindPoseAbsoluteInverse(armUpperLeft).Inverse;
              var bindPoseRelative = parentBindPoseAbsolute.Inverse * childBindPoseAbsolute;
              AddTwistSwingLimit(ragdoll, backUpper, armUpperLeft, bindPoseRelative.Orientation * Matrix33F.CreateRotationY(-0.5f) * Matrix33F.CreateRotationZ(-0.5f), Matrix33F.Identity, new Vector3F(-0.7f, -1.2f, -1.2f), new Vector3F(0.7f, 1.2f, 1.2f));

              AddTwistSwingLimit(ragdoll, armUpperLeft, armLowerLeft, Matrix33F.CreateRotationZ(-1.2f), Matrix33F.Identity, new Vector3F(-0.3f, -1.2f, -1.2f), new Vector3F(0.3f, 1.2f, 1.2f));
              AddTwistSwingLimit(ragdoll, armLowerLeft, handLeft, Matrix33F.Identity, Matrix33F.CreateRotationX(+ConstantsF.PiOver2), new Vector3F(-0.3f, -0.7f, -0.7f), new Vector3F(0.3f, 0.7f, 0.7f));

              parentBindPoseAbsolute = (Pose)skeleton.GetBindPoseAbsoluteInverse(backUpper).Inverse;
              childBindPoseAbsolute = (Pose)skeleton.GetBindPoseAbsoluteInverse(armUpperRight).Inverse;
              bindPoseRelative = parentBindPoseAbsolute.Inverse * childBindPoseAbsolute;
              AddTwistSwingLimit(ragdoll, backUpper, armUpperRight, bindPoseRelative.Orientation * Matrix33F.CreateRotationY(0.5f) * Matrix33F.CreateRotationZ(-0.5f), Matrix33F.Identity, new Vector3F(-0.7f, -1.2f, -1.2f), new Vector3F(0.7f, 1.2f, 1.2f));

              AddTwistSwingLimit(ragdoll, armUpperRight, armLowerRight, Matrix33F.CreateRotationZ(-1.2f), Matrix33F.Identity, new Vector3F(-0.3f, -1.2f, -1.2f), new Vector3F(0.3f, 1.2f, 1.2f));
              AddTwistSwingLimit(ragdoll, armLowerRight, handRight, Matrix33F.Identity, Matrix33F.CreateRotationX(-ConstantsF.PiOver2), new Vector3F(-0.3f, -0.7f, -0.7f), new Vector3F(0.3f, 0.7f, 0.7f));

              parentBindPoseAbsolute = (Pose)skeleton.GetBindPoseAbsoluteInverse(pelvis).Inverse;
              childBindPoseAbsolute = (Pose)skeleton.GetBindPoseAbsoluteInverse(legUpperLeft).Inverse;
              bindPoseRelative = parentBindPoseAbsolute.Inverse * childBindPoseAbsolute;
              AddTwistSwingLimit(ragdoll, pelvis, legUpperLeft, bindPoseRelative.Orientation * Matrix33F.CreateRotationZ(1.2f), Matrix33F.Identity, new Vector3F(-0.1f, -0.7f, -1.5f), new Vector3F(+0.1f, +0.7f, +1.5f));

              AddAngularLimit(skeletonPose, ragdoll, legUpperLeft, legLowerLeft, new Vector3F(0, 0, -2.2f), new Vector3F(0, 0, 0.0f));
              AddTwistSwingLimit(ragdoll, legLowerLeft, footLeft, Matrix33F.Identity, Matrix33F.Identity, new Vector3F(-0.1f, -0.3f, -0.7f), new Vector3F(0.1f, 0.3f, 0.7f));

              parentBindPoseAbsolute = (Pose)skeleton.GetBindPoseAbsoluteInverse(pelvis).Inverse;
              childBindPoseAbsolute = (Pose)skeleton.GetBindPoseAbsoluteInverse(legUpperRight).Inverse;
              bindPoseRelative = parentBindPoseAbsolute.Inverse * childBindPoseAbsolute;
              AddTwistSwingLimit(ragdoll, pelvis, legUpperRight, bindPoseRelative.Orientation * Matrix33F.CreateRotationZ(1.2f), Matrix33F.Identity, new Vector3F(-0.1f, -0.7f, -1.5f), new Vector3F(+0.1f, +0.7f, +1.5f));

              AddAngularLimit(skeletonPose, ragdoll, legUpperRight, legLowerRight, new Vector3F(0, 0, -2.2f), new Vector3F(0, 0, 0.0f));
              AddTwistSwingLimit(ragdoll, legLowerRight, footRight, Matrix33F.Identity, Matrix33F.Identity, new Vector3F(-0.1f, -0.3f, -0.7f), new Vector3F(0.1f, 0.3f, 0.7f));
              #endregion

              #region ----- Add Motors -----

              ragdoll.Motors.AddRange(Enumerable.Repeat<RagdollMotor>(null, numberOfBones));
              ragdoll.Motors[pelvis] = new RagdollMotor(pelvis, -1);
              ragdoll.Motors[backLower] = new RagdollMotor(backLower, pelvis);
              ragdoll.Motors[backUpper] = new RagdollMotor(backUpper, backLower);
              ragdoll.Motors[neck] = new RagdollMotor(neck, backUpper);
              ragdoll.Motors[head] = new RagdollMotor(head, neck);
              ragdoll.Motors[armUpperLeft] = new RagdollMotor(armUpperLeft, backUpper);
              ragdoll.Motors[armLowerLeft] = new RagdollMotor(armLowerLeft, armUpperLeft);
              ragdoll.Motors[handLeft] = new RagdollMotor(handLeft, armLowerLeft);
              ragdoll.Motors[armUpperRight] = new RagdollMotor(armUpperRight, backUpper);
              ragdoll.Motors[armLowerRight] = new RagdollMotor(armLowerRight, armUpperRight);
              ragdoll.Motors[handRight] = new RagdollMotor(handRight, armLowerRight);
              ragdoll.Motors[legUpperLeft] = new RagdollMotor(legUpperLeft, pelvis);
              ragdoll.Motors[legLowerLeft] = new RagdollMotor(legLowerLeft, legUpperLeft);
              ragdoll.Motors[footLeft] = new RagdollMotor(footLeft, legLowerLeft);
              ragdoll.Motors[legUpperRight] = new RagdollMotor(legUpperRight, pelvis);
              ragdoll.Motors[legLowerRight] = new RagdollMotor(legLowerRight, legUpperRight);
              ragdoll.Motors[footRight] = new RagdollMotor(footRight, legLowerRight);
              #endregion
        }
예제 #42
0
        private void InitializeModels()
        {
            // Load the two different 3D human models.
              // The models use our custom SkinnedModelProcessor as the content processor!
              // This content processor stores the model's skeleton in the additional data of the model.

              _modelA = Game.Content.Load<Model>("Dude");
              var additionalData = (Dictionary<string, object>)_modelA.Tag;
              var skeleton = (Skeleton)additionalData["Skeleton"];
              _skeletonPoseA = SkeletonPose.Create(skeleton);

              _modelB = Game.Content.Load<Model>("PlayerMarine");
              additionalData = (Dictionary<string, object>)_modelB.Tag;
              skeleton = (Skeleton)additionalData["Skeleton"];
              _skeletonPoseB = SkeletonPose.Create(skeleton);
        }
예제 #43
0
        private void InitializeSkeletonPoses()
        {
            // Create a list of the bone/joint names of a Kinect skeleton.
              int numberOfJoints = Enum.GetNames(typeof(JointType)).Length;
              var boneNames = new string[numberOfJoints];
              for (int i = 0; i < numberOfJoints; i++)
            boneNames[i] = ((JointType)i).ToString();

              // Create list with one entry per bone. Each entry is the index of the parent bone.
              var boneParents = new[]
              {
            -1,
            (int)JointType.HipCenter,
            (int)JointType.Spine,
            (int)JointType.ShoulderCenter,
            (int)JointType.ShoulderCenter,
            (int)JointType.ShoulderLeft,
            (int)JointType.ElbowLeft,
            (int)JointType.WristLeft,
            (int)JointType.ShoulderCenter,
            (int)JointType.ShoulderRight,
            (int)JointType.ElbowRight,
            (int)JointType.WristRight,
            (int)JointType.HipCenter,
            (int)JointType.HipLeft,
            (int)JointType.KneeLeft,
            (int)JointType.AnkleLeft,
            (int)JointType.HipCenter,
            (int)JointType.HipRight,
            (int)JointType.KneeRight,
            (int)JointType.AnkleRight,
              };

              // Create a list of the bind pose transformations of all bones. Since we do not
              // get such information from Kinect, we position all bones in the local origin.
              var boneBindPoses = new SrtTransform[numberOfJoints];
              for (int i = 0; i < numberOfJoints; i++)
            boneBindPoses[i] = SrtTransform.Identity;

              // Create a skeleton that defines the bone hierarchy and rest pose.
              var skeleton = new DRSkeleton(boneParents, boneNames, boneBindPoses);

              // Create a SkeletonPose for each player.
              SkeletonPoseA = SkeletonPose.Create(skeleton);
              SkeletonPoseB = SkeletonPose.Create(skeleton);
        }
예제 #44
0
        private void UpdateKinectSkeletonPose(KinectSkeleton skeletonData, SkeletonPose skeletonPose)
        {
            if (skeletonData == null)
            return;

              // Update the skeleton pose using the data from Kinect.
              for (int i = 0; i < skeletonPose.Skeleton.NumberOfBones; i++)
              {
            var joint = (JointType)i;
            if (skeletonData.Joints[joint].TrackingState != JointTrackingState.NotTracked)
            {
              // The joint position in "Kinect space".
              SkeletonPoint kinectPosition = skeletonData.Joints[joint].Position;

              // Convert Kinect joint position to a Vector3F.
              // z is negated because in XNA the camera forward vectors is -z, but the Kinect
              // forward vector is +z.
              Vector3F position = new Vector3F(kinectPosition.X, kinectPosition.Y, -kinectPosition.Z);

              // Apply scale and offset.
              position = position * Scale + Offset;

              skeletonPose.SetBonePoseAbsolute(i, new SrtTransform(QuaternionF.Identity, position));
            }
              }
        }
예제 #45
0
        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();
        }
예제 #46
0
        protected override void LoadContent()
        {
            _basicEffect = new BasicEffect(GraphicsDevice);

              // Load dude model.
              _dudeModel = Game.Content.Load<Model>("Dude");

              // The SkinnedModelProcessor stores additional data in the tag.
              Dictionary<string, object> additionalData = (Dictionary<string, object>)_dudeModel.Tag;

              // Get the skeleton.
              Skeleton skeleton = (Skeleton)additionalData["Skeleton"];

              // Create a skeleton pose that can be used transform and animate the skeleton.
              _dudeSkeletonPose = SkeletonPose.Create(skeleton);

              // Repeat the above steps for the marine model:
              _marineModel = Game.Content.Load<Model>("dude");
              additionalData = (Dictionary<string, object>)_marineModel.Tag;
              skeleton = (Skeleton)additionalData["Skeleton"];
              _marineSkeletonPose = SkeletonPose.Create(skeleton);

              base.LoadContent();
        }
예제 #47
0
        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();
        }
        protected override void LoadContent()
        {
            _model = Game.Content.Load<Model>("Dude");
              var additionalData = (Dictionary<string, object>)_model.Tag;

              var skeleton = (Skeleton)additionalData["Skeleton"];
              _skeletonPose = SkeletonPose.Create(skeleton);

              base.LoadContent();
        }
        protected override void OnUpdate(RenderContext context)
        {
            var meshNode = context.SceneNode as MeshNode;
              if (meshNode != null)
              {
            Value = meshNode.SkeletonPose;
            if (Value != null)
            {
              if (Value.Skeleton.NumberOfBones > Parameter.Elements.Count)
              {
            Value = null;

            var message = string.Format(
              CultureInfo.InvariantCulture,
              "Cannot update skeleton pose effect parameter binding: " +
              "The skeleton has {0} bones. The effect supports only {1} bones.",
              meshNode.SkeletonPose.Skeleton.NumberOfBones,
              Parameter.Elements.Count);
            throw new GraphicsException(message);
              }

              Value.Update();
            }
              }
              else
              {
            Value = null;
              }
        }
예제 #50
0
        /// <summary>
        /// Copies the bone transforms from skeleton pose to another skeleton pose.
        /// </summary>
        /// <param name="source">The <see cref="SkeletonPose"/> from which the bone transforms are copied.</param>
        /// <param name="target">The <see cref="SkeletonPose"/> to which the bone transforms are copied.</param>
        /// <remarks>
        /// Copying a <see cref="SkeletonPose"/> using this method is faster than manually copying all
        /// bone transforms.
        /// </remarks>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="source"/> or <paramref name="target"/> is <see langword="null"/>.
        /// </exception>
        /// <exception cref="ArgumentException">
        /// <paramref name="source"/> and <paramref name="target"/> belong to different skeletons and
        /// <paramref name="target"/> has more bones than <paramref name="source"/>.
        /// </exception>
        public static void Copy(SkeletonPose source, SkeletonPose target)
        {
            if (source == null)
            throw new ArgumentNullException("source");
              if (target == null)
            throw new ArgumentNullException("target");

              if (target != source)
              {
            var sourceTransforms = source.BoneTransforms;
            var targetTransforms = target.BoneTransforms;
            Array.Copy(sourceTransforms, 0, targetTransforms, 0, targetTransforms.Length);
            target.Invalidate();
              }
        }
예제 #51
0
        protected void LoadModel(string filepath)
        {
            Moving = false;
            var contentManager = ServiceLocator.Current.GetInstance<ContentManager>();
            var graphicsService = ServiceLocator.Current.GetInstance<IGraphicsService>();
            var animationService = ServiceLocator.Current.GetInstance<IAnimationService>();
            var screen = ((BasicScreen)graphicsService.Screens["Default"]);

            _model = Content.Load<Model>(filepath);
            var additionalData = (Dictionary<string, object>)_model.Tag;
            var skeleton = (Skeleton)additionalData["Skeleton"];
            _skeletonPose = SkeletonPose.Create(skeleton);
               // var animations = (Dictionary<string, SkeletonKeyFrameAnimation>)additionalData["Animations"];
              //  SkeletonKeyFrameAnimation walkAnimation = animations.Values.First();

            //_model = contentManager.Load<ModelNode>(filepath).Clone();

              /*  foreach (var meshNode in _model.GetSubtree().OfType<MeshNode>())
            {
                Mesh mesh = meshNode.Mesh;
                foreach (var material in mesh.Materials)
                {
                    var effectBinding = material["Default"];
                    effectBinding.Set("DiffuseColor", _color);
                    ((BasicEffectBinding)effectBinding).LightingEnabled = false;
                }
            }*/

               ID = screen.Add(_model, _pose, _skeletonPose);

            //screen.Scene.Children.Add(_model);
        }
 /// <summary>
 /// converts SkeletonPose enum into spoken words
 /// </summary>
 /// <param name="pose"></param>
 /// <returns></returns>
 private string SkeletonPoseToSpokenString(SkeletonPose pose)
 {
     // split CamelCase into words:
     string sPose = pose.ToString();
     Regex upperCaseRegex = new Regex(@"[A-Z]{1}[a-z]*");
     MatchCollection matches = upperCaseRegex.Matches(sPose);
     List<string> words = new List<string>();
     foreach (Match match in matches)
     {
         words.Add(match.Value);
     }
     return string.Join(" ", words.ToArray());
 }
예제 #53
0
 public SkeletonPoseFilter(SkeletonPose skeletonPose)
 {
     SkeletonPose = skeletonPose;
       TimeConstant = 0.05f;
 }
예제 #54
0
    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);
    }
예제 #55
0
        protected override void LoadContent()
        {
            // Add a ground plane to the simulation.
              Simulation.RigidBodies.Add(
            new RigidBody(new PlaneShape(Vector3F.UnitY, 0))
            {
              MotionType = MotionType.Static
            });

              // Load model.
              _model = Game.Content.Load<Model>("Dude");
              var additionalData = (Dictionary<string, object>)_model.Tag;
              var skeleton = (Skeleton)additionalData["Skeleton"];

              // Create the two skeleton poses.
              _targetSkeletonPose = SkeletonPose.Create(skeleton);
              _actualSkeletonPose = SkeletonPose.Create(skeleton);

              // Animate the _targetSkeletonPose.
              var animations = (Dictionary<string, SkeletonKeyFrameAnimation>)additionalData["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);

              // Set the world space pose of the whole ragdoll. And copy the bone poses of the
              // current skeleton pose.
              _ragdoll.Pose = _pose;
              _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);

              base.LoadContent();
        }
예제 #56
0
        /// <summary>
        /// Adds a BallJoint between the specified bones.
        /// </summary>
        /// <param name="skeletonPose">The skeleton pose.</param>
        /// <param name="ragdoll">The ragdoll.</param>
        /// <param name="parent">The parent.</param>
        /// <param name="child">The child.</param>
        private static void AddJoint(SkeletonPose skeletonPose, Ragdoll ragdoll, int parent, int child)
        {
            // Get bodies and offsets for the bones.
              var skeleton = skeletonPose.Skeleton;
              var childBody = ragdoll.Bodies[child];
              var childOffset = ragdoll.BodyOffsets[child];
              var parentBody = ragdoll.Bodies[parent];
              var parentOffset = ragdoll.BodyOffsets[parent];

              // Get bind poses of the bones in model space.
              var parentBindPoseAbsolute = (Pose)skeleton.GetBindPoseAbsoluteInverse(parent).Inverse;
              var childBindPoseAbsolute = (Pose)skeleton.GetBindPoseAbsoluteInverse(child).Inverse;

              // The child pose relative to the parent bone.
              var bindPoseRelative = parentBindPoseAbsolute.Inverse * childBindPoseAbsolute;

              // Add BallJoint that connects the two bones. The position of the joint is the
              // origin of the child bone.
              BallJoint joint = new BallJoint
              {
            BodyA = parentBody,
            BodyB = childBody,
            CollisionEnabled = false,
            AnchorPositionALocal = (parentOffset.Inverse * bindPoseRelative).Position,
            AnchorPositionBLocal = childOffset.Inverse.Position,
            ErrorReduction = 0.2f,
            Softness = 0.0001f,
              };
              ragdoll.Joints.Add(joint);
        }
        protected override void LoadContent()
        {
            // Load model and start 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 loopingAnimation = new AnimationClip<SkeletonPose>(animations.Values.First())
              {
            LoopBehavior = LoopBehavior.Cycle,
            Duration = TimeSpan.MaxValue,
              };
              AnimationService.StartAnimation(loopingAnimation, (IAnimatableProperty)_skeletonPose);

              // Create a ragdoll for the Dude model.
              _ragdoll = new Ragdoll();
              DudeRagdollCreator.Create(_skeletonPose, _ragdoll, Simulation);

              // Set the world space pose of the whole ragdoll.
              _ragdoll.Pose = _pose;
              // And copy the bone poses of the current skeleton pose.
              _ragdoll.UpdateBodiesFromSkeleton(_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);

              base.LoadContent();
        }
        private void InitializeModel()
        {
            // Load dude model including the skeleton.
              _model = Game.Content.Load<Model>("Dude");
              var additionalData = (Dictionary<string, object>)_model.Tag;
              var ragdollSkeleton = (DRSkeleton)additionalData["Skeleton"];
              _skeletonPose = SkeletonPose.Create(ragdollSkeleton);

              // Create a ragdoll for the Dude model.
              _ragdoll = new Ragdoll();
              DudeRagdollCreator.Create(_skeletonPose, _ragdoll, Simulation, 0.57f);

              // Set the world space pose of the whole ragdoll. And copy the bone poses of the
              // current skeleton pose.
              _ragdoll.UpdateBodiesFromSkeleton(_skeletonPose);

              // Disable sleeping.
              foreach (var body in _ragdoll.Bodies)
              {
            if (body != null)
              body.CanSleep = 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);
        }
        /// <summary>
        /// when changed, announce pose and react to it. Left and right are mirror in robot view.
        /// </summary>
        /// <param name="skeletonPose"></param>
        private void ReactOnSkeletonPose(SkeletonPose skeletonPose)
        {
            if (skeletonPose != skeletonPoseLast)
            {
                skeletonPoseLast = skeletonPose;

                switch (skeletonPose)
                {
                    case SkeletonPose.NotDetected:      // we don't come here with "NotDetected"
                    case SkeletonPose.None:
                    case SkeletonPose.BothArmsForward:  // special case - growling at human
                        break;

                    default:
                        talkerToHuman.Say(9, SkeletonPoseToSpokenString(skeletonPose));
                        break;
                }

                switch (skeletonPose)
                {
                    case SkeletonPose.NotDetected:  // we don't come here with "NotDetected"
                    default:
                        StartHeadAnimationCombo(HeadComboAnimations.Restpose);
                        AddHeadAnimationCombo(HeadComboAnimations.BlinkCycle);
                        HeadlightsOff();
                        break;

                    case SkeletonPose.ArmsCrossed:
                    case SkeletonPose.LeftHandPointingRight:
                    case SkeletonPose.LeftHandUp:
                    case SkeletonPose.RightHandPointingLeft:
                    case SkeletonPose.RightHandUp:
                        StartHeadAnimationCombo(HeadComboAnimations.Blink1, true, 0.5d);
                        break;

                    case SkeletonPose.None:
                        //talkerToHuman.Say(9, "At ease");
                        HeadlightsOff();
                        StartHeadAnimationCombo(HeadComboAnimations.Restpose);
                        AddHeadAnimationCombo(HeadComboAnimations.Acknowledge);
                        break;

                    case SkeletonPose.HandsUp:
                        //talkerToHuman.Say(9, "Hands Up");
                        StartHeadAnimationCombo(HeadComboAnimations.Angry);
                        break;

                    case SkeletonPose.BothArmsForward:
                        //talkerToHuman.Say(9, "Pointing At Me");
                        talkerToHuman.GrowlAtHuman();
                        break;

                    case SkeletonPose.LeftArmForward:
                        StartHeadAnimationCombo(HeadComboAnimations.Alert_lookright);
                        break;

                    case SkeletonPose.RightArmForward:
                        StartHeadAnimationCombo(HeadComboAnimations.Alert_lookleft);
                        break;

                    // react to headlights commanding pose gestures:
                    case SkeletonPose.BothArmsOut:
                        {
                            HeadlightsOn();
                            FollowDirectionTargetDistanceToGoalMeters += 0.3d;  // hands to the sides also means back up a bit
                            StartHeadAnimationCombo(HeadComboAnimations.Angry);
                        }
                        break;

                    case SkeletonPose.LeftArmOut:
                        {
                            HeadlightsOnOff(false, true);   // right light on
                            StartHeadAnimationCombo(HeadComboAnimations.Acknowledge);
                            AddHeadAnimationCombo(HeadComboAnimations.Turn_right);
                        }
                        break;

                    case SkeletonPose.RightArmOut:
                        {
                            HeadlightsOnOff(true, false);   // left light on
                            StartHeadAnimationCombo(HeadComboAnimations.Acknowledge);
                            AddHeadAnimationCombo(HeadComboAnimations.Turn_left);
                        }
                        break;
                }
            }
        }
예제 #60
0
        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);
        }