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); } } }
public void CreateRotationY() { float angle = 0.3f; QuaternionF q = QuaternionF.CreateRotation(Vector3F.UnitY, angle); QuaternionF qy = QuaternionF.CreateRotationY(angle); Assert.AreEqual(q, qy); }
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))); }
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())); }
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) }); } }
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); }
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)); } }
/// <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); }
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))); }
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))); }
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()); }
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); }
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); }
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); }
// 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() }; }
// 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); }
/// <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); }
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. }
// 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); }
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)); } }
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); } } }
// 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 }
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)); }
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, }); }