} // 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