Ejemplo n.º 1
0
        /// <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);
        }
Ejemplo n.º 2
0
        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);
        }
Ejemplo n.º 3
0
        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);
        }
Ejemplo n.º 4
0
        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();
        }
Ejemplo n.º 5
0
        /// <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));
                }
            }
        }
Ejemplo n.º 6
0
        /// <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);
        }
Ejemplo n.º 7
0
        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);
        }
Ejemplo n.º 8
0
        /// <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));
                }
            }
        }
Ejemplo n.º 9
0
        /// <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);
        }
Ejemplo n.º 10
0
        /// <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));
        }
Ejemplo n.º 11
0
        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;
        }
Ejemplo n.º 12
0
        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);
        }
Ejemplo n.º 13
0
        /// <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);
        }
Ejemplo n.º 14
0
        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();
        }
Ejemplo n.º 15
0
        /// <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));
            }
        }
Ejemplo n.º 16
0
        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();
        }
Ejemplo n.º 17
0
        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;
            }
        }
Ejemplo n.º 18
0
        /// <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);
            }
        }
Ejemplo n.º 19
0
        /// <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));
                }
            }
        }
Ejemplo n.º 20
0
        /// <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);
        }
Ejemplo n.º 21
0
 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);
 }
Ejemplo n.º 22
0
        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)));
            }
        }
Ejemplo n.º 23
0
        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);
        }
Ejemplo n.º 26
0
        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.
        }
Ejemplo n.º 27
0
        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;
        }
Ejemplo n.º 28
0
        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.
        }
Ejemplo n.º 30
0
        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.");
        }