예제 #1
0
        } // NormalizedViewport

        #endregion

        #region Constructor

        /// <summary>
        /// Editor Viewport.
        /// </summary>
        public EditorViewport(RectangleF normalizedViewport, ViewportMode mode)
        {
            #region Controls

            viewportControl = new Container
            {
                Parent   = MainWindow.ViewportsSpace,
                Anchor   = Anchors.Left | Anchors.Top,
                CanFocus = false,
            };
            // Stores the normalized viewport to adapt to screen size changes.
            NormalizedViewport = normalizedViewport;

            ToolBarPanel topPanel = new ToolBarPanel {
                Width = viewportControl.Width
            };
            viewportControl.ToolBarPanel = topPanel;
            ToolBar toolBarTopPanel = new ToolBar
            {
                Parent  = topPanel,
                Movable = true,
                FullRow = true,
            };
            var modeComboBox = new ComboBox
            {
                Parent = topPanel,
                Width  = 200,
                Top    = 2,
            };
            modeComboBox.Items.AddRange(new [] { "Perspective", "Top", "Front", "Right", "Game" });
            modeComboBox.ItemIndex         = 0;
            modeComboBox.ItemIndexChanged += delegate
            {
                switch (modeComboBox.ItemIndex)
                {
                case 0: Mode = ViewportMode.Perspective; break;

                case 1: Mode = ViewportMode.Top; break;

                case 2: Mode = ViewportMode.Front; break;

                case 3: Mode = ViewportMode.Right; break;

                case 4: Mode = ViewportMode.Game; break;
                }
            };
            modeComboBox.Draw += delegate
            {
                if (modeComboBox.ListBoxVisible)
                {
                    return;
                }
                switch (Mode)
                {
                case ViewportMode.Perspective: modeComboBox.ItemIndex = 0; break;

                case ViewportMode.Top: modeComboBox.ItemIndex = 1; break;

                case ViewportMode.Front: modeComboBox.ItemIndex = 2; break;

                case ViewportMode.Right: modeComboBox.ItemIndex = 3; break;

                case ViewportMode.Game: modeComboBox.ItemIndex = 4; break;
                }
            };

            #endregion

            #region Cameras

            // Assets
            ambientLight = new AmbientLight {
                Name = "Editor Camara Ambient Light ", Color = Color.White, Intensity = 5f
            };
            postProcess = new PostProcess   {
                Name = "Editor Camera Post Process"
            };
            postProcess.ToneMapping.ToneMappingFunction = ToneMapping.ToneMappingFunctionEnumerate.FilmicALU;
            postProcess.Bloom.Enabled = false;

            // Editor Camera
            viewportCamera = new GameObject3D();
            viewportCamera.AddComponent <Camera>();
            viewportCamera.Camera.Enabled        = true;
            viewportCamera.Layer                 = Layer.GetLayerByNumber(31);
            viewportCamera.Camera.RenderingOrder = int.MinValue;
            editorCameraScript            = (ScriptEditorCamera)viewportCamera.AddComponent <ScriptEditorCamera>();
            editorCameraScript.Mode       = ScriptEditorCamera.ModeType.Maya;
            editorCameraScript.ClientArea = viewportControl.ClientArea;
            // Camera to render the gizmos and other editor elements.
            // This is done because the gizmos need to be in front of everything and I can't clear the ZBuffer wherever I want.
            helperCamera = new GameObject3D();
            helperCamera.AddComponent <Camera>();
            helperCamera.Camera.Enabled     = true;
            helperCamera.Camera.CullingMask = Layer.GetLayerByNumber(31).Mask; // The editor layer.
            helperCamera.Camera.ClearColor  = Color.Transparent;
            helperCamera.Layer = Layer.GetLayerByNumber(31);
            // Set the viewport camara as master of the gizmo camera.
            helperCamera.Camera.MasterCamera = viewportCamera.Camera;

            #endregion

            // Set default camera transformation in each mode.
            Mode = ViewportMode.Perspective;
            Reset();
            Mode = ViewportMode.Top;
            Reset();
            Mode = ViewportMode.Front;
            Reset();
            Mode = ViewportMode.Right;
            Reset();

            // Set current mode.
            Mode = mode;

            // Adjust viewport dimentions and render target size when the size changes.
            Screen.ScreenSizeChanged += OnScreenSizeChanged;
        } // EditorViewport
        } // SetPosition

        #endregion

        #region Update

        /// <summary>
        /// Update camera.
        /// </summary>
        public override void Update()
        {
            if (!((GameObject3D)Owner).Camera.Enabled)
            {
                return;
            }
            if (CouldBeManipulated() || ThisCameraIsBeingManipulated)
            {
                if (mode == ModeType.Softimage || mode == ModeType.NoManipulationKey)
                {
                    #region Softimage mode

                    #region Is it in manipulation mode?

                    if (ThisCameraIsBeingManipulated)
                    {
                        // To exit the manipulation mode.
                        if (Keyboard.KeyJustPressed(Keys.Escape) || Keyboard.KeyJustPressed(Keys.Space))
                        {
                            cameraBeingManipulated = null;
                        }
                    }
                    // To enter or exit the manipulation mode using the s key.
                    if (Keyboard.KeyJustPressed(Keys.S))
                    {
                        sJustPressed     = true;
                        sJustPressedTime = Time.ApplicationTime;
                    }
                    else
                    {
                        if (sJustPressed && !Keyboard.KeyPressed(Keys.S))
                        {
                            sJustPressed = false;
                            if (Time.ApplicationTime - sJustPressedTime < 0.3f)
                            {
                                cameraBeingManipulated = ThisCameraIsBeingManipulated ? null : this;
                            }
                        }
                    }

                    #endregion

                    #region Manipulate

                    if (ThisCameraIsBeingManipulated || Keyboard.KeyPressed(Keys.S) || mode == ModeType.NoManipulationKey)
                    {
                        // Translation
                        if (Mouse.LeftButtonPressed)
                        {
                            LookAtPosition -= ((GameObject3D)Owner).Transform.Right * Mouse.DeltaX * Distance / 1000;
                            LookAtPosition += ((GameObject3D)Owner).Transform.Up * Mouse.DeltaY * Distance / 1000;
                        }
                        // Orientation
                        if (Mouse.RightButtonPressed && !OrthographicMode)
                        {
                            Yaw   += Mouse.DeltaX * 0.005f;
                            Pitch += Mouse.DeltaY * 0.005f;
                        }
                        // Zoom
                        if (Mouse.MiddleButtonPressed)
                        {
                            Distance -= (-Mouse.DeltaX + Mouse.DeltaY) * Distance / 1300; // The minus is because I'm a little perfectionist.
                        }
                    }
                    // Zoom
                    Distance -= Mouse.WheelDelta * Distance / 1300;

                    #endregion

                    #endregion
                }
                else
                {
                    #region Maya mode

                    if ((Keyboard.KeyPressed(Keys.LeftAlt) || Keyboard.KeyPressed(Keys.RightAlt)) &&
                        (Mouse.LeftButtonPressed || Mouse.RightButtonPressed || Mouse.MiddleButtonPressed))
                    {
                        cameraBeingManipulated = this;
                        // Translation
                        if (Mouse.MiddleButtonPressed)
                        {
                            LookAtPosition -= ((GameObject3D)Owner).Transform.Right * Mouse.DeltaX * Distance / 1000;
                            LookAtPosition += ((GameObject3D)Owner).Transform.Up * Mouse.DeltaY * Distance / 1000;
                        }
                        // Orientation
                        if (Mouse.LeftButtonPressed && !OrthographicMode)
                        {
                            Yaw   += Mouse.DeltaX * 0.005f;
                            Pitch += Mouse.DeltaY * 0.005f;
                        }
                        if (Mouse.RightButtonPressed)
                        {
                            // Distance or zoom
                            Distance -= (Mouse.DeltaX + Mouse.DeltaY) * Distance / 1300;
                        }
                    }
                    else
                    {
                        cameraBeingManipulated = null;
                    }
                    // Distance or zoom
                    Distance -= Mouse.WheelDelta * Distance / 1300; // 1300 is an arbitrary number.

                    #endregion
                }
            }

            #region Gamepad

            LookAtPosition -= ((GameObject3D)Owner).Transform.Right * -GamePad.PlayerOne.LeftStickX * Distance / 1000;
            LookAtPosition += ((GameObject3D)Owner).Transform.Up * GamePad.PlayerOne.LeftStickY * Distance / 1000;
            // Orientation
            Yaw   -= GamePad.PlayerOne.RightStickX * 0.008f;
            Pitch += GamePad.PlayerOne.RightStickY * 0.008f;
            // Distance or zoom
            Distance -= (GamePad.PlayerOne.RightTrigger - GamePad.PlayerOne.LeftTrigger) * Distance / 300;

            #endregion

            #region Bounds

            // Orientation bounds
            if (Yaw >= twoPi)
            {
                Yaw -= twoPi;
            }
            if (Yaw < 0)
            {
                Yaw += twoPi;
            }
            if (Pitch >= twoPi)
            {
                Pitch -= twoPi;
            }
            if (Pitch < 0)
            {
                Pitch += twoPi;
            }
            // Distance bounds.
            if (Distance > ((GameObject3D)Owner).Camera.FarPlane)
            {
                Distance = ((GameObject3D)Owner).Camera.FarPlane;
            }
            if (Distance < ((GameObject3D)Owner).Camera.NearPlane)
            {
                Distance = ((GameObject3D)Owner).Camera.NearPlane;
            }

            #endregion

            // Calculate Rotation //
            Quaternion rotation = Quaternion.Identity;
            rotation *= Quaternion.CreateFromYawPitchRoll(0, Pitch, 0);
            rotation *= Quaternion.CreateFromYawPitchRoll(Yaw, 0, 0);
            rotation *= Quaternion.CreateFromYawPitchRoll(0, 0, Roll);
            // Its actually the invert...
            ((GameObject3D)Owner).Transform.Rotation = Quaternion.Inverse(rotation);
            // Now the position.
            Matrix rotationMatrix = Matrix.CreateFromQuaternion(rotation);
            ((GameObject3D)Owner).Transform.Position = LookAtPosition + new Vector3(rotationMatrix.M13, rotationMatrix.M23, rotationMatrix.M33) * Distance;
            if (OrthographicMode)
            {
                ((GameObject3D)Owner).Camera.OrthographicVerticalSize = Distance;
            }
        } // Update