Пример #1
0
        public override void Update(GameTime gameTime)
        {
            if (_avatarPose == null)
            {
                if (_avatarRenderer.State == AvatarRendererState.Ready)
                {
                    _avatarPose = new AvatarPose(_avatarRenderer);

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

                    // In this sample we use a passive ragdoll where we need joints to hold the
                    // limbs together and limits to control the angular movement.
                    _ragdoll.EnableJoints();
                    _ragdoll.EnableLimits();

                    // Set all motors to constraint motors that only use damping. This adds a damping
                    // effect to all ragdoll limbs.
                    foreach (RagdollMotor motor in _ragdoll.Motors)
                    {
                        if (motor != null)
                        {
                            motor.Mode = RagdollMotorMode.Constraint;
                            motor.ConstraintDamping = 5;
                            motor.ConstraintSpring  = 0;
                        }
                    }
                    _ragdoll.EnableMotors();

                    // Add rigid bodies and the constraints of the ragdoll to the simulation.
                    _ragdoll.AddToSimulation(Simulation);
                }
            }
            else
            {
                // Copy skeleton pose from ragdoll.
                _ragdoll.UpdateSkeletonFromBodies(_avatarPose.SkeletonPose);
            }

            // Render rigid bodies.
            _debugRenderer.Clear();
            foreach (var body in Simulation.RigidBodies)
            {
                if (!(body.Shape is EmptyShape)) // Do not draw dummy bodies which might be used by the ragdoll.
                {
                    _debugRenderer.DrawObject(body, Color.Black, true, false);
                }
            }
        }
        public 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);
                }
            }
        }