Example #1
0
        public override void Update(GameTime gameTime)
        {
            // Move the directional light in a circle.
            float deltaTimeF = (float)gameTime.ElapsedGameTime.TotalSeconds;

            _lightAngle += 0.3f * deltaTimeF;
            var position = QuaternionF.CreateRotationY(_lightAngle).Rotate(new Vector3F(6, 6, 0));

            // Make the light look at the world space origin.
            var lightTarget  = Vector3F.Zero;
            var lookAtMatrix = Matrix44F.CreateLookAt(position, lightTarget, Vector3F.Up);

            // A look-at matrix is the inverse of a normal world or pose matrix.
            _mainDirectionalLightNode.PoseWorld =
                new Pose(lookAtMatrix.Translation, lookAtMatrix.Minor).Inverse;

            // Compute shadow matrix for the new light direction.
            var lightRayDirection = (lightTarget - position);

            _shadowMatrix = ProjectedShadowRenderer.CreateShadowMatrix(
                new Plane(new Vector3F(0, 1, 0), 0.01f), new Vector4F(-lightRayDirection, 0));

            // Update the scene - this must be called once per frame.
            _scene.Update(gameTime.ElapsedGameTime);

            base.Update(gameTime);
        }
        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);
                }
            }
        }
Example #3
0
        public void CreateRotationY()
        {
            float       angle = 0.3f;
            QuaternionF q     = QuaternionF.CreateRotation(Vector3F.UnitY, angle);
            QuaternionF qy    = QuaternionF.CreateRotationY(angle);

            Assert.AreEqual(q, qy);
        }
Example #4
0
        public void MultiplyOperator()
        {
            Pose p1 = new Pose(new Vector3F(1, 2, 3), QuaternionF.CreateRotationY(0.3f));
            Pose p2 = new Pose(new Vector3F(-4, 5, -6), QuaternionF.CreateRotationZ(-0.1f));

            Assert.IsTrue(Vector4F.AreNumericallyEqual(
                              p1.ToMatrix44F() * p2.ToMatrix44F() * new Vector4F(1, 2, 3, 1),
                              p1 * p2 * new Vector4F(1, 2, 3, 1)));
        }
Example #5
0
        public void Equals()
        {
            Pose p1 = new Pose(new Vector3F(1, 2, 3), QuaternionF.CreateRotationY(0.3f));
            Pose p2 = new Pose(new Vector3F(1, 2, 3), QuaternionF.CreateRotationY(0.3f));

            Assert.AreEqual(p1, p2);
            Assert.IsTrue(p1.Equals((object)p2));
            Assert.IsTrue(p1.Equals(p2));
            Assert.IsFalse(p1.Equals(p2.ToMatrix44F()));
        }
Example #6
0
        public PostProcessingSample(Microsoft.Xna.Framework.Game game)
            : base(game)
        {
            SampleFramework.IsMouseVisible = false;

            // Add a PostProcessingGraphicsScreen. This graphics screen has a Scene and does
            // the rendering including post-processing. Please look at PostProcessingGraphicsScreen
            // for more details.
            GraphicsScreen             = new PostProcessingGraphicsScreen(Services);
            GraphicsScreen.DrawReticle = true;
            GraphicsService.Screens.Insert(0, GraphicsScreen);

            // GameObjects that need to render stuff will retrieve the DebugRenderers or
            // Scene through the service provider.
            Services.Register(typeof(DebugRenderer), null, GraphicsScreen.DebugRenderer);
            Services.Register(typeof(IScene), null, GraphicsScreen.Scene);

            // Add gravity and damping to the physics simulation.
            Simulation.ForceEffects.Add(new Gravity());
            Simulation.ForceEffects.Add(new Damping());

            // Add a custom game object which controls the camera.
            var cameraGameObject = new CameraObject(Services, 100);

            GameObjectService.Objects.Add(cameraGameObject);
            GraphicsScreen.ActiveCameraNode = cameraGameObject.CameraNode;

            GameObjectService.Objects.Add(new GrabObject(Services));
            GameObjectService.Objects.Add(new StaticSkyObject(Services)
            {
                SkyExposure = 1
            });
            GameObjectService.Objects.Add(new GroundObject(Services));

            for (int i = 0; i < 20; i++)
            {
                GameObjectService.Objects.Add(new DynamicObject(Services, 2));
            }

            for (int i = 0; i < 10; i++)
            {
                var randomPosition = new Vector3F(
                    RandomHelper.Random.NextFloat(-5, 5),
                    0,
                    RandomHelper.Random.NextFloat(-10, 0));
                var randomOrientation = QuaternionF.CreateRotationY(RandomHelper.Random.NextFloat(0, ConstantsF.TwoPi));

                GameObjectService.Objects.Add(new DudeObject(Services)
                {
                    Pose = new Pose(randomPosition, randomOrientation)
                });
            }
        }
Example #7
0
        public override void Update(Microsoft.Xna.Framework.GameTime gameTime)
        {
            // Get steering angle from arrow keys.
            if (InputService.IsDown(Keys.Left))
            {
                _steeringAngle = 0.7f;
            }
            else if (InputService.IsDown(Keys.Right))
            {
                _steeringAngle = -0.7f;
            }
            else
            {
                _steeringAngle = 0;
            }

            // Lock the steering angles of the front wheels.
            _frontLeftHinge.Minimum  = new Vector2F(_steeringAngle, float.NegativeInfinity);
            _frontLeftHinge.Maximum  = new Vector2F(_steeringAngle, float.PositiveInfinity);
            _frontRightHinge.Minimum = new Vector2F(_steeringAngle, float.NegativeInfinity);
            _frontRightHinge.Maximum = new Vector2F(_steeringAngle, float.PositiveInfinity);

            // Get velocity from arrow keys.
            float wheelVelocity = 0;

            if (InputService.IsDown(Keys.Up))
            {
                wheelVelocity += 60;
            }
            if (InputService.IsDown(Keys.Down))
            {
                wheelVelocity -= 60;
            }

            // The normal rotation axis is the -x axis.
            Vector3F axis = -Vector3F.UnitX;

            // Rotate the axis by the steering angle.
            axis = QuaternionF.CreateRotationY(_steeringAngle).Rotate(axis);

            // Set the axes and the velocities of the motors.
            _frontLeftMotor.AxisALocal      = axis;
            _frontLeftMotor.TargetVelocity  = wheelVelocity;
            _frontRightMotor.AxisALocal     = axis;
            _frontRightMotor.TargetVelocity = wheelVelocity;

            base.Update(gameTime);
        }
Example #8
0
        public void ResetPose()
        {
            _currentYaw   = _defaultYaw;
            _currentPitch = _defaultPitch;

            if (IsLoaded)
            {
                // Also update SceneNode.LastPose - this is required for some effect, like
                // object motion blur.
                CameraNode.SetLastPose(true);

                CameraNode.PoseWorld = new Pose(
                    _defaultPosition,
                    QuaternionF.CreateRotationY(_currentYaw) * QuaternionF.CreateRotationX(_currentPitch));
            }
        }
Example #9
0
        /// <summary>
        /// Called when a mesh should be generated for the shape.
        /// </summary>
        /// <param name="absoluteDistanceThreshold">The absolute distance threshold.</param>
        /// <param name="iterationLimit">The iteration limit.</param>
        /// <returns>The triangle mesh for this shape.</returns>
        protected override TriangleMesh OnGetMesh(float absoluteDistanceThreshold, int iterationLimit)
        {
            // Estimate required segment angle for given accuracy.
            // (Easy to derive from simple drawing of a circle segment with a triangle used to represent
            // the segment.)
            float alpha            = (float)Math.Acos((_radius - absoluteDistanceThreshold) / _radius) * 2;
            int   numberOfSegments = (int)Math.Ceiling(ConstantsF.TwoPi / alpha);

            // Apply the iteration limit - in case absoluteDistanceThreshold is 0.
            // Lets say each iteration doubles the number of segments. This is an arbitrary interpretation
            // of the "iteration limit".
            numberOfSegments = Math.Min(numberOfSegments, 2 << iterationLimit);

            alpha = ConstantsF.TwoPi / numberOfSegments;

            Vector3F    r0       = new Vector3F(_radius, 0, 0);
            Vector3F    tip      = new Vector3F(0, _height, 0);
            QuaternionF rotation = QuaternionF.CreateRotationY(alpha);

            TriangleMesh mesh = new TriangleMesh();

            for (int i = 1; i <= numberOfSegments; i++)
            {
                Vector3F r1 = rotation.Rotate(r0);

                // Bottom triangle
                mesh.Add(new Triangle
                {
                    Vertex0 = Vector3F.Zero,
                    Vertex1 = r1,
                    Vertex2 = r0,
                }, false);

                // Side triangle
                mesh.Add(new Triangle
                {
                    Vertex0 = r0,
                    Vertex1 = r1,
                    Vertex2 = tip,
                }, false);
                r0 = r1;
            }

            mesh.WeldVertices();

            return(mesh);
        }
Example #10
0
        public void SetVelocityTest()
        {
            var body = new RigidBody(new BoxShape(1, 2, 3));

            body.Pose            = new Pose(new Vector3F(10, 20, 30), QuaternionF.CreateRotationY(1.1f));
            body.LinearVelocity  = new Vector3F(1, 2, 3);
            body.AngularVelocity = new Vector3F(4, 5, 6);

            Vector3F pointLocal     = new Vector3F(0.5f, 0.9f, 1.3f);
            Vector3F point          = body.Pose.ToWorldPosition(pointLocal);
            Vector3F targetVelocity = new Vector3F(7, -8, 9);

            Assert.AreNotEqual(targetVelocity, body.GetVelocityOfLocalPoint(pointLocal));

            ConstraintHelper.SetVelocityOfWorldPoint(body, point, targetVelocity);
            Assert.IsTrue(Vector3F.AreNumericallyEqual(targetVelocity, body.GetVelocityOfLocalPoint(pointLocal)));
        }
Example #11
0
        public void Interpolate()
        {
            Pose p1 = new Pose(new Vector3F(1, 2, 3), QuaternionF.CreateRotationY(0.3f));
            Pose p2 = new Pose(new Vector3F(-4, 5, -6), QuaternionF.CreateRotationZ(-0.1f));

            Assert.IsTrue(Vector3F.AreNumericallyEqual(p1.Position, Pose.Interpolate(p1, p2, 0).Position));
            Assert.IsTrue(Matrix33F.AreNumericallyEqual(p1.Orientation, Pose.Interpolate(p1, p2, 0).Orientation));

            Assert.IsTrue(Vector3F.AreNumericallyEqual(p2.Position, Pose.Interpolate(p1, p2, 1).Position));
            Assert.IsTrue(Matrix33F.AreNumericallyEqual(p2.Orientation, Pose.Interpolate(p1, p2, 1).Orientation));

            Assert.IsTrue(Vector3F.AreNumericallyEqual(InterpolationHelper.Lerp(p1.Position, p2.Position, 0.3f), Pose.Interpolate(p1, p2, 0.3f).Position));
            Assert.IsTrue(
                QuaternionF.AreNumericallyEqual(
                    InterpolationHelper.Lerp(QuaternionF.CreateRotation(p1.Orientation), QuaternionF.CreateRotation(p2.Orientation), 0.3f),
                    QuaternionF.CreateRotation(Pose.Interpolate(p1, p2, 0.3f).Orientation)));
        }
Example #12
0
        public void GetHashCodeTest()
        {
            Pose p1 = new Pose(new Vector3F(1, 2, 3), QuaternionF.CreateRotationY(0.3f));
            Pose p2 = new Pose(new Vector3F(1, 2, 3), QuaternionF.CreateRotationY(0.3f));

            Assert.AreEqual(p1.GetHashCode(), p2.GetHashCode());

            p1 = new Pose(new Vector3F(1, 2, 3), QuaternionF.CreateRotationY(0.3f));
            p2 = new Pose(new Vector3F(2, 1, 3), QuaternionF.CreateRotationY(0.3f));
            Assert.AreNotEqual(p1.GetHashCode(), p2.GetHashCode());

            // Too bad two rotation matrices that differ only by the sign of the angle
            // (+/- angle with same axis) have the same hashcodes. See KB -> .NET --> GetHashCode
            //p1 = new Pose(new Vector3F(1, 2, 3), QuaternionF.CreateRotationY(0.3f));
            //p2 = new Pose(new Vector3F(1, 2, 3), QuaternionF.CreateRotationY(-0.3f));
            //Assert.AreNotEqual(p1.GetHashCode(), p2.GetHashCode());
        }
Example #13
0
        private bool _drawDebugInfo; // true if the collision shapes should be drawn for debugging.


        public ContentPipelineSample(Microsoft.Xna.Framework.Game game)
            : base(game)
        {
            SampleFramework.IsMouseVisible = false;
            GraphicsScreen.ClearBackground = true;
            GraphicsScreen.BackgroundColor = Color.CornflowerBlue;
            SetCamera(new Vector3F(0, 1, 10), 0, 0);

            // Initialize collision detection.
            // Note: The physics Simulation also has a collision domain (Simulation.CollisionDomain)
            // which we could use and which is updated together with the Simulation in
            // SampleGame.cs. But in this example we create our own CollisionDomain for demonstration
            // purposes.
            _collisionDomain = new CollisionDomain(new CollisionDetection());

            // Register CollisionDomain in service container.
            Services.Register(typeof(CollisionDomain), null, _collisionDomain);

            // Add game objects which manage graphics models and their collision representations.
            _saucerObject = new SaucerObject(Services)
            {
                Name = "Saucer"
            };
            _shipObjectA = new ShipObject(Services)
            {
                Name = "ShipA"
            };
            _shipObjectB = new ShipObject(Services)
            {
                Name = "ShipB"
            };

            GameObjectService.Objects.Add(_saucerObject);
            GameObjectService.Objects.Add(_shipObjectA);
            GameObjectService.Objects.Add(_shipObjectB);

            // Position the second ship right of the first ship with an arbitrary rotation.
            _shipObjectB.Pose = new Pose(new Vector3F(2, 0, 0), QuaternionF.CreateRotationY(0.7f) * QuaternionF.CreateRotationX(1.2f));

            // Position the saucer left of the first ship with an arbitrary rotation.
            _saucerObject.Pose = new Pose(new Vector3F(-2.5f, 0, 0), QuaternionF.CreateRotationY(0.2f) * QuaternionF.CreateRotationX(0.4f));
        }
        public override void Update(GameTime gameTime)
        {
            base.Update(gameTime);

            float deltaTime = (float)gameTime.ElapsedGameTime.TotalSeconds;

            // Change rotation angle.
            if (_moveArmDown)
            {
                _upperArmAngle -= 0.3f * deltaTime;
            }
            else
            {
                _upperArmAngle += 0.3f * deltaTime;
            }

            // Change direction when a certain angle is reached.
            if (Math.Abs(_upperArmAngle) > 0.5f)
            {
                _moveArmDown = !_moveArmDown;
            }

            // Get the bone index of the upper arm bone.
            var skeleton      = _meshNode.Mesh.Skeleton;
            int upperArmIndex = skeleton.GetIndex("L_UpperArm");

            // Define the desired bone transform.
            SrtTransform boneTransform = new SrtTransform(QuaternionF.CreateRotationY(_upperArmAngle));

            // Set the new bone transform.
            var skeletonPose = _meshNode.SkeletonPose;

            skeletonPose.SetBoneTransform(upperArmIndex, boneTransform);

            // The class SkeletonHelper provides some useful extension methods.
            // One is SetBoneRotationAbsolute() which sets the orientation of a bone relative
            // to model space.
            int handIndex = skeleton.GetIndex("L_Hand");

            SkeletonHelper.SetBoneRotationAbsolute(skeletonPose, handIndex, QuaternionF.CreateRotationX(ConstantsF.Pi));
        }
        public void ResetPose()
        {
            positionFilter.Reset();
            orientationFilter.Reset();
            positionFilter.RawValue[0]    = _defaultPosition.X;
            positionFilter.RawValue[1]    = _defaultPosition.Y;
            positionFilter.RawValue[2]    = _defaultPosition.Z;
            orientationFilter.RawValue[0] = _defaultYaw;
            orientationFilter.RawValue[1] = _defaultPitch;

            if (IsLoaded)
            {
                // Also update SceneNode.LastPose - this is required for some effect, like
                // object motion blur.
                CameraNode.SetLastPose(true);

                CameraNode.PoseWorld = new Pose(
                    _defaultPosition,
                    QuaternionF.CreateRotationY(_defaultYaw) * QuaternionF.CreateRotationX(_defaultPitch));
            }
        }
        public Vector3F GetFogColor(int numberOfSamples, float elevation)
        {
            var forward = new Vector3F((float)Math.Cos(elevation), (float)Math.Sin(elevation), 0);

            Debug.Assert(forward.IsNumericallyNormalized);

            var color = new Vector3F();

            for (int i = numberOfSamples - 1; i >= 0; i--)
            {
                Vector3F sampleDirection = QuaternionF.CreateRotationY(ConstantsF.TwoPi / numberOfSamples).Rotate(forward);

                // Note: Crysis computes fog color without phase function and applies the phase function
                // in the fog shader. The color difference with and without phase function seems to be
                // negligible. The intensity will be about 7 to 12 times lower with the phase function
                // (about 7 when the sun is near the horizon, about 12 when the sun is at the zenith).
                // We use the phase function because our fog shader might not apply a phase function.
                // And if it does apply the phase function, the phase function is normalized to keep the
                // average fog brightness constant.
                const bool usePhaseFunction = true;

                Vector3F transmittance;
                Vector3F colorR, colorM;
                ComputeScattering(sampleDirection, usePhaseFunction, out transmittance, out colorR, out colorM);
                Debug.Assert(sampleDirection.IsNumericallyNormalized);

                Vector3F sample = colorR + colorM + GetBaseColor(sampleDirection);
                if (sample.IsNaN)
                {
                    numberOfSamples--; // Ignore sample.
                }
                else
                {
                    color += sample;
                }
            }

            color /= numberOfSamples;
            return(color);
        }
Example #17
0
        public override void Update(GameTime gameTime)
        {
            // Move the directional light in a circle.
            float deltaTimeF = (float)gameTime.ElapsedGameTime.TotalSeconds;

            _lightAngle += 0.3f * deltaTimeF;
            var position = QuaternionF.CreateRotationY(_lightAngle).Rotate(new Vector3F(6, 6, 0));

            // Make the light look at the world space origin.
            var lightTarget  = Vector3F.Zero;
            var lookAtMatrix = Matrix44F.CreateLookAt(position, lightTarget, Vector3F.Up);

            // A look-at matrix is the inverse of a normal world or pose matrix.
            _mainDirectionalLightNode.PoseWorld =
                new Pose(lookAtMatrix.Translation, lookAtMatrix.Minor).Inverse;

            // Update the light position of the renderer.
            // To create a local light shadow (light rays are not parallel), we have to set the light
            // position and a 4th component of 1.
            //_projectedShadowRenderer.LightPosition = new Vector4F(position, 1);
            // To create a directional light shadow (light rays are parallel), we have to set the inverse
            // light direction and 0.
            var lightRayDirection = (lightTarget - position);

            _projectedShadowRenderer.LightPosition = new Vector4F(-lightRayDirection, 0);

            // For debugging: Draw coordinate axes at (0, 0, 0).
            _debugRenderer.Clear();
            _debugRenderer.DrawAxes(Pose.Identity, 1, true);

            // Draw light node. (Will be drawn as a coordinate cross.)
            _debugRenderer.DrawObject(_mainDirectionalLightNode, Color.Yellow, false, true);

            // Update the scene - this must be called once per frame.
            _scene.Update(gameTime.ElapsedGameTime);

            base.Update(gameTime);
        }
Example #18
0
        protected override void OnUpdate(TimeSpan deltaTime)
        {
            // Mouse centering (controlled by the MenuComponent) is disabled if the game
            // is inactive or if the GUI is active. In these cases, we do not want to move
            // the player.
            if (!_inputService.EnableMouseCentering)
            {
                return;
            }

            float deltaTimeF = (float)deltaTime.TotalSeconds;

            // ----- Hulk Mode
            // Toggle "Hulk" mode if <H> or <X> (gamepad) is pressed.
            if (_inputService.IsPressed(Keys.H, false) || _inputService.IsPressed(Buttons.X, false, LogicalPlayerIndex.One))
            {
                ToggleHulk();
            }

            // ----- Crouching
            if (_inputService.IsPressed(Keys.LeftShift, false) || _inputService.IsPressed(Buttons.RightTrigger, false, LogicalPlayerIndex.One))
            {
                Crouch();
            }
            else if (!_inputService.IsDown(Keys.LeftShift) && !_inputService.IsDown(Buttons.RightTrigger, LogicalPlayerIndex.One) && CharacterController.Height <= 1)
            {
                StandUp();
            }

            // ----- Update orientation
            // Update _yaw and _pitch.
            UpdateOrientation(deltaTimeF);

            // Compute the new orientation of the camera.
            QuaternionF orientation = QuaternionF.CreateRotationY(_yaw) * QuaternionF.CreateRotationX(_pitch);

            // ----- Compute translation
            // Create velocity from <W>, <A>, <S>, <D> and gamepad sticks.
            Vector3F moveDirection = Vector3F.Zero;

            if (Keyboard.GetState().IsKeyDown(Keys.W))
            {
                moveDirection.Z--;
            }
            if (Keyboard.GetState().IsKeyDown(Keys.S))
            {
                moveDirection.Z++;
            }
            if (Keyboard.GetState().IsKeyDown(Keys.A))
            {
                moveDirection.X--;
            }
            if (Keyboard.GetState().IsKeyDown(Keys.D))
            {
                moveDirection.X++;
            }

            GamePadState gamePadState = _inputService.GetGamePadState(LogicalPlayerIndex.One);

            moveDirection.X += gamePadState.ThumbSticks.Left.X;
            moveDirection.Z -= gamePadState.ThumbSticks.Left.Y;

            // Rotate the velocity vector from view space to world space.
            moveDirection = orientation.Rotate(moveDirection);

            // Add velocity from <R>, <F> keys.
            // <R> or DPad up is used to move up ("rise").
            // <F> or DPad down is used to move down ("fall").
            if (Keyboard.GetState().IsKeyDown(Keys.R) || gamePadState.DPad.Up == ButtonState.Pressed)
            {
                moveDirection.Y++;
            }
            if (Keyboard.GetState().IsKeyDown(Keys.F) || gamePadState.DPad.Down == ButtonState.Pressed)
            {
                moveDirection.Y--;
            }

            // ----- Climbing
            bool hasLadderContact = HasLadderContact();
            bool hasLedgeContact  = HasLedgeContact();

            CharacterController.IsClimbing = hasLadderContact || hasLedgeContact;

            // When the character is walking (gravity > 0) it cannot walk up/down - only on a ladder.
            if (CharacterController.Gravity != 0 && !hasLadderContact)
            {
                moveDirection.Y = 0;
            }

            // ----- Moving
            moveDirection.TryNormalize();
            Vector3F moveVelocity = moveDirection * LinearVelocityMagnitude;

            // ----- Jumping
            if ((_inputService.IsPressed(Keys.Space, false) || _inputService.IsPressed(Buttons.A, false, LogicalPlayerIndex.One)) &&
                (CharacterController.HasGroundContact || CharacterController.IsClimbing))
            {
                // Jump button was newly pressed and the character has support to start the jump.
                _timeSinceLastJump = 0;
            }

            float jumpVelocity = 0;

            if ((_inputService.IsDown(Keys.Space) || _inputService.IsDown(Buttons.A, LogicalPlayerIndex.One)))
            {
                // Jump button is still down.
                if (_timeSinceLastJump + deltaTimeF <= DynamicJumpTime)
                {
                    // The DynamicJumpTime has not been exceeded.
                    // Set a jump velocity to make the jump higher.
                    jumpVelocity = JumpVelocity;
                }
                else if (_timeSinceLastJump <= DynamicJumpTime)
                {
                    // The jump time exceeds DynamicJumpTime in this time step.
                    //   _timeSinceLastJump <= DynamicJumpTime
                    //   _timeSinceLastJump + deltaTime > DynamicJumpTime

                    // In order to achieve exact, reproducible jump heights we need to split
                    // the time step:
                    float deltaTime0 = DynamicJumpTime - _timeSinceLastJump;
                    float deltaTime1 = deltaTimeF - deltaTime0;

                    // The first part of the movement is a jump with active jump velocity.
                    jumpVelocity        = JumpVelocity;
                    _timeSinceLastJump += deltaTime0;
                    CharacterController.Move(moveVelocity, jumpVelocity, deltaTime0);

                    // The second part of the movement is a jump without jump velocity.
                    jumpVelocity = 0;
                    deltaTimeF   = deltaTime1;
                }
            }

            _timeSinceLastJump += deltaTimeF;

            // ----- Move the character.
            CharacterController.Move(moveVelocity, jumpVelocity, deltaTimeF);

            // Draw character controller capsule.
            // The character controller is also transparent The hulk is green, of course.
            var color = _isHulk ? Color.DarkGreen : Color.Gray;

            color.A = 128;
            _debugRenderer.DrawObject(CharacterController.Body, color, false, false);
        }
Example #19
0
        // Handle character-related input and move the character.
        private void ControlCharacter(float deltaTime)
        {
            // Compute new orientation from mouse movement.
            float deltaYaw = -InputService.MousePositionDelta.X;

            _yaw += deltaYaw * deltaTime * 0.1f;
            float deltaPitch = -InputService.MousePositionDelta.Y;

            _pitch += deltaPitch * deltaTime * 0.1f;

            // Limit the pitch angle.
            _pitch = MathHelper.Clamp(_pitch, -ConstantsF.PiOver2, ConstantsF.PiOver2);

            // Compute new orientation of the camera.
            QuaternionF cameraOrientation = QuaternionF.CreateRotationY(_yaw) * QuaternionF.CreateRotationX(_pitch);

            // Create velocity from WASD keys.
            // TODO: Diagonal movement is faster ;-). Fix this.
            Vector3F velocityVector = Vector3F.Zero;

            if (Keyboard.GetState().IsKeyDown(Keys.W))
            {
                velocityVector.Z--;
            }
            if (Keyboard.GetState().IsKeyDown(Keys.S))
            {
                velocityVector.Z++;
            }
            if (Keyboard.GetState().IsKeyDown(Keys.A))
            {
                velocityVector.X--;
            }
            if (Keyboard.GetState().IsKeyDown(Keys.D))
            {
                velocityVector.X++;
            }
            velocityVector *= 10 * deltaTime;

            // Velocity vector is currently in view space. -z is the forward direction.
            // We have to convert this vector to world space by rotating it.
            velocityVector = QuaternionF.CreateRotationY(_yaw).Rotate(velocityVector);

            // New compute desired character controller position in world space:
            Vector3F targetPosition = _character.Position + velocityVector;

            // Check if user wants to jump.
            bool jump = Keyboard.GetState().IsKeyDown(Keys.Space);

            // Call character controller to compute a new valid position. The character
            // controller slides along obstacles, handles stepping up/down, etc.
            _character.Move(targetPosition, deltaTime, jump);

            // ----- Set view matrix for graphics.
            // For third person we move the eye position back, behind the body (+z direction is
            // the "back" direction).
            Vector3F thirdPersonDistance = cameraOrientation.Rotate(new Vector3F(0, 0, 6));

            // Compute camera pose (= position + orientation).
            _cameraNode.PoseWorld = new Pose
            {
                Position = _character.Position        // Floor position of character
                           + new Vector3F(0, 1.6f, 0) // + Eye height
                           + thirdPersonDistance,
                Orientation = cameraOrientation.ToRotationMatrix33()
            };
        }
Example #20
0
        // OnLoad() is called when the GameObject is added to the IGameObjectService.
        protected override void OnLoad()
        {
            var content = _services.GetInstance <ContentManager>();

            _skyboxNode = new SkyboxNode(content.Load <TextureCube>("Sky2"))
            {
                Color = new Vector3F(SkyExposure),
            };

            // The ambient light.
            var ambientLight = new AmbientLight
            {
                Color     = new Vector3F(0.9f, 0.9f, 1f),
                HdrScale  = 0.1f,
                Intensity = 0.5f,
                HemisphericAttenuation = 0.8f,
            };

            _ambientLightNode = new LightNode(ambientLight)
            {
                Name = "Ambient",
            };

            // The main directional light.
            var sunlight = new DirectionalLight
            {
                Color             = new Vector3F(1, 0.9607844f, 0.9078432f),
                HdrScale          = 0.4f,
                DiffuseIntensity  = 1,
                SpecularIntensity = 1,
            };

            _sunlightNode = new LightNode(sunlight)
            {
                Name      = "Sunlight",
                Priority  = 10, // This is the most important light.
                PoseWorld = new Pose(QuaternionF.CreateRotationY(-1.4f) * QuaternionF.CreateRotationX(-0.6f)),

                // This light uses Cascaded Shadow Mapping.
                Shadow = new CascadedShadow
                {
#if XBOX
                    PreferredSize = 512,
#else
                    PreferredSize = 1024,
#endif
                    Prefer16Bit = true,
                }
            };

            // Add a lens flare for the key light.
            var lensFlare = new LensFlare(true)
            {
                QuerySize = 0.2f, Size = 0.2f, Name = "Sun Flare"
            };
            var lensFlareTexture = content.Load <Texture2D>("LensFlare/LensFlares");
            var circleTexture    = new PackedTexture("Circle", lensFlareTexture, new Vector2F(0, 0), new Vector2F(0.25f, 0.5f));
            var glowTexture      = new PackedTexture("Glow", lensFlareTexture, new Vector2F(0.25f, 0), new Vector2F(0.25f, 0.5f));
            var ringTexture      = new PackedTexture("Ring", lensFlareTexture, new Vector2F(0.5f, 0), new Vector2F(0.25f, 0.5f));
            var haloTexture      = new PackedTexture("Halo", lensFlareTexture, new Vector2F(0.75f, 0), new Vector2F(0.25f, 0.5f));
            var sunTexture       = new PackedTexture("Sun", lensFlareTexture, new Vector2F(0, 0.5f), new Vector2F(0.25f, 0.5f));
            var streaksTexture   = new PackedTexture("Streaks", lensFlareTexture, new Vector2F(0.25f, 0.5f), new Vector2F(0.25f, 0.5f));
            var flareTexture     = new PackedTexture("Flare", lensFlareTexture, new Vector2F(0.5f, 0.5f), new Vector2F(0.25f, 0.5f));
            lensFlare.Elements.Add(new LensFlareElement(-0.2f, 0.55f, 0.0f, new Color(175, 175, 255, 20), new Vector2F(0.5f, 0.5f), circleTexture));
            lensFlare.Elements.Add(new LensFlareElement(0.0f, 0.9f, 0.0f, new Color(255, 255, 255, 255), new Vector2F(0.5f, 0.5f), sunTexture));
            lensFlare.Elements.Add(new LensFlareElement(0.0f, 1.8f, 0.0f, new Color(255, 255, 255, 128), new Vector2F(0.5f, 0.5f), streaksTexture));
            lensFlare.Elements.Add(new LensFlareElement(0.0f, 2.6f, 0.0f, new Color(255, 255, 200, 64), new Vector2F(0.5f, 0.5f), glowTexture));
            lensFlare.Elements.Add(new LensFlareElement(0.5f, 0.12f, 0.0f, new Color(60, 60, 180, 35), new Vector2F(0.5f, 0.5f), circleTexture));
            lensFlare.Elements.Add(new LensFlareElement(0.55f, 0.46f, 0.0f, new Color(100, 100, 200, 60), new Vector2F(0.5f, 0.5f), circleTexture));
            lensFlare.Elements.Add(new LensFlareElement(0.6f, 0.17f, 0.0f, new Color(120, 120, 220, 40), new Vector2F(0.5f, 0.5f), circleTexture));
            lensFlare.Elements.Add(new LensFlareElement(0.85f, 0.2f, 0.0f, new Color(60, 60, 255, 100), new Vector2F(0.5f, 0.5f), ringTexture));
            lensFlare.Elements.Add(new LensFlareElement(1.5f, 0.2f, 0.0f, new Color(255, 60, 60, 130), new Vector2F(0.5f, 0.5f), flareTexture));
            lensFlare.Elements.Add(new LensFlareElement(0.15f, 0.15f, 0.0f, new Color(255, 60, 60, 90), new Vector2F(0.5f, 0.5f), flareTexture));
            lensFlare.Elements.Add(new LensFlareElement(1.3f, 0.6f, 0.0f, new Color(60, 60, 255, 180), new Vector2F(0.5f, 0.5f), haloTexture));
            lensFlare.Elements.Add(new LensFlareElement(1.4f, 0.2f, 0.0f, new Color(220, 80, 80, 98), new Vector2F(0.5f, 0.5f), haloTexture));
            lensFlare.Elements.Add(new LensFlareElement(1.5f, 0.1f, 0.0f, new Color(220, 80, 80, 85), new Vector2F(0.5f, 0.5f), circleTexture));
            lensFlare.Elements.Add(new LensFlareElement(1.6f, 0.5f, 0.0f, new Color(60, 60, 255, 80), new Vector2F(0.5f, 0.5f), haloTexture));
            lensFlare.Elements.Add(new LensFlareElement(1.8f, 0.3f, 0.0f, new Color(90, 60, 255, 110), new Vector2F(0.5f, 0.5f), ringTexture));
            lensFlare.Elements.Add(new LensFlareElement(1.95f, 0.5f, 0.0f, new Color(60, 60, 255, 120), new Vector2F(0.5f, 0.5f), haloTexture));
            lensFlare.Elements.Add(new LensFlareElement(2.0f, 0.15f, 0.0f, new Color(60, 60, 255, 85), new Vector2F(0.5f, 0.5f), circleTexture));

            // Add lens flare as a child of the sunlight.
            var lensFlareNode = new LensFlareNode(lensFlare);
            _sunlightNode.Children = new SceneNodeCollection();
            _sunlightNode.Children.Add(lensFlareNode);

            // Add scene nodes to scene graph.
            var scene = _services.GetInstance <IScene>();
            scene.Children.Add(_skyboxNode);
            scene.Children.Add(_ambientLightNode);
            scene.Children.Add(_sunlightNode);
        }
Example #21
0
        /// <summary>
        /// Called when a mesh should be generated for the shape.
        /// </summary>
        /// <param name="absoluteDistanceThreshold">The absolute distance threshold.</param>
        /// <param name="iterationLimit">The iteration limit.</param>
        /// <returns>The triangle mesh for this shape.</returns>
        protected override TriangleMesh OnGetMesh(float absoluteDistanceThreshold, int iterationLimit)
        {
            // Estimate required segment angle for given accuracy.
            // (Easy to derive from simple drawing of a circle segment with a triangle used to represent
            // the segment.)
            float alpha            = (float)Math.Acos((Radius - absoluteDistanceThreshold) / Radius) * 2;
            int   numberOfSegments = (int)Math.Ceiling(ConstantsF.PiOver2 / alpha) * 4;

            // Apply the iteration limit - in case absoluteDistanceThreshold is 0.
            // Lets say each iteration doubles the number of segments. This is an arbitrary interpretation
            // of the "iteration limit".
            numberOfSegments = Math.Min(numberOfSegments, 2 << iterationLimit);

            alpha = ConstantsF.TwoPi / numberOfSegments;

            TriangleMesh mesh = new TriangleMesh();

            // The world space vertices are created by rotating "radius vectors" with this rotations.
            QuaternionF rotationY = QuaternionF.CreateRotationY(alpha);
            QuaternionF rotationZ = QuaternionF.CreateRotationZ(alpha);

            // We use two nested loops: In each loop a "radius vector" is rotated further to get a
            // new vertex.
            Vector3F rLow = Vector3F.UnitX * Radius; // Radius vector for the lower vertex.

            for (int i = 1; i <= numberOfSegments / 4; i++)
            {
                Vector3F rHigh = rotationZ.Rotate(rLow); // Radius vector for the higher vertex.

                // In the inner loop we create lines and triangles between 4 vertices, which are created
                // with the radius vectors rLow0, rLow1, rHigh0, rHigh1.
                Vector3F rLow0  = rLow;
                Vector3F rHigh0 = rHigh;
                for (int j = 1; j <= numberOfSegments; j++)
                {
                    Vector3F rLow1  = rotationY.Rotate(rLow0);
                    Vector3F rHigh1 = rotationY.Rotate(rHigh0);

                    // Two top hemisphere triangles
                    mesh.Add(new Triangle
                    {
                        Vertex0 = new Vector3F(0, Height / 2 - Radius, 0) + rLow0,
                        Vertex1 = new Vector3F(0, Height / 2 - Radius, 0) + rLow1,
                        Vertex2 = new Vector3F(0, Height / 2 - Radius, 0) + rHigh0,
                    }, false);
                    if (i < numberOfSegments / 4) // At the "northpole" only a triangle is needed. No quad.
                    {
                        mesh.Add(new Triangle
                        {
                            Vertex0 = new Vector3F(0, Height / 2 - Radius, 0) + rLow1,
                            Vertex1 = new Vector3F(0, Height / 2 - Radius, 0) + rHigh1,
                            Vertex2 = new Vector3F(0, Height / 2 - Radius, 0) + rHigh0,
                        }, false);
                    }

                    // Two bottom hemisphere triangles
                    mesh.Add(new Triangle
                    {
                        Vertex0 = new Vector3F(0, -Height / 2 + Radius, 0) - rLow0,
                        Vertex1 = new Vector3F(0, -Height / 2 + Radius, 0) - rHigh0,
                        Vertex2 = new Vector3F(0, -Height / 2 + Radius, 0) - rLow1,
                    }, false);
                    if (i < numberOfSegments / 4) // At the "southpole" only a triangle is needed. No quad.
                    {
                        mesh.Add(new Triangle
                        {
                            Vertex0 = new Vector3F(0, -Height / 2 + Radius, 0) - rLow1,
                            Vertex1 = new Vector3F(0, -Height / 2 + Radius, 0) - rHigh0,
                            Vertex2 = new Vector3F(0, -Height / 2 + Radius, 0) - rHigh1,
                        }, false);
                    }

                    // Two side triangles
                    if (i == 1)
                    {
                        mesh.Add(new Triangle
                        {
                            Vertex0 = new Vector3F(0, -Height / 2 + Radius, 0) + rLow0,
                            Vertex1 = new Vector3F(0, -Height / 2 + Radius, 0) + rLow1,
                            Vertex2 = new Vector3F(0, Height / 2 - Radius, 0) + rLow0,
                        }, false);
                        mesh.Add(new Triangle
                        {
                            Vertex0 = new Vector3F(0, -Height / 2 + Radius, 0) + rLow1,
                            Vertex1 = new Vector3F(0, Height / 2 - Radius, 0) + rLow1,
                            Vertex2 = new Vector3F(0, Height / 2 - Radius, 0) + rLow0,
                        }, false);
                    }

                    rLow0  = rLow1;
                    rHigh0 = rHigh1;
                }

                rLow = rHigh;
            }

            mesh.WeldVertices();

            return(mesh);
        }
Example #22
0
        public DecalSample(Microsoft.Xna.Framework.Game game)
            : base(game)
        {
            SampleFramework.IsMouseVisible = false;

            _graphicsScreen             = new DeferredGraphicsScreen(Services);
            _graphicsScreen.DrawReticle = true;
            GraphicsService.Screens.Insert(0, _graphicsScreen);
            GameObjectService.Objects.Add(new DeferredGraphicsOptionsObject(Services));

            Services.Register(typeof(DebugRenderer), null, _graphicsScreen.DebugRenderer);
            Services.Register(typeof(IScene), null, _graphicsScreen.Scene);

            // Add gravity and damping to the physics simulation.
            Simulation.ForceEffects.Add(new Gravity());
            Simulation.ForceEffects.Add(new Damping());

            // Add a custom game object which controls the camera.
            var cameraGameObject = new CameraObject(Services);

            GameObjectService.Objects.Add(cameraGameObject);
            _graphicsScreen.ActiveCameraNode = cameraGameObject.CameraNode;

            GameObjectService.Objects.Add(new GrabObject(Services));
            GameObjectService.Objects.Add(new StaticSkyObject(Services));
            GameObjectService.Objects.Add(new GroundObject(Services));
            GameObjectService.Objects.Add(new ObjectCreatorObject(Services));
            GameObjectService.Objects.Add(new LavaBallsObject(Services));
            GameObjectService.Objects.Add(new FogObject(Services));

            // Add some static objects.
            GameObjectService.Objects.Add(new StaticObject(Services, "Barrier/Barrier", 1, Pose.Identity));
            GameObjectService.Objects.Add(new StaticObject(Services, "Barrier/Cylinder", 1, new Pose(new Vector3F(3, 0, 1), QuaternionF.CreateRotationY(MathHelper.ToRadians(-20)))));

            // Add a dynamic object.
            GameObjectService.Objects.Add(new DynamicObject(Services, 1));

            // Add some predefined decals.
            GameObjectService.Objects.Add(new EnvironmentDecalsObject(Services));
        }
        public EnvironmentLightSample(Microsoft.Xna.Framework.Game game)
            : base(game)
        {
            SampleFramework.IsMouseVisible = false;

            _graphicsScreen             = new DeferredGraphicsScreen(Services);
            _graphicsScreen.DrawReticle = true;
            GraphicsService.Screens.Insert(0, _graphicsScreen);
            GameObjectService.Objects.Add(new DeferredGraphicsOptionsObject(Services));

            Services.Register(typeof(DebugRenderer), null, _graphicsScreen.DebugRenderer);
            Services.Register(typeof(IScene), null, _graphicsScreen.Scene);

            // Add gravity and damping to the physics Simulation.
            Simulation.ForceEffects.Add(new Gravity());
            Simulation.ForceEffects.Add(new Damping());

            // Add a custom game object which controls the camera.
            var cameraGameObject = new CameraObject(Services);

            GameObjectService.Objects.Add(cameraGameObject);
            _graphicsScreen.ActiveCameraNode = cameraGameObject.CameraNode;

            GameObjectService.Objects.Add(new GrabObject(Services));
            GameObjectService.Objects.Add(new GroundObject(Services));
            GameObjectService.Objects.Add(new DudeObject(Services));
            var lavaBallsObject = new LavaBallsObject(Services);

            GameObjectService.Objects.Add(lavaBallsObject);
            GameObjectService.Objects.Add(new ObjectCreatorObject(Services));
            GameObjectService.Objects.Add(new FogObject(Services));
            GameObjectService.Objects.Add(new StaticObject(Services, "Barrier/Barrier", 0.9f, new Pose(new Vector3F(0, 0, -2))));
            GameObjectService.Objects.Add(new StaticObject(Services, "Barrier/Cylinder", 0.9f, new Pose(new Vector3F(3, 0, 0), QuaternionF.CreateRotationY(MathHelper.ToRadians(-20)))));
            GameObjectService.Objects.Add(new StaticSkyObject(Services));

            // Add a few palm trees.
            Random random = new Random(12345);

            for (int i = 0; i < 10; i++)
            {
                Vector3F  position    = new Vector3F(random.NextFloat(-3, -8), 0, random.NextFloat(0, -5));
                Matrix33F orientation = Matrix33F.CreateRotationY(random.NextFloat(0, ConstantsF.TwoPi));
                float     scale       = random.NextFloat(0.5f, 1.2f);
                GameObjectService.Objects.Add(new StaticObject(Services, "PalmTree/palm_tree", scale, new Pose(position, orientation)));
            }

            // Add some more dynamic objects.
            for (int i = 0; i < 5; i++)
            {
                lavaBallsObject.Spawn();
                GameObjectService.Objects.Add(new ProceduralObject(Services));
                GameObjectService.Objects.Add(new DynamicObject(Services, 7));
            }

            // To show the effect of the EnvironmentLight in isolation, disable all other light sources.
            //foreach (var light in _graphicsScreen.Scene.GetDescendants().OfType<LightNode>())
            //  light.IsEnabled = false;

            // Add the environment light.
            var environmentLight = new EnvironmentLight
            {
                Color             = new Vector3F(0.1f),
                DiffuseIntensity  = 0,
                SpecularIntensity = 1,
                EnvironmentMap    = ContentManager.Load <TextureCube>("Sky2"),
            };
            var environmentLightNode = new LightNode(environmentLight)
            {
                Name = "Environment",
            };

            _graphicsScreen.Scene.Children.Add(environmentLightNode);

            // The EnvironmentLight is a new light type. We have to register a light renderer
            // for this light in the LightRenderer of the DeferredGraphicsScreen.
            _graphicsScreen.LightBufferRenderer.LightRenderer.Renderers.Add(new EnvironmentLightRenderer(GraphicsService));

            // EnvironmentLight.fx uses the specular power of the materials to determine
            // which mip map level of the cube is reflected.
            // In reality, a high specular power is necessary to reflect the cube map
            // with all its detail. To reflect a cube map level with 512 texels size, we
            // need a specular power of ~200000.
            // To make the reflection effects more obvious, let's change some material properties
            // and make the more reflective.

            // ProceduralObject:
            var proceduralObjects = _graphicsScreen.Scene
                                    .GetDescendants()
                                    .OfType <MeshNode>()
                                    .Where(mn => mn.Mesh.Name == "ProceduralObject")
                                    .Select(mn => mn.Mesh);

            foreach (var mesh in proceduralObjects)
            {
                foreach (var material in mesh.Materials)
                {
                    material["GBuffer"].Set("SpecularPower", 10000f);
                    material["Material"].Set("DiffuseColor", new Vector3(0.01f));
                    material["Material"].Set("SpecularColor", new Vector3(1));
                }
            }

            // Frame of GlassBox:
            var glassBoxes = _graphicsScreen.Scene
                             .GetDescendants()
                             .OfType <ModelNode>()
                             .Where(mn => mn.Name == "GlassBox")
                             .Select(mn => ((MeshNode)mn.Children[0]).Mesh);

            foreach (var mesh in glassBoxes)
            {
                foreach (var material in mesh.Materials.Where(m => m.Contains("GBuffer")))
                {
                    material["GBuffer"].Set("SpecularPower", 100000f);
                    material["Material"].Set("DiffuseColor", new Vector3(0.0f));
                    material["Material"].Set("SpecularColor", new Vector3(1));
                }
            }

            // LavaBall:
            var lavaBalls = _graphicsScreen.Scene
                            .GetDescendants()
                            .OfType <ModelNode>()
                            .Where(mn => mn.Name == "LavaBall")
                            .Select(mn => ((MeshNode)mn.Children[0]).Mesh);

            foreach (var mesh in lavaBalls)
            {
                foreach (var material in mesh.Materials.Where(m => m.Contains("GBuffer")))
                {
                    material["GBuffer"].Set("SpecularPower", 10000f);
                    material["Material"].Set("DiffuseColor", new Vector3(0.0f));
                    material["Material"].Set("SpecularColor", new Vector3(10));
                    material["Material"].Set("EmissiveColor", new Vector3(0.0f));
                }
            }

            // Ground plane:
            var groundPlanes = _graphicsScreen.Scene
                               .GetDescendants()
                               .OfType <ModelNode>()
                               .Where(mn => mn.Name == "Ground")
                               .Select(mn => ((MeshNode)mn.Children[0]).Mesh);

            foreach (var mesh in groundPlanes)
            {
                foreach (var material in mesh.Materials.Where(m => m.Contains("GBuffer")))
                {
                    material["GBuffer"].Set("SpecularPower", 200000.0f);
                    material["Material"].Set("DiffuseColor", new Vector3(0.5f));
                    material["Material"].Set("SpecularColor", new Vector3(0.4f));
                }
            }

            // Please note, XNA does not filter cube maps over cube map borders. Therefore, reflections
            // of low resolution mip map levels might show obvious borders between the cube map
            // sides. In this case you can change the EnvironmentLight.fx effect to always reflect
            // the mip map level 0.
            // This is not a problem with MonoGame because DirectX automatically filters cube map borders.
        }
Example #24
0
        // OnUpdate() is called once per frame.
        protected override void OnUpdate(TimeSpan deltaTime)
        {
            // Mouse centering (controlled by the MenuComponent) is disabled if the game
            // is inactive or if the GUI is active. In these cases, we do not want to move
            // the player.
            if (!_inputService.EnableMouseCentering)
            {
                return;
            }

            if (!IsEnabled)
            {
                return;
            }

            float deltaTimeF = (float)deltaTime.TotalSeconds;

            // Compute new orientation from mouse movement, gamepad and touch.
            Vector2F     mousePositionDelta = _inputService.MousePositionDelta;
            GamePadState gamePadState       = _inputService.GetGamePadState(LogicalPlayerIndex.One);
            Vector2F     touchDelta         = Vector2F.Zero;

#if MONOGAME || WINDOWS_PHONE
            foreach (var gesture in _inputService.Gestures)
            {
                if (gesture.GestureType == GestureType.FreeDrag)
                {
                    touchDelta += (Vector2F)gesture.Delta;

                    // If we have touch input, we ignore the mouse movement
                    mousePositionDelta = Vector2F.Zero;
                }
            }
#endif

#if WINDOWS_PHONE || IOS
            // On Windows Phone touch input also sets the mouse input. --> Ignore mouse data.
            mousePositionDelta = Vector2F.Zero;
#endif

            float deltaYaw = -mousePositionDelta.X - touchDelta.X - gamePadState.ThumbSticks.Right.X * ThumbStickFactor;
            _currentYaw += deltaYaw * deltaTimeF * AngularVelocityMagnitude;

            float deltaPitch = -mousePositionDelta.Y - touchDelta.Y + gamePadState.ThumbSticks.Right.Y * ThumbStickFactor;
            _currentPitch += deltaPitch * deltaTimeF * AngularVelocityMagnitude;

            // Limit the pitch angle to +/- 90°.
            _currentPitch = MathHelper.Clamp(_currentPitch, -ConstantsF.PiOver2, ConstantsF.PiOver2);

            // Reset camera position if <Home> or <Right Stick> is pressed.
            if (_inputService.IsPressed(Keys.Home, false) ||
                _inputService.IsPressed(Buttons.RightStick, false, LogicalPlayerIndex.One))
            {
                ResetPose();
            }

            // Compute new orientation of the camera.
            QuaternionF orientation = QuaternionF.CreateRotationY(_currentYaw) * QuaternionF.CreateRotationX(_currentPitch);

            // Create velocity from <W>, <A>, <S>, <D> and <R>, <F> keys.
            // <R> or DPad up is used to move up ("rise").
            // <F> or DPad down is used to move down ("fall").
            Vector3F      velocity      = Vector3F.Zero;
            KeyboardState keyboardState = _inputService.KeyboardState;
            if (keyboardState.IsKeyDown(Keys.W))
            {
                velocity.Z--;
            }
            if (keyboardState.IsKeyDown(Keys.S))
            {
                velocity.Z++;
            }
            if (keyboardState.IsKeyDown(Keys.A))
            {
                velocity.X--;
            }
            if (keyboardState.IsKeyDown(Keys.D))
            {
                velocity.X++;
            }
            if (keyboardState.IsKeyDown(Keys.R) || gamePadState.DPad.Up == ButtonState.Pressed)
            {
                velocity.Y++;
            }
            if (keyboardState.IsKeyDown(Keys.F) || gamePadState.DPad.Down == ButtonState.Pressed)
            {
                velocity.Y--;
            }

            // Add velocity from gamepad sticks.
            velocity.X += gamePadState.ThumbSticks.Left.X;
            velocity.Z -= gamePadState.ThumbSticks.Left.Y;

            // Rotate the velocity vector from view space to world space.
            velocity = orientation.Rotate(velocity);

            if (keyboardState.IsKeyDown(Keys.LeftShift))
            {
                velocity *= SpeedBoost;
            }

            // Multiply the velocity by time to get the translation for this frame.
            Vector3F translation = velocity * LinearVelocityMagnitude * deltaTimeF;

            // Update SceneNode.LastPoseWorld - this is required for some effects, like
            // camera motion blur.
            CameraNode.LastPoseWorld = CameraNode.PoseWorld;

            // Set the new camera pose.
            CameraNode.PoseWorld = new Pose(
                CameraNode.PoseWorld.Position + translation,
                orientation);
        }
Example #25
0
        public CloudQuadSample(Microsoft.Xna.Framework.Game game)
            : base(game)
        {
            SampleFramework.IsMouseVisible = false;

            _graphicsScreen             = new DeferredGraphicsScreen(Services);
            _graphicsScreen.DrawReticle = true;
            GraphicsService.Screens.Insert(0, _graphicsScreen);
            GameObjectService.Objects.Add(new DeferredGraphicsOptionsObject(Services));

            Services.Register(typeof(DebugRenderer), null, _graphicsScreen.DebugRenderer);
            Services.Register(typeof(IScene), null, _graphicsScreen.Scene);

            // Add gravity and damping to the physics Simulation.
            Simulation.ForceEffects.Add(new Gravity());
            Simulation.ForceEffects.Add(new Damping());

            // Add a custom game object which controls the camera.
            var cameraGameObject = new CameraObject(Services);

            GameObjectService.Objects.Add(cameraGameObject);
            _graphicsScreen.ActiveCameraNode = cameraGameObject.CameraNode;

            GameObjectService.Objects.Add(new GrabObject(Services));
            GameObjectService.Objects.Add(new GroundObject(Services));
            GameObjectService.Objects.Add(new DudeObject(Services));
            GameObjectService.Objects.Add(new ObjectCreatorObject(Services));
            GameObjectService.Objects.Add(new LavaBallsObject(Services));
            GameObjectService.Objects.Add(new FogObject(Services));
            GameObjectService.Objects.Add(new StaticObject(Services, "Barrier/Barrier", 0.9f, new Pose(new Vector3F(0, 0, -2))));
            GameObjectService.Objects.Add(new StaticObject(Services, "Barrier/Cylinder", 0.9f, new Pose(new Vector3F(3, 0, 0), QuaternionF.CreateRotationY(MathHelper.ToRadians(-20)))));

            // The DynamicSkyObject creates the dynamic sky and lights but no clouds.
            var dynamicSkyObject = new DynamicSkyObject(Services, false, false, false);

            GameObjectService.Objects.Add(dynamicSkyObject);

            // Add a few palm trees.
            Random random = new Random(12345);

            for (int i = 0; i < 10; i++)
            {
                Vector3F  position    = new Vector3F(random.NextFloat(-3, -8), 0, random.NextFloat(0, -5));
                Matrix33F orientation = Matrix33F.CreateRotationY(random.NextFloat(0, ConstantsF.TwoPi));
                float     scale       = random.NextFloat(0.5f, 1.2f);
                GameObjectService.Objects.Add(new StaticObject(Services, "PalmTree/palm_tree", scale, new Pose(position, orientation)));
            }

            // The model CloudQuad.fbx consists of a textured quad with a custom effect
            // "Cloud.fx". The effect uses several effect parameters. Constant effect
            // parameters are set in the Cloud.drmat material file.
            // The effect parameters, like "World", "WorldViewProjection", "CameraPosition",
            // are automatically updated by the graphics service. But the effect
            // contains 3 new effect parameters which must be set at runtime:
            // "SunDirection", "SunLight" and "SkyLight".
            // Therefore we add a custom effect interpreter and a custom effect binder
            // which tell the graphics manager what it should do with these parameters.
            // The effect interpreter and binder must be registered before the CloudQuad
            // model is loaded!
            _skyEffectInterpreter = GraphicsService.EffectInterpreters.OfType <SkyEffectInterpreter>().FirstOrDefault();
            if (_skyEffectInterpreter == null)
            {
                _skyEffectInterpreter = new SkyEffectInterpreter();
                GraphicsService.EffectInterpreters.Add(_skyEffectInterpreter);
            }

            _skyEffectBinder = GraphicsService.EffectBinders.OfType <SkyEffectBinder>().FirstOrDefault();
            if (_skyEffectBinder == null)
            {
                _skyEffectBinder = new SkyEffectBinder();
                GraphicsService.EffectBinders.Add(_skyEffectBinder);
            }

            // The effect binder defines several delegates which update the effect parameters
            // using values which are computed by the DynamicSkyObject.
            _skyEffectBinder.DynamicSkyObject = dynamicSkyObject;

            // Add several CloudQuad models in the sky with random scales and poses.
            for (int i = 0; i < 20; i++)
            {
                var scale = new Vector3F(
                    RandomHelper.Random.NextFloat(100, 200),
                    0,
                    RandomHelper.Random.NextFloat(100, 200));

                var position = new Vector3F(
                    RandomHelper.Random.NextFloat(-500, 500),
                    RandomHelper.Random.NextFloat(100, 200),
                    RandomHelper.Random.NextFloat(-500, 500));

                var orientation = Matrix33F.CreateRotationY(RandomHelper.Random.NextFloat(0, ConstantsF.TwoPi));
                GameObjectService.Objects.Add(new StaticObject(Services, "CloudQuad/CloudQuad", scale, new Pose(position, orientation), false, false));
            }
        }
Example #26
0
        private void CreateRoad()
        {
            //RandomHelper.Random = new Random(1234567);

            // Set isClosed to true join the start and the end of the road.
            bool isClosed = false;

            // Create a new TerrainRoadLayer which paints a road onto the terrain.
            // The road itself is defined by a mesh which is set later.
            _roadLayer = new TerrainRoadLayer(GraphicsService)
            {
                DiffuseColor    = new Vector3F(0.5f),
                SpecularColor   = new Vector3F(1),
                DiffuseTexture  = ContentManager.Load <Texture2D>("Terrain/Road-Asphalt-Diffuse"),
                NormalTexture   = ContentManager.Load <Texture2D>("Terrain/Road-Asphalt-Normal"),
                SpecularTexture = ContentManager.Load <Texture2D>("Terrain/Road-Asphalt-Specular"),
                HeightTexture   = ContentManager.Load <Texture2D>("Terrain/Road-Asphalt-Height"),

                // The size of the tileable detail textures in world space units.
                TileSize = 5,

                // The border blend range controls how the border of the road fades out.
                // We fade out 5% of the texture on each side of the road.
                BorderBlendRange = new Vector4F(0.05f, 0.05f, 0.05f, 0.05f),
            };

            // Create 3D spline path with some semi-random control points.
            _roadPath = new Path3F
            {
                PreLoop    = isClosed ? CurveLoopType.Cycle : CurveLoopType.Linear,
                PostLoop   = isClosed ? CurveLoopType.Cycle : CurveLoopType.Linear,
                SmoothEnds = isClosed,
            };

            // The position of the next path key.
            Vector3F position = new Vector3F(
                RandomHelper.Random.NextFloat(-20, 20),
                0,
                RandomHelper.Random.NextFloat(-20, 20));

            // The direction to the next path key.
            Vector3F direction = QuaternionF.CreateRotationY(RandomHelper.Random.NextFloat(0, 10)).Rotate(Vector3F.Forward);

            // Add path keys.
            for (int j = 0; j < 10; j++)
            {
                // Instead of a normal PathKey3F, we use a TerrainRoadPathKey which allows to control
                // the road with and the side falloff.
                var key = new TerrainRoadPathKey
                {
                    Interpolation = SplineInterpolation.CatmullRom,
                    Parameter     = j,
                    Point         = position,

                    // The width of the road at the path key.
                    Width = RandomHelper.Random.NextFloat(6, 10),

                    // The side falloff (which is used in ClampTerrainToRoad to blend the height values with
                    // the road).
                    SideFalloff = RandomHelper.Random.NextFloat(20, 40),
                };

                _roadPath.Add(key);

                // Get next random position and direction.
                position   += direction * RandomHelper.Random.NextFloat(20, 40);
                position.Y += RandomHelper.Random.NextFloat(-2, 2);
                direction   = QuaternionF.CreateRotationY(RandomHelper.Random.NextFloat(-1, 1))
                              .Rotate(direction);
            }

            if (isClosed)
            {
                // To create a closed path the first and the last key should be identical.
                _roadPath[_roadPath.Count - 1].Point = _roadPath[0].Point;
                ((TerrainRoadPathKey)_roadPath[_roadPath.Count - 1]).Width       = ((TerrainRoadPathKey)_roadPath[0]).Width;
                ((TerrainRoadPathKey)_roadPath[_roadPath.Count - 1]).SideFalloff =
                    ((TerrainRoadPathKey)_roadPath[0]).SideFalloff;

                // Since the path is closed we do not have to fade out the start and the end of the road.
                _roadLayer.BorderBlendRange *= new Vector4F(1, 0, 1, 0);
            }

            // Convert the path to a mesh.
            Submesh roadSubmesh;
            Aabb    roadAabb;
            float   roadLength;

            TerrainRoadLayer.CreateMesh(
                GraphicsService.GraphicsDevice,
                _roadPath,
                4,
                10,
                0.1f,
                out roadSubmesh,
                out roadAabb,
                out roadLength);

            // Set the mesh in the road layer.
            _roadLayer.SetMesh(roadSubmesh, roadAabb, roadLength, true);

            if (isClosed)
            {
                // When the path is closed, the end texture and the start texture coordinates should
                // match. This is the case if (roadLength / tileSize) is an integer.
                var numberOfTiles = (int)(roadLength / _roadLayer.TileSize);
                _roadLayer.TileSize = roadLength / numberOfTiles;
            }

            // The road layer is added to the layers of a tile. We have to add the road to each terrain
            // tile which it overlaps.
            foreach (var tile in _terrainObject.TerrainNode.Terrain.Tiles)
            {
                if (GeometryHelper.HaveContact(tile.Aabb, _roadLayer.Aabb.Value))
                {
                    tile.Layers.Add(_roadLayer);
                }
            }
        }
Example #27
0
        // OnUpdate() is called once per frame.
        protected override void OnUpdate(TimeSpan deltaTime)
        {
#if !WINDOWS_PHONE
            // Mouse centering (controlled by the MenuComponent) is disabled if the game
            // is inactive or if the GUI is active. In these cases, we do not want to move
            // the player.
            if (!_inputService.EnableMouseCentering)
            {
                return;
            }
#endif

            if (!IsEnabled)
            {
                return;
            }

            float deltaTimeF = (float)deltaTime.TotalSeconds;

            // Compute new orientation from mouse movement and gamepad.
            Vector2F mousePositionDelta = _inputService.MousePositionDelta;

#if !WINDOWS_PHONE
            GamePadState gamePadState = _inputService.GetGamePadState(LogicalPlayerIndex.One);

            float deltaYaw = -mousePositionDelta.X - gamePadState.ThumbSticks.Right.X * ThumbStickFactor;
            _currentYaw += deltaYaw * deltaTimeF * AngularVelocityMagnitude;

            float deltaPitch = -mousePositionDelta.Y + gamePadState.ThumbSticks.Right.Y * ThumbStickFactor;
            _currentPitch += deltaPitch * deltaTimeF * AngularVelocityMagnitude;

            // Limit the pitch angle to +/- 90°.
            _currentPitch = MathHelper.Clamp(_currentPitch, -ConstantsF.PiOver2, ConstantsF.PiOver2);

            // Reset camera position if <Home> or <Right Stick> is pressed.
            if (_inputService.IsPressed(Keys.Home, false) ||
                _inputService.IsPressed(Buttons.RightStick, false, LogicalPlayerIndex.One))
            {
                ResetPose();
            }

            // Compute new orientation of the camera.
            QuaternionF orientation = QuaternionF.CreateRotationY(_currentYaw) * QuaternionF.CreateRotationX(_currentPitch);

            // Create velocity from <W>, <A>, <S>, <D> and <R>, <F> keys.
            // <R> or DPad up is used to move up ("rise").
            // <F> or DPad down is used to move down ("fall").
            Vector3F      velocity      = Vector3F.Zero;
            KeyboardState keyboardState = _inputService.KeyboardState;
            if (keyboardState.IsKeyDown(Keys.W))
            {
                velocity.Z--;
            }
            if (keyboardState.IsKeyDown(Keys.S))
            {
                velocity.Z++;
            }
            if (keyboardState.IsKeyDown(Keys.A))
            {
                velocity.X--;
            }
            if (keyboardState.IsKeyDown(Keys.D))
            {
                velocity.X++;
            }
            if (keyboardState.IsKeyDown(Keys.R) || gamePadState.DPad.Up == ButtonState.Pressed)
            {
                velocity.Y++;
            }
            if (keyboardState.IsKeyDown(Keys.F) || gamePadState.DPad.Down == ButtonState.Pressed)
            {
                velocity.Y--;
            }

            // Add velocity from gamepad sticks.
            velocity.X += gamePadState.ThumbSticks.Left.X;
            velocity.Z -= gamePadState.ThumbSticks.Left.Y;

            // Rotate the velocity vector from view space to world space.
            velocity = orientation.Rotate(velocity);

            if (keyboardState.IsKeyDown(Keys.LeftShift))
            {
                velocity *= SpeedBoost;
            }

            // Multiply the velocity by time to get the translation for this frame.
            Vector3F translation = velocity * LinearVelocityMagnitude * deltaTimeF;

            // Update SceneNode.LastPoseWorld - this is required for some effects, like
            // camera motion blur.
            CameraNode.LastPoseWorld = CameraNode.PoseWorld;

            // Set the new camera pose.
            CameraNode.PoseWorld = new Pose(
                CameraNode.PoseWorld.Position + translation,
                orientation);
#else
            // Only handle mouse movement is mouse button was down the last frame.
            if (!_inputService.IsPressed(MouseButtons.Left, false))
            {
                float deltaYaw = -mousePositionDelta.X;
                _currentYaw += deltaYaw * deltaTimeF * AngularVelocityMagnitude;
                float deltaPitch = -mousePositionDelta.Y;
                _currentPitch += deltaPitch * deltaTimeF * AngularVelocityMagnitude;

                // Limit the pitch angle.
                _currentPitch = MathHelper.Clamp(_currentPitch, -1, 1);

                // Compute new orientation of the camera.
                QuaternionF orientation = QuaternionF.CreateRotationY(_currentYaw) * QuaternionF.CreateRotationX(_currentPitch);

                var radius = CameraNode.PoseWorld.Position.Length;

                // Update SceneNode.LastPoseWorld - this is required for some effects, like
                // camera motion blur.
                CameraNode.LastPoseWorld = CameraNode.PoseWorld;

                // Set the new camera pose.
                CameraNode.PoseWorld = new Pose(orientation.Rotate(new Vector3F(0, 0, radius)), orientation);
            }
#endif
        }
Example #28
0
        public SplitScreenSample(Microsoft.Xna.Framework.Game game)
            : base(game)
        {
            _graphicsScreen             = new SplitScreen(Services);
            _graphicsScreen.DrawReticle = true;
            GraphicsService.Screens.Insert(0, _graphicsScreen);

            Services.Register(typeof(DebugRenderer), null, _graphicsScreen.DebugRenderer);
            Services.Register(typeof(IScene), null, _graphicsScreen.Scene);

            // Add gravity and damping to the physics Simulation.
            Simulation.ForceEffects.Add(new Gravity());
            Simulation.ForceEffects.Add(new Damping());

            // Add a custom game object which controls the camera of player A.
            var cameraGameObject = new CameraObject(Services);

            GameObjectService.Objects.Add(cameraGameObject);
            _graphicsScreen.ActiveCameraNodeA = cameraGameObject.CameraNode;

            var projection = (PerspectiveProjection)cameraGameObject.CameraNode.Camera.Projection;

            projection.SetFieldOfView(
                projection.FieldOfViewY,
                GraphicsService.GraphicsDevice.Viewport.AspectRatio / 2,
                projection.Near,
                projection.Far);
            cameraGameObject.CameraNode.Camera = new Camera(projection);

            // A second camera for player B.
            _cameraNodeB = new CameraNode(cameraGameObject.CameraNode.Camera);
            _graphicsScreen.ActiveCameraNodeB = _cameraNodeB;

            GameObjectService.Objects.Add(new GrabObject(Services));
            GameObjectService.Objects.Add(new GroundObject(Services));
            GameObjectService.Objects.Add(new DudeObject(Services));
            GameObjectService.Objects.Add(new ObjectCreatorObject(Services));
            GameObjectService.Objects.Add(new LavaBallsObject(Services));
            GameObjectService.Objects.Add(new FogObject(Services));
            GameObjectService.Objects.Add(new StaticObject(Services, "Barrier/Barrier", 0.9f, new Pose(new Vector3F(0, 0, -2))));
            GameObjectService.Objects.Add(new StaticObject(Services, "Barrier/Cylinder", 0.9f, new Pose(new Vector3F(3, 0, 0), QuaternionF.CreateRotationY(MathHelper.ToRadians(-20)))));
            GameObjectService.Objects.Add(new StaticSkyObject(Services));

            // Add a few palm trees.
            Random random = new Random(12345);

            for (int i = 0; i < 10; i++)
            {
                Vector3F  position    = new Vector3F(random.NextFloat(-3, -8), 0, random.NextFloat(0, -5));
                Matrix33F orientation = Matrix33F.CreateRotationY(random.NextFloat(0, ConstantsF.TwoPi));
                float     scale       = random.NextFloat(0.5f, 1.2f);
                GameObjectService.Objects.Add(new StaticObject(Services, "PalmTree/palm_tree", scale, new Pose(position, orientation)));
            }

            GameObjectService.Objects.Add(new OptionsObject(Services));
        }
Example #29
0
        public SkySample(Microsoft.Xna.Framework.Game game)
            : base(game)
        {
            _graphicsScreen             = new DeferredGraphicsScreen(Services);
            _graphicsScreen.DrawReticle = true;
            GraphicsService.Screens.Insert(0, _graphicsScreen);

            Services.Register(typeof(DebugRenderer), null, _graphicsScreen.DebugRenderer);
            Services.Register(typeof(IScene), null, _graphicsScreen.Scene);

            // Add gravity and damping to the physics Simulation.
            Simulation.ForceEffects.Add(new Gravity());
            Simulation.ForceEffects.Add(new Damping());

            // Add a custom game object which controls the camera.
            var cameraGameObject = new CameraObject(Services);

            GameObjectService.Objects.Add(cameraGameObject);
            _graphicsScreen.ActiveCameraNode = cameraGameObject.CameraNode;

            GameObjectService.Objects.Add(new GrabObject(Services));
            GameObjectService.Objects.Add(new GroundObject(Services));
            GameObjectService.Objects.Add(new DudeObject(Services));
            GameObjectService.Objects.Add(new ObjectCreatorObject(Services));
            GameObjectService.Objects.Add(new LavaBallsObject(Services));
            GameObjectService.Objects.Add(new FogObject(Services));
            GameObjectService.Objects.Add(new StaticObject(Services, "Barrier/Barrier", 0.9f, new Pose(new Vector3F(0, 0, -2))));
            GameObjectService.Objects.Add(new StaticObject(Services, "Barrier/Cylinder", 0.9f, new Pose(new Vector3F(3, 0, 0), QuaternionF.CreateRotationY(MathHelper.ToRadians(-20)))));

            // The DynamicSkyObject creates the dynamic sky and lights.
            GameObjectService.Objects.Add(new DynamicSkyObject(Services));

            // Add a few palm trees.
            Random random = new Random(12345);

            for (int i = 0; i < 10; i++)
            {
                Vector3F  position    = new Vector3F(random.NextFloat(-3, -8), 0, random.NextFloat(0, -5));
                Matrix33F orientation = Matrix33F.CreateRotationY(random.NextFloat(0, ConstantsF.TwoPi));
                float     scale       = random.NextFloat(0.5f, 1.2f);
                GameObjectService.Objects.Add(new StaticObject(Services, "PalmTree/palm_tree", scale, new Pose(position, orientation)));
            }

            GameObjectService.Objects.Add(new OptionsObject(Services));

            // Add a grain filter to add some noise in the night.
            _graphicsScreen.PostProcessors.Add(new GrainFilter(GraphicsService)
            {
                IsAnimated         = true,
                LuminanceThreshold = 0.3f,
                ScaleWithLuminance = true,
                Strength           = 0.04f,
                GrainScale         = 1.5f,
            });
        }