/// <inheritdoc /> /// <summary> /// </summary> /// <param name="dt"></param> /// <param name="gameTime"></param> public override void Update(GameTime gameTime) { var dt = gameTime.ElapsedGameTime.TotalMilliseconds; // Fade in on map start if (Screen.Timing.Time < -500) { var alpha = MathHelper.Lerp(Title.Alpha, 1, (float)Math.Min(dt / AnimationScale, 1)); Title.Alpha = alpha; Difficulty.Alpha = alpha; Creator.Alpha = alpha; Rating.Alpha = alpha; Mods.Alpha = alpha; if (Screen.InReplayMode) { Watching.Alpha = alpha; } } else { var alpha = MathHelper.Lerp(Title.Alpha, 0, (float)Math.Min(dt / AnimationScale, 1)); Title.Alpha = alpha; Difficulty.Alpha = alpha; Creator.Alpha = alpha; Rating.Alpha = alpha; Mods.Alpha = alpha; } base.Update(gameTime); }
private void CalcControlSize() { var canvas = this.MinimapCanvas; Size minimapSize = new Size(canvas?.Width ?? 0, canvas?.Height ?? 0); //计算边框 int top = this.resource.N.Height, bottom = this.resource.S.Height, left = this.resource.W.Width, right = this.resource.E.Width; //计算实际大小 Size desireSize = new Size(minimapSize.Width + left + right, minimapSize.Height + top + bottom); //计算标题 if (this.lblStreetName.Text != null) { this.lblStreetName.Measure(new Size(double.MaxValue, double.MaxValue)); var lblRight = Canvas.GetLeft(this.lblStreetName) + this.lblStreetName.DesiredSize.Width; desireSize.Width = Math.Max(desireSize.Width, lblRight); } if (this.lblMapName.Text != null) { this.lblMapName.Measure(new Size(double.MaxValue, double.MaxValue)); var lblRight = Canvas.GetLeft(this.lblMapName) + this.lblMapName.DesiredSize.Width; desireSize.Width = Math.Max(desireSize.Width, lblRight); } this.Width = MathHelper.Clamp(desireSize.Width, this.MinWidth, this.MaxWidth); this.Height = MathHelper.Clamp(desireSize.Height, this.MinHeight, this.MaxHeight); this.MapAreaControl.Width = Math.Max(0, this.Width - left - right); this.MapAreaControl.Height = Math.Max(0, this.Height - top - bottom); }
private void BuildStation() { BuildRings(125, 175); BuildRings(250, 300); BuildBridge(175, 250, 45, 45.2f, floorTile); BuildBridge(175, 250, 45.2f, 45.2f, 3); BuildBridge(175, 250, 45, 45, 3); BuildBridge(175, 250, 45 - 180, 45.2f - 180, floorTile); BuildBridge(175, 250, 45.2f - 180f, 45.2f - 180, 3); BuildBridge(175, 250, 45 - 180, 45 - 180, 3); BuildBridge(175, 250, 45 - 360, 45.2f - 360, floorTile); BuildBridge(175, 250, 45.2f - 360, 45.2f - 360, 3); BuildBridge(175, 250, 45 - 360, 45 - 360, 3); GameData <Room> roomData = new GameData <Room>(); roomData.folderPath = @"Saves\Rooms\"; Room tempRoom = roomData.LoadObjectData("FloorDecal3"); rooms.Add(tempRoom); BuildRoomsOnRing(150, MathHelper.ToRadians(10f)); BuildRooms(125, 175, 1.85f); BuildRooms(250, 300, 1.95f); }
public WpRagdollSample(Microsoft.Xna.Framework.Game game) : base(game) { GraphicsScreen.ClearBackground = true; GraphicsScreen.BackgroundColor = Color.CornflowerBlue; // Set a fixed camera. var projection = new PerspectiveProjection(); projection.SetFieldOfView( MathHelper.ToRadians(30), GraphicsService.GraphicsDevice.Viewport.AspectRatio, 1f, 100.0f); Vector3F cameraTarget = new Vector3F(0, 1, 0); Vector3F cameraPosition = new Vector3F(0, 12, 0); Vector3F cameraUpVector = new Vector3F(0, 0, -1); GraphicsScreen.CameraNode = new CameraNode(new Camera(projection)) { View = Matrix44F.CreateLookAt(cameraPosition, cameraTarget, cameraUpVector), }; InitializePhysics(); }
/// <summary> /// Processes an area and applies a gradient calculation to each part of the area. /// </summary> /// <param name="position">The center of the gradient.</param> /// <param name="strength">The width of the gradient spread.</param> /// <param name="angle">The angle to apply the gradient.</param> /// <param name="area">The area to calculate.</param> /// <param name="applyAction">The callback called for each part of the area.</param> public static void GradientFill(Point cellSize, Point position, int strength, int angle, Rectangle area, ColorGradient gradient, Action <int, int, Color> applyAction) { double radians = angle * Math.PI / 180; // = Math.Atan2(x1 - x2, y1 - y2); Vector2 angleVector = new Vector2((float)(Math.Sin(radians) * strength), (float)(Math.Cos(radians) * strength)) / 2; Vector2 location = new Vector2(position.X, position.Y); if (cellSize.X > cellSize.Y) { angleVector.Y *= cellSize.X / cellSize.Y; } else if (cellSize.X < cellSize.Y) { angleVector.X *= cellSize.Y / cellSize.X; } Vector2 endingPoint = location + angleVector; Vector2 startingPoint = location - angleVector; double x1 = (startingPoint.X / (double)area.Width) * 2.0f - 1.0f; double y1 = (startingPoint.Y / (double)area.Height) * 2.0f - 1.0f; double x2 = (endingPoint.X / (double)area.Width) * 2.0f - 1.0f; double y2 = (endingPoint.Y / (double)area.Height) * 2.0f - 1.0f; double start = x1 * angleVector.X + y1 * angleVector.Y; double end = x2 * angleVector.X + y2 * angleVector.Y; for (int x = area.Left; x < area.Width; x++) { for (int y = area.Top; y < area.Height; y++) { // but we need vectors from (-1, -1) to (1, 1) // instead of pixels from (0, 0) to (width, height) double u = (x / (double)area.Width) * 2.0f - 1.0f; double v = (y / (double)area.Height) * 2.0f - 1.0f; double here = u * angleVector.X + v * angleVector.Y; double lerp = (start - here) / (start - end); //lerp = Math.Abs((lerp - (int)lerp)); lerp = MyMathHelper.Clamp((float)lerp, 0f, 1.0f); int counter; for (counter = 0; counter < gradient.Stops.Length && gradient.Stops[counter].Stop < (float)lerp; counter++) { ; } counter--; counter = (int)MyMathHelper.Clamp(counter, 0, gradient.Stops.Length - 2); float newLerp = (gradient.Stops[counter].Stop - (float)lerp) / (gradient.Stops[counter].Stop - gradient.Stops[counter + 1].Stop); applyAction(x, y, ColorHelper.Lerp(gradient.Stops[counter].Color, gradient.Stops[counter + 1].Color, newLerp)); } } }
/// <inheritdoc /> /// <summary> /// </summary> /// <param name="dt"></param> /// <param name="gameTime"></param> public override void Update(GameTime gameTime) { var dt = gameTime.ElapsedGameTime.TotalMilliseconds; // Tween to target Y positions Users.ForEach(user => { user.Y = MathHelper.Lerp(user.Y, user.TargetYPosition, (float)Math.Min(dt / 120, 1)); // Tween X Position based on if the scoreboard is hidden if (ConfigManager.ScoreboardVisible.Value) { var target = Team == MultiplayerTeam.Red ? 0 : WindowManager.Width - user.Width; user.X = MathHelper.Lerp(user.X, target, (float)Math.Min(dt / 120, 1)); } else { var target = Team == MultiplayerTeam.Red ? -user.Width - 10 : WindowManager.Width + user.Width + 10; user.X = MathHelper.Lerp(user.X, target, (float)Math.Min(dt / 90, 1)); } user.Visible = user.X >= -user.Width + 10; }); // Lerp team banner in and out if (TeamBanner != null) { var target = Team == MultiplayerTeam.Red ? 0 : WindowManager.Width - TeamBanner.Width; TeamBanner.X = MathHelper.Lerp(TeamBanner.X, target, (float)Math.Min(dt / 120, 1)); } base.Update(gameTime); }
public override void Update(GameTime gameTime) { PerformLoadingWheelRotation(); Button.Alpha = MathHelper.Lerp(Button.Alpha, Button.IsHovered ? 0.4f : 0f, (float)Math.Min(gameTime.ElapsedGameTime.TotalMilliseconds / 60, 1)); base.Update(gameTime); }
/// <summary> /// Handles the input for all pause input. /// </summary> /// <param name="gameTime"></param> private void HandlePauseInput(GameTime gameTime) { // Go back to editor if we're currently play testing. if (IsPlayTesting && (KeyboardManager.IsUniqueKeyPress(Keys.Escape) || KeyboardManager.CurrentState.IsKeyDown(ConfigManager.KeyPause.Value))) { if (AudioEngine.Track.IsPlaying) { AudioEngine.Track.Pause(); AudioEngine.Track.Seek(PlayTestAudioTime); } Exit(() => new EditorScreen(OriginalEditorMap)); } if (IsCalibratingOffset && (KeyboardManager.IsUniqueKeyPress(Keys.Escape) || KeyboardManager.CurrentState.IsKeyDown(ConfigManager.KeyPause.Value))) { OffsetConfirmDialog.Exit(this); } if (!IsPaused && (KeyboardManager.CurrentState.IsKeyDown(ConfigManager.KeyPause.Value) || KeyboardManager.CurrentState.IsKeyDown(Keys.Escape))) { Pause(gameTime); } // The user wants to resume their play. else if (IsPaused && (KeyboardManager.IsUniqueKeyPress(ConfigManager.KeyPause.Value) || KeyboardManager.IsUniqueKeyPress(Keys.Escape))) { if (ChatManager.IsActive) { ChatManager.ToggleChatOverlay(); return; } Pause(); TimePauseKeyHeld = 0; GameBase.Game.GlobalUserInterface.Cursor.Alpha = 0; } else { TimePauseKeyHeld = 0; var screenView = (GameplayScreenView)View; if (Failed || IsPlayComplete || IsPaused) { return; } // Properly fade in now. if (!screenView.FadingOnRestartKeyPress) { screenView.Transitioner.Alpha = MathHelper.Lerp(screenView.Transitioner.Alpha, 0, (float)Math.Min(gameTime.ElapsedGameTime.TotalMilliseconds / 120, 1)); } } }
/// <summary> /// </summary> /// <param name="gameTime"></param> public override void Update(GameTime gameTime) { if (!HasMap || OnlineManager.CurrentGame?.HostId == OnlineManager.Self.OnlineUser.Id) { DownloadButton.Alpha = MathHelper.Lerp(DownloadButton.Alpha, DownloadButton.IsHovered ? 0.3f : 0f, (float)Math.Min(gameTime.ElapsedGameTime.TotalMilliseconds / 60, 1)); } base.Update(gameTime); }
/// <summary> /// Rotates the loading wheel endlessly /// </summary> private void PerformLoadingWheelRotation() { if (LoadingWheel.Animations.Count != 0) { return; } var rotation = MathHelper.ToDegrees(LoadingWheel.Rotation); LoadingWheel.ClearAnimations(); LoadingWheel.Animations.Add(new Animation(AnimationProperty.Rotation, Easing.Linear, rotation, rotation + 360, 1000)); }
private void BuildRooms(int r1, int r2, float roomModifier) { int tileX = 0; int tileY = 0; float startAngle; float endAngle; float roomSize = roomModifier; //float mRadius; Point middle = new Point(tileMap.GetLength(0) / 2, tileMap.GetLength(1) / 2); for (float d = 0; d < 2 * Math.PI; d += .0001f) { startAngle = d; endAngle = startAngle + MathHelper.ToRadians(Game1.random.Next(3, 7)); // Close Room for (float a = startAngle; a < endAngle; a += .0001f) { tileX = (int)(Math.Cos(a) * ((r1 + r2) / roomSize)) + middle.X; tileY = (int)(Math.Sin(a) * ((r1 + r2) / roomSize)) + middle.Y; tileMap[tileX, tileY] = 3; tileX = (int)(Math.Cos(a) * r2) + middle.X; tileY = (int)(Math.Sin(a) * r2) + middle.Y; tileMap[tileX, tileY] = 3; } float roomOpening = ((startAngle + endAngle) / 2); for (float r = roomOpening; r <= roomOpening + MathHelper.ToRadians(.5f); r += .001f) { tileX = (int)(Math.Cos(r) * ((r1 + r2) / roomSize)) + middle.X; tileY = (int)(Math.Sin(r) * ((r1 + r2) / roomSize)) + middle.Y; tileMap[tileX, tileY] = floorTile; } BuildWall(r1, r2, roomSize, startAngle); BuildWall(r1, r2, roomSize, endAngle); d = endAngle + MathHelper.ToRadians(3); } //tileMap[tileX, tileY] = 3; }
protected override void Update(GameTime gameTime) { G.update_input(); switch (state) { case OnlineState.AskingRole: if (G.ks.IsKeyDown(Keys.H)) { onlineGame = new HostOnlineGame(6666); state = OnlineState.Connecting; onlineGame.OnConnection += OnlineGame_OnConnection; imMisterH = true; } else if (G.ks.IsKeyDown(Keys.J)) { onlineGame = new JoinOnlineGame("127.0.0.1", 6666); state = OnlineState.Connecting; onlineGame.OnConnection += OnlineGame_OnConnection; imMisterH = false; } break; case OnlineState.Connecting: Window.Title = "connecting"; //on connection invoke for the characters //start the background thread for the two player // change state for playing break; case OnlineState.Playing: onlineGame.hostChar.update(); onlineGame.joinChar.update(); if (G.ks.IsKeyDown(Keys.A)) { G.zoom = MH.Lerp(G.zoom, 0.1f, 0.01f); } if (G.ks.IsKeyDown(Keys.D)) { G.zoom = MH.Lerp(G.zoom, 5f, 0.001f); } break; } base.Update(gameTime); }
/// <inheritdoc /> /// <summary> /// </summary> /// <param name="gameTime"></param> public override void Update(GameTime gameTime) { var dt = gameTime.ElapsedGameTime.TotalMilliseconds; // Gradually fade out the line. foreach (var line in LineObjectPool) { line.Alpha = MathHelper.Lerp(line.Alpha, 0, (float)Math.Min(dt / 960, 1)); } // Tween the chevron to the last hit if (CurrentLinePoolIndex != -1) { LastHitCheveron.X = MathHelper.Lerp(LastHitCheveron.X, LineObjectPool[CurrentLinePoolIndex].X, (float)Math.Min(dt / 360, 1)); } base.Update(gameTime); }
public WindowsPhoneSample(Microsoft.Xna.Framework.Game game) : base(game) { GraphicsScreen.ClearBackground = true; GraphicsScreen.BackgroundColor = Color.CornflowerBlue; // Set a fixed camera. var projection = new PerspectiveProjection(); projection.SetFieldOfView( MathHelper.ToRadians(30), GraphicsService.GraphicsDevice.Viewport.AspectRatio, 1f, 1000.0f); Vector3F cameraTarget = new Vector3F(0, 1, 0); Vector3F cameraPosition = new Vector3F(0, 12, 0); Vector3F cameraUpVector = new Vector3F(0, 0, -1); GraphicsScreen.CameraNode = new CameraNode(new Camera(projection)) { View = Matrix44F.CreateLookAt(cameraPosition, cameraTarget, cameraUpVector), }; // We use the accelerometer to control the camera view. The accelerometer registers every // little change, but we do not want a shaky camera. We can use a low-pass filter to smooth // the sensor signal. _lowPassFilter = new LowPassFilter(new Vector3F(0, -1, 0)) { TimeConstant = 0.15f, // Let's try a time constant of 0.15 seconds. // When increasing the time constant the camera becomes more stable, // but also slower. }; // Enable touch gestures _originalEnabledGestures = TouchPanel.EnabledGestures; TouchPanel.EnabledGestures = GestureType.Tap // Tap is used to drop new bodies. | GestureType.Flick // Flick creates an explosion. | GestureType.Hold // Hold to clear the scene. | GestureType.Pinch; // Pinch can be used to zoom in or out. InitializePhysics(); }
/// <inheritdoc /> /// <summary> /// </summary> /// <param name="gameTime"></param> public override void Update(GameTime gameTime) { HandleWaitingForPlayersDialog(); CheckIfNewScoreboardUsers(); HandlePlayCompletion(gameTime); BattleRoyaleBackgroundAlerter?.Update(gameTime); Screen.Ruleset?.Update(gameTime); Container?.Update(gameTime); // Update the position and size of the grade display. GradeDisplay.X = AccuracyDisplay.X - AccuracyDisplay.Width - 8; GradeDisplay.Height = AccuracyDisplay.Height; GradeDisplay.UpdateWidth(); if (SpectatorDialog != null) { SpectatorDialog.Alpha = MathHelper.Lerp(SpectatorDialog.Alpha, Screen.IsPaused ? 1 : 0, (float)Math.Min(gameTime.ElapsedGameTime.TotalMilliseconds / 100, 1)); } }
public SpaceStation(int radius, string name) { InitializeMap(radius); entityName = name; GameData <Room> roomData = new GameData <Room>(); roomData.folderPath = @"Saves\Rooms\"; Room tempRoom = roomData.LoadObjectData("Room1"); rooms.Add(tempRoom); BuildRoomsOnRing(radius / 4, MathHelper.ToRadians(20)); BuildRoomsOnRing(radius / 2, MathHelper.ToRadians(10)); position = new Vector2(); nodeMesh = new World.NodeMesh(); InitializeCellSpacePartition(); InitializeILocalCellPartition(); }
public override void Update(System.TimeSpan time) { base.Update(time); _angle -= MathHelper.ToRadians(0.5f); if (_angle < 0.0f) { _angle += MathHelper.TwoPi; } if (SadConsole.Global.KeyboardState.IsKeyReleased(Microsoft.Xna.Framework.Input.Keys.T)) { toggle = !toggle; Clear(); } if (SadConsole.Global.KeyboardState.IsKeyReleased(Microsoft.Xna.Framework.Input.Keys.B)) { reader1.UseBlockMode = !reader1.UseBlockMode; } }
/// <summary> /// Zooms the camera when Pinch/Stretch is detected. /// </summary> /// <param name="pinchGesture">The pinch gesture.</param> private void ZoomCamera(GestureSample pinchGesture) { // Get the current and the previous location of the two fingers. Vector2 p1New = pinchGesture.Position; Vector2 p1Old = pinchGesture.Position - pinchGesture.Delta; Vector2 p2New = pinchGesture.Position2; Vector2 p2Old = pinchGesture.Position2 - pinchGesture.Delta2; // Get the distance between the current and the previous locations. float dNew = Vector2.Distance(p1New, p2New); float dOld = Vector2.Distance(p1Old, p2Old); // Use the ratio between old and new distance to scale the camera distance. float scale = dOld / dNew; if (!Numeric.IsNaN(scale)) { _cameraDistance *= scale; _cameraDistance = MathHelper.Clamp(_cameraDistance, MinCameraDistance, MaxCameraDistance); } }
/// <summary> /// Handles the input for all pause input. /// </summary> /// <param name="gameTime"></param> private void HandlePauseInput(GameTime gameTime) { if (!IsPaused && (KeyboardManager.CurrentState.IsKeyDown(ConfigManager.KeyPause.Value) || KeyboardManager.CurrentState.IsKeyDown(Keys.Escape))) { Pause(gameTime); } // The user wants to resume their play. else if (IsPaused && (KeyboardManager.IsUniqueKeyPress(ConfigManager.KeyPause.Value) || KeyboardManager.IsUniqueKeyPress(Keys.Escape))) { if (ChatManager.IsActive) { ChatManager.ToggleChatOverlay(); return; } Pause(); TimePauseKeyHeld = 0; GameBase.Game.GlobalUserInterface.Cursor.Alpha = 0; } else { TimePauseKeyHeld = 0; var screenView = (GameplayScreenView)View; if (Failed || IsPlayComplete || IsPaused) { return; } // Properly fade in now. if (!screenView.FadingOnRestartKeyPress) { screenView.Transitioner.Alpha = MathHelper.Lerp(screenView.Transitioner.Alpha, 0, (float)Math.Min(gameTime.ElapsedGameTime.TotalMilliseconds / 120, 1)); } } }
/// <summary> /// Initializes the physics simulation. /// </summary> private void InitializePhysics() { // Add a gravity force. _gravity = new Gravity { Acceleration = new Vector3F(0, -GravityAcceleration, 0) }; Simulation.ForceEffects.Add(_gravity); // Add a damping force. Simulation.ForceEffects.Add(new Damping()); // Add a few spheres. Simulation.RigidBodies.Add(new RigidBody(new SphereShape(0.3f)) { Pose = new Pose(new Vector3F(0, 1, 0)), }); Simulation.RigidBodies.Add(new RigidBody(new SphereShape(0.2f)) { Pose = new Pose(new Vector3F(1, 1, 0)), }); Simulation.RigidBodies.Add(new RigidBody(new SphereShape(0.4f)) { Pose = new Pose(new Vector3F(0, 1, 2)), }); // Add ragdoll. AddRagdoll(1, new Vector3F(0, 2, 0)); // The Simulation performs 2 sub-time-steps per frame because we have set // the FixedTimeStep of the simulation to 1/60 s and the TargetElapsedTime of the game // is 1/30 s (30 Hz). In the event SubTimeStepFinished, we call our method // HandleBreakableJoints() to check the forces in the joints and disable constraints where // the force is too large. // Instead, we could also call HandleBreakableJoints() in the Update() method of the game // but then it is only called with the 30 Hz of the game. It is more accurate to call the // method at the end of each simulation sub-time-step (60 Hz). Simulation.SubTimeStepFinished += (s, e) => HandleBreakableJoints(); // Add 6 planes that keep the bodies inside the visible area. The exact positions and angles // have been determined by experimentation. var groundPlane = new RigidBody(new PlaneShape(Vector3F.UnitY, 0)) { Name = "GroundPlane", MotionType = MotionType.Static, }; Simulation.RigidBodies.Add(groundPlane); var nearPlane = new RigidBody(new PlaneShape(-Vector3F.UnitY, -8)) { Name = "NearPlane", MotionType = MotionType.Static, }; Simulation.RigidBodies.Add(nearPlane); var leftPlane = new RigidBody(new PlaneShape(Matrix33F.CreateRotationZ(MathHelper.ToRadians(-22f)) * Vector3F.UnitX, -4.8f)) { Name = "LeftPlane", MotionType = MotionType.Static, }; Simulation.RigidBodies.Add(leftPlane); var rightPlane = new RigidBody(new PlaneShape(Matrix33F.CreateRotationZ(MathHelper.ToRadians(22f)) * -Vector3F.UnitX, -4.8f)) { Name = "RightPlane", MotionType = MotionType.Static, }; Simulation.RigidBodies.Add(rightPlane); var topPlane = new RigidBody(new PlaneShape(Matrix33F.CreateRotationX(MathHelper.ToRadians(14f)) * Vector3F.UnitZ, -3f)) { Name = "TopPlane", MotionType = MotionType.Static, }; Simulation.RigidBodies.Add(topPlane); var bottomPlane = new RigidBody(new PlaneShape(Matrix33F.CreateRotationX(MathHelper.ToRadians(-14f)) * -Vector3F.UnitZ, -3f)) { Name = "BottomPlane", MotionType = MotionType.Static, }; Simulation.RigidBodies.Add(bottomPlane); }
public override void Draw() { if (raycast.points != null && inUse && charge > 0) { for (int i = 0; i < raycast.points.Count; i++) { if (i < 1) { ParticleSystem.AddParticle(raycast.points[i].ToVector2(), new Systems.Particle(position, 1, 0, 1f, 0, 0, Color.Orange) { fadeRate = .95f, maxDampening = 99, minDampening = 95, minSpeed = .01f, minAngle = MathHelper.ToDegrees(rotation) - 3, maxAngle = MathHelper.ToDegrees(rotation) + 3, size = .2f, minSize = .01f, sizeRate = .99f, maxSize = 5, mass = .3f, }); } ParticleSystem.AddParticle(raycast.points[i].ToVector2(), new Systems.Particle(position, 1, 0, 1f, 0, 0, Color.Yellow) { fadeRate = .95f, maxDampening = 99, minDampening = 99, minSpeed = .01f, minAngle = MathHelper.ToDegrees(rotation) - 90, maxAngle = MathHelper.ToDegrees(rotation) + 90, size = .05f, minSize = .01f, sizeRate = .95f, maxSize = 5 }); ParticleSystem.AddParticle(raycast.points[i].ToVector2(), new Systems.Particle(position, 1, 0, 1f, 0, 0, Color.LightBlue) { fadeRate = .95f, maxDampening = 99, minDampening = 99, minSpeed = .01f, minAngle = MathHelper.ToDegrees(rotation) - 90, maxAngle = MathHelper.ToDegrees(rotation) + 90, size = .09f, minSize = .01f, sizeRate = .95f, maxSize = 5, mass = 1.2f }); ParticleSystem.AddParticle(raycast.points[i].ToVector2(), new Systems.Particle(position, 1, 0, 1f, 0, 0, Color.Orange) { fadeRate = .95f, maxDampening = 95, minDampening = 90, minSpeed = .01f, minAngle = MathHelper.ToDegrees(rotation) - 3, maxAngle = MathHelper.ToDegrees(rotation) + 3, size = .2f, minSize = .01f, sizeRate = .99f, maxSize = 5, mass = 1.5f, }); } } //base.Draw(spriteBatch); }
public SplitScreenSample(Microsoft.Xna.Framework.Game game) : base(game) { SampleFramework.IsMouseVisible = false; _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.ActiveCameraNode = 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 Vector3(0, 0, -2)))); GameObjectService.Objects.Add(new StaticObject(Services, "Barrier/Cylinder", 0.9f, new Pose(new Vector3(3, 0, 0), Quaternion.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++) { Vector3 position = new Vector3(random.NextFloat(-3, -8), 0, random.NextFloat(0, -5)); Matrix orientation = Matrix.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))); } }
public SkySample(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 Vector3(0, 0, -2)))); GameObjectService.Objects.Add(new StaticObject(Services, "Barrier/Cylinder", 0.9f, new Pose(new Vector3(3, 0, 0), Quaternion.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++) { Vector3 position = new Vector3(random.NextFloat(-3, -8), 0, random.NextFloat(0, -5)); Matrix orientation = Matrix.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 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, }); }
/// <overloads> /// <summary> /// Gets a the bounds of the specified object relative to the viewport. /// </summary> /// </overloads> /// /// <summary> /// Gets a the bounds of the specified geometric object relative to the viewport. /// </summary> /// <param name="cameraNode">The camera node.</param> /// <param name="geometricObject">The geometric object.</param> /// <returns> /// The bounds (left, top, right, bottom) where each entry is in the range [0, 1]. /// </returns> /// <exception cref="ArgumentNullException"> /// <paramref name="cameraNode"/> or <paramref name="geometricObject"/> is /// <see langword="null"/>. /// </exception> internal static Vector4F GetBounds(CameraNode cameraNode, IGeometricObject geometricObject) { // Notes: // Do not call this GetBounds() method for spheres. Use the other overload for spheres. // // At first this problem seems trivial, we only have to get the support // points of the geometric object's shape in the directions of the frustum // plane normal vectors. The we project these points to the near plane... // But this does not work because which can be seen if you draw simple // drop down sketch. Actually each eye ray has its own direction therefore // it has its normal and its own support direction! if (cameraNode == null) { throw new ArgumentNullException("cameraNode"); } if (geometricObject == null) { throw new ArgumentNullException("geometricObject"); } Debug.Assert(!(geometricObject.Shape is SphereShape), "Call a different GetBounds() overload for spheres!"); // Projection properties. var camera = cameraNode.Camera; var projection = camera.Projection; float near = projection.Near; float left = projection.Left; float right = projection.Right; float width = projection.Width; float top = projection.Top; float bottom = projection.Bottom; float height = projection.Height; // Get AABB in view space. Pose localToViewPose = cameraNode.PoseWorld.Inverse * geometricObject.Pose; Aabb aabb = geometricObject.Shape.GetAabb(geometricObject.Scale, localToViewPose); // Is the AABB in front of the near plane (= totally clipped)? if (aabb.Minimum.Z >= -near) { return(new Vector4F(0)); } // Does the AABB contain the origin? if (GeometryHelper.HaveContact(aabb, Vector3F.Zero)) { return(new Vector4F(0, 0, 1, 1)); } // Project the AABB far face to the near plane. Vector2F min; min.X = aabb.Minimum.X / -aabb.Minimum.Z * near; min.Y = aabb.Minimum.Y / -aabb.Minimum.Z * near; Vector2F max; max.X = aabb.Maximum.X / -aabb.Minimum.Z * near; max.Y = aabb.Maximum.Y / -aabb.Minimum.Z * near; // If the AABB z extent overlaps the origin, some results are invalid. if (aabb.Maximum.Z > -Numeric.EpsilonF) { if (aabb.Minimum.X < 0) { min.X = left; } if (aabb.Maximum.X > 0) { max.X = right; } if (aabb.Minimum.Y < 0) { min.Y = bottom; } if (aabb.Maximum.Y > 0) { max.Y = top; } } else { // The AABB near face is also in front. Project AABB near face to near plane // and take the most extreme. min.X = Math.Min(min.X, aabb.Minimum.X / -aabb.Maximum.Z * near); min.Y = Math.Min(min.Y, aabb.Minimum.Y / -aabb.Maximum.Z * near); max.X = Math.Max(max.X, aabb.Maximum.X / -aabb.Maximum.Z * near); max.Y = Math.Max(max.Y, aabb.Maximum.Y / -aabb.Maximum.Z * near); } Vector4F bounds; bounds.X = (min.X - left) / width; bounds.Y = (top - max.Y) / height; bounds.Z = (max.X - left) / width; bounds.W = (top - min.Y) / height; bounds.X = MathHelper.Clamp(bounds.X, 0, 1); bounds.Y = MathHelper.Clamp(bounds.Y, 0, 1); bounds.Z = MathHelper.Clamp(bounds.Z, bounds.X, 1); bounds.W = MathHelper.Clamp(bounds.W, bounds.Y, 1); return(bounds); }
/// <summary> /// Gets the bounds of the specified sphere relative to the viewport. /// </summary> /// <param name="cameraNode">The camera node.</param> /// <param name="positionWorld">The sphere center in world space.</param> /// <param name="radius">The sphere radius.</param> /// <returns> /// The bounds (left, top, right, bottom) where each entry is in the range [0, 1]. /// </returns> /// <exception cref="ArgumentNullException"> /// <paramref name="cameraNode"/> is <see langword="null"/>. /// </exception> internal static Vector4F GetBounds(CameraNode cameraNode, Vector3F positionWorld, float radius) { var camera = cameraNode.Camera; var projection = camera.Projection; float near = projection.Near; float left = projection.Left; float width = projection.Width; float top = projection.Top; float height = projection.Height; Vector3F l = cameraNode.PoseWorld.ToLocalPosition(positionWorld); float r = radius; // Default bounds (left, top, right, bottom) var bounds = new Vector4F(0, 0, 1, 1); // ----- Solve for N = (x, 0, z). // Discriminant already divided by 4: float d = (r * r * l.X * l.X - (l.X * l.X + l.Z * l.Z) * (r * r - l.Z * l.Z)); if (d > 0) { // Camera is outside the sphere. float rootD = (float)Math.Sqrt(d); // Now check two possible solutions (+/- rootD): float nx1 = (r * l.X + rootD) / (l.X * l.X + l.Z * l.Z); float nx2 = (r * l.X - rootD) / (l.X * l.X + l.Z * l.Z); float nz1 = (r - nx1 * l.X) / l.Z; float nz2 = (r - nx2 * l.X) / l.Z; // Compute tangent position (px, 0, pz) on the sphere. float pz1 = (l.X * l.X + l.Z * l.Z - r * r) / (l.Z - (nz1 / nx1) * l.X); float pz2 = (l.X * l.X + l.Z * l.Z - r * r) / (l.Z - (nz2 / nx2) * l.X); if (pz1 < 0) { // Plane (nx1, 0, nz1) is within camera frustum. float px = -pz1 * nz1 / nx1; float x = nz1 * near / nx1; // x coordinate on the near plane. float boundsX = (x - left) / width; // Value relative to viewport. (0 = left, 1 = right) // Shrink the scissor rectangle on the left or on the right side. if (px < l.X) { bounds.X = Math.Max(bounds.X, boundsX); } else { bounds.Z = Math.Min(bounds.Z, boundsX); } } if (pz2 < 0) { float px = -pz2 * nz2 / nx2; float x = nz2 * near / nx2; float scissorX = (x - left) / width; if (px < l.X) { bounds.X = Math.Max(bounds.X, scissorX); } else { bounds.Z = Math.Min(bounds.Z, scissorX); } } } // ----- Solve for N = (0, y, z) first. d = (r * r * l.Y * l.Y - (l.Y * l.Y + l.Z * l.Z) * (r * r - l.Z * l.Z)); if (d > 0) { // Camera is outside the sphere. float rootD = (float)Math.Sqrt(d); float ny1 = (r * l.Y + rootD) / (l.Y * l.Y + l.Z * l.Z); float ny2 = (r * l.Y - rootD) / (l.Y * l.Y + l.Z * l.Z); float nz1 = (r - ny1 * l.Y) / l.Z; float nz2 = (r - ny2 * l.Y) / l.Z; float pz1 = (l.Y * l.Y + l.Z * l.Z - r * r) / (l.Z - (nz1 / ny1) * l.Y); float pz2 = (l.Y * l.Y + l.Z * l.Z - r * r) / (l.Z - (nz2 / ny2) * l.Y); if (pz1 < 0) { float py = -pz1 * nz1 / ny1; float y = nz1 * near / ny1; float scissorY = -(y - top) / height; if (py > l.Y) { bounds.Y = Math.Max(bounds.Y, scissorY); } else { bounds.W = Math.Min(bounds.W, scissorY); } } if (pz2 < 0) { float py = -pz2 * nz2 / ny2; float y = nz2 * near / ny2; float scissorY = -(y - top) / height; if (py > l.Y) { bounds.Y = Math.Max(bounds.Y, scissorY); } else { bounds.W = Math.Min(bounds.W, scissorY); } } } bounds.X = MathHelper.Clamp(bounds.X, 0, 1); bounds.Y = MathHelper.Clamp(bounds.Y, 0, 1); bounds.Z = MathHelper.Clamp(bounds.Z, bounds.X, 1); bounds.W = MathHelper.Clamp(bounds.W, bounds.Y, 1); return(bounds); }
private void UpdateSky() { // Update ephemeris model. #if XBOX _ephemeris.Time = new DateTimeOffset(_time.Ticks, TimeSpan.Zero); #else _ephemeris.Time = _time; #endif _ephemeris.Update(); // Update rotation of milky way. We also need to add an offset because the // cube map texture is rotated. _milkyWayNode.PoseWorld = new Pose( (Matrix33F)_ephemeris.EquatorialToWorld.Minor * Matrix33F.CreateRotationZ(ConstantsF.PiOver2 + -0.004f) * Matrix33F.CreateRotationX(ConstantsF.PiOver2 + -0.002f)); // Update rotation of stars. _starfieldNode.PoseWorld = new Pose((Matrix33F)_ephemeris.EquatorialToWorld.Minor); // Update direction of sun. SunDirection = (Vector3F)_ephemeris.SunDirectionRefracted; var sunUp = SunDirection.Orthonormal1; _sunNode.LookAt(SunDirection, sunUp); // Update direction of moon. var moonDirection = (Vector3F)_ephemeris.MoonPosition.Normalized; var moonUp = (Vector3F)_ephemeris.EquatorialToWorld.TransformDirection(Vector3D.Up); _moonNode.LookAt(moonDirection, moonUp); // The moon needs to know the sun position and brightness to compute the moon phase. _moonNode.SunDirection = (Vector3F)_ephemeris.SunPosition.Normalized; _moonNode.SunLight = Ephemeris.ExtraterrestrialSunlight * SunlightScale; // The ScatteringSky needs the sun direction and brightness to compute the sky colors. _scatteringSkyNode.SunDirection = SunDirection; _scatteringSkyNode.SunColor = Ephemeris.ExtraterrestrialSunlight * ScatteringSkyLightScale; // Update the light directions. _sunlightNode.LookAt(-SunDirection, sunUp); _moonlightNode.LookAt(-moonDirection, moonUp); // The ScatteringSkyNode can compute the actual sunlight. SunLight = _scatteringSkyNode.GetSunlight(); // Undo the ScatteringSkyLightScale and apply a custom scale for the sunlight. SunLight = SunLight / ScatteringSkyLightScale * SunlightScale; // The ScatteringSkyNode can also compute the ambient light by sampling the // sky hemisphere. AmbientLight = _scatteringSkyNode.GetAmbientLight(256); AmbientLight = AmbientLight / ScatteringSkyLightScale * SunlightScale; // Desaturate the ambient light to avoid very blue shadows. AmbientLight = InterpolationHelper.Lerp( new Vector3F(Vector3F.Dot(AmbientLight, GraphicsHelper.LuminanceWeights)), AmbientLight, 0.5f); // The Ephemeris model can compute the actual moonlight. Vector3F moonlight, moonAmbient; Ephemeris.GetMoonlight( _scatteringSkyNode.ObserverAltitude, 2.2f, _ephemeris.MoonPosition, (float)_ephemeris.MoonPhaseAngle, out moonlight, out moonAmbient); moonlight *= MoonlightScale; moonAmbient *= MoonlightScale; // Scale sun light to 0 at horizon. var directionalLightColor = SunLight; directionalLightColor *= MathHelper.Clamp(SunDirection.Y / 0.1f, 0, 1); var directionalLight = ((DirectionalLight)_sunlightNode.Light); directionalLight.Color = directionalLightColor; ((DirectionalLight)_moonlightNode.Light).Color = moonlight; ((AmbientLight)_ambientLightNode.Light).Color = AmbientLight + moonAmbient + LightPollution; // Use the sunlight color to create a bright sun disk. var sunDiskColor = SunLight; sunDiskColor.TryNormalize(); _sunNode.GlowColor0 = sunDiskColor * Ephemeris.ExtraterrestrialSunlight.Length * SunlightScale * 10; if (_enableClouds) { // Update lighting info of cloud layer nodes. _cloudLayerNode0.SunDirection = SunDirection; _cloudLayerNode0.SunLight = SunLight; _cloudLayerNode0.AmbientLight = AmbientLight; // The second cloud layer uses simple unlit clouds (only ambient lighting). _cloudLayerNode1.SunDirection = SunDirection; _cloudLayerNode1.SunLight = Vector3F.Zero; _cloudLayerNode1.AmbientLight = AmbientLight + SunLight; // Use the cloud map as the texture for the directional light to create cloud shadows. if (EnableCloudShadows) { directionalLight.Texture = _cloudLayerNode0.CloudMap.Texture; } else { directionalLight.Texture = null; } // Compute a texture offset so that the current sun position and the projected cloud // shadows match. // Since sky dome is always centered on the camera, position the sunlight node in // line with the camera. var cameraPosition = _cameraObject.CameraNode.PoseWorld.Position; var upVector = Vector3F.AreNumericallyEqual(SunDirection, Vector3F.UnitZ) ? Vector3F.UnitY : Vector3F.UnitZ; _sunlightNode.LookAt(cameraPosition + SunDirection, cameraPosition, upVector); // Choose a scale for the cloud shadows. directionalLight.TextureScale = new Vector2F(-1000); // Get the scaled texture offset for the sun direction. directionalLight.TextureOffset = _cloudLayerNode0.GetTextureCoordinates(SunDirection) * directionalLight.TextureScale; } // The ScatteringSkyNode can also estimate a fog color by sampling the horizon colors. Vector3F fogColor = _scatteringSkyNode.GetFogColor(256, FogSampleAngle); // Desaturate the fog color. fogColor = InterpolationHelper.Lerp( new Vector3F(Vector3F.Dot(fogColor, GraphicsHelper.LuminanceWeights)), fogColor, FogSaturation); // Find any FogNode in the scene and update its fog color. foreach (var fogNode in ((Scene)_scene).GetSubtree().OfType <FogNode>()) { var fog = fogNode.Fog; fog.Color0 = fog.Color1 = new Vector4F(fogColor, 1); fog.ScatteringSymmetry = FogScatteringSymmetry; } // TODO: If the fog is dense, reduce the direct light and increase the ambient light. }
public void Draw(UltimaBatcher2D batcher, int x, int y) { bool removeEffects = false; if (Timer < Engine.Ticks) { if (CurrentCount == 0) { return; } removeEffects = true; } else if (Type == 0xFF || Type == 0xFE) { return; } uint passed = Engine.Ticks - LastTick; if (passed > 7000) { LastTick = Engine.Ticks; passed = 25; } bool windChanged = false; if (WindTimer < Engine.Ticks) { if (WindTimer == 0) { windChanged = true; } WindTimer = Engine.Ticks + (uint)(RandomHelper.GetValue(7, 13) * 1000); sbyte lastWind = Wind; Wind = (sbyte)RandomHelper.GetValue(0, 4); if (RandomHelper.GetValue(0, 2) != 0) { Wind *= -1; } if (Wind < 0 && lastWind > 0) { Wind = 0; } else if (Wind > 0 && lastWind < 0) { Wind = 0; } if (lastWind != Wind) { windChanged = true; } } //switch ((WEATHER_TYPE) Type) //{ // case WEATHER_TYPE.WT_RAIN: // case WEATHER_TYPE.WT_FIERCE_STORM: // // TODO: set color // break; // case WEATHER_TYPE.WT_SNOW: // case WEATHER_TYPE.WT_STORM: // // TODO: set color // break; // default: // break; //} Point winpos = Engine.Profile.Current.GameWindowPosition; Point winsize = Engine.Profile.Current.GameWindowSize; for (int i = 0; i < Effects.Count; i++) { var effect = Effects[i]; if (effect.X < x || effect.X > x + winsize.X || effect.Y < y || effect.Y > y + winsize.Y) { if (removeEffects) { Effects.RemoveAt(i--); if (CurrentCount > 0) { CurrentCount--; } else { CurrentCount = 0; } continue; } effect.X = x + RandomHelper.GetValue(0, winsize.X); effect.Y = y + RandomHelper.GetValue(0, winsize.Y); } switch ((WEATHER_TYPE)Type) { case WEATHER_TYPE.WT_RAIN: float scaleRation = effect.ScaleRatio; effect.SpeedX = -4.5f - scaleRation; effect.SpeedY = 5.0f + scaleRation; break; case WEATHER_TYPE.WT_FIERCE_STORM: effect.SpeedX = Wind; effect.SpeedY = 6.0f; break; case WEATHER_TYPE.WT_SNOW: case WEATHER_TYPE.WT_STORM: if (Type == (byte)WEATHER_TYPE.WT_SNOW) { effect.SpeedX = Wind; effect.SpeedY = 1.0f; } else { effect.SpeedX = Wind * 1.5f; effect.SpeedY = 1.5f; } if (windChanged) { effect.SpeedAngle = MathHelper.ToDegrees((float)Math.Atan2(effect.SpeedX, effect.SpeedY)); effect.SpeedMagnitude = (float)Math.Sqrt(Math.Pow(effect.SpeedX, 2) + Math.Pow(effect.SpeedY, 2)); } float speed_angle = effect.SpeedAngle; float speed_magnitude = effect.SpeedMagnitude; speed_magnitude += effect.ScaleRatio; speed_angle += SinOscillate(0.4f, 20, Engine.Ticks + effect.ID); var rad = MathHelper.ToRadians(speed_angle); effect.SpeedX = speed_magnitude * (float)Math.Sin(rad); effect.SpeedY = speed_magnitude * (float)Math.Cos(rad); break; default: break; } float speedOffset = passed / SimulationRation; switch ((WEATHER_TYPE)Type) { case WEATHER_TYPE.WT_RAIN: case WEATHER_TYPE.WT_FIERCE_STORM: int oldX = (int)effect.X; int oldY = (int)effect.Y; float ofsx = effect.SpeedX * speedOffset; float ofsy = effect.SpeedY * speedOffset; effect.X += ofsx; effect.Y += ofsy; const float MAX_OFFSET_XY = 5.0f; if (ofsx >= MAX_OFFSET_XY) { oldX = (int)(effect.X - MAX_OFFSET_XY); } else if (ofsx <= -MAX_OFFSET_XY) { oldX = (int)(effect.X + MAX_OFFSET_XY); } if (ofsy >= MAX_OFFSET_XY) { oldY = (int)(effect.Y - MAX_OFFSET_XY); } else if (oldY <= -MAX_OFFSET_XY) { oldY = (int)(effect.Y + MAX_OFFSET_XY); } batcher.DrawLine(Textures.GetTexture(Color.Gray), x + oldX, y + oldY, x + (int)effect.X, y + (int)effect.Y, 0, 0); break; case WEATHER_TYPE.WT_SNOW: case WEATHER_TYPE.WT_STORM: effect.X += effect.SpeedX * speedOffset; effect.Y += effect.SpeedY * speedOffset; batcher.Draw2D(Textures.GetTexture(Color.White), x + (int)effect.X, y + (int)effect.Y, 2, 2, ref _hueVector); break; default: break; } } LastTick = Engine.Ticks; }
private float SinOscillate(float freq, int range, uint current_tick) { float anglef = (float)((int)((current_tick / 2.7777f) * freq) % 360); return(Math.Sign(MathHelper.ToRadians(anglef)) * range); }
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 Vector3(0, 0, -2)))); GameObjectService.Objects.Add(new StaticObject(Services, "Barrier/Cylinder", 0.9f, new Pose(new Vector3(3, 0, 0), Quaternion.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++) { Vector3 position = new Vector3(random.NextFloat(-3, -8), 0, random.NextFloat(0, -5)); Matrix orientation = Matrix.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 Vector3(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. }
private bool _cullingEnabled = true; // True to use frustum culling. False to disable frustum culling. public FrustumCullingSample(Microsoft.Xna.Framework.Game game) : base(game) { GraphicsScreen.ClearBackground = true; GraphicsScreen.BackgroundColor = Color.CornflowerBlue; // The top-down camera. var orthographicProjection = new OrthographicProjection(); orthographicProjection.Set( LevelSize * 1.1f * GraphicsService.GraphicsDevice.Viewport.AspectRatio, LevelSize * 1.1f, 1, 10000f); var topDownCamera = new Camera(orthographicProjection); _topDownCameraNode = new CameraNode(topDownCamera) { View = Matrix44F.CreateLookAt(new Vector3F(0, 1000, 0), new Vector3F(0, 0, 0), -Vector3F.UnitZ), }; // The perspective camera moving through the scene. var perspectiveProjection = new PerspectiveProjection(); perspectiveProjection.SetFieldOfView( MathHelper.ToRadians(45), GraphicsService.GraphicsDevice.Viewport.AspectRatio, 1, 500); var sceneCamera = new Camera(perspectiveProjection); _sceneCameraNode = new CameraNode(sceneCamera); // Initialize collision detection. // We use one collision domain that manages all objects. _domain = new CollisionDomain(new CollisionDetection()) { // We exchange the default broad phase with a DualPartition. The DualPartition // has special support for frustum culling. BroadPhase = new DualPartition <CollisionObject>(), }; // Create a lot of random objects and add them to the collision domain. RandomHelper.Random = new Random(12345); for (int i = 0; i < NumberOfObjects; i++) { // A real scene consists of a lot of complex objects such as characters, vehicles, // buildings, lights, etc. When doing frustum culling we need to test each objects against // the viewing frustum. If it intersects with the viewing frustum, the object is visible // from the camera's point of view. However, in practice we do not test the exact object // against the viewing frustum. Each objects is approximated by a simpler shape. In our // example, we assume that each object is approximated with an oriented bounding box. // (We could also use an other shape, such as a bounding sphere.) // Create a random box. Shape randomShape = new BoxShape(RandomHelper.Random.NextVector3F(1, 10)); // Create a random position. Vector3F randomPosition; randomPosition.X = RandomHelper.Random.NextFloat(-LevelSize / 2, LevelSize / 2); randomPosition.Y = RandomHelper.Random.NextFloat(0, 2); randomPosition.Z = RandomHelper.Random.NextFloat(-LevelSize / 2, LevelSize / 2); // Create a random orientation. QuaternionF randomOrientation = RandomHelper.Random.NextQuaternionF(); // Create object and add it to collision domain. var geometricObject = new GeometricObject(randomShape, new Pose(randomPosition, randomOrientation)); var collisionObject = new CollisionObject(geometricObject) { CollisionGroup = 0, }; _domain.CollisionObjects.Add(collisionObject); } // Per default, the collision domain computes collision between all objects. // In this sample we do not need this information and disable it with a collision // filter. // In a real application, we would use this collision information for rendering, // for example, to find out which lights overlap with which meshes, etc. var filter = new CollisionFilter(); // Disable collision between objects in collision group 0. filter.Set(0, 0, false); _domain.CollisionDetection.CollisionFilter = filter; // Start with the top-down camera. GraphicsScreen.CameraNode = _topDownCameraNode; // We will collect a few statistics for debugging. Profiler.SetFormat("NoCull", 1000, "Time in ms to submit DebugRenderer draw jobs without frustum culling."); Profiler.SetFormat("WithCull", 1000, "Time in ms to submit DebugRenderer draw jobs with frustum culling."); }