/// <summary>
        /// Creates GUI elements for fields specific to the capsule collider.
        /// </summary>
        protected void BuildGUI(CapsuleCollider collider)
        {
            centerField.OnChanged += x => { collider.Center = x; MarkAsModified(); };
            centerField.OnFocusLost += ConfirmModify;
            centerField.OnConfirmed += ConfirmModify;

            orientationField.OnChanged += x =>
            {
                orientation = x;
                Quaternion rotation = Quaternion.FromEuler(x);

                collider.Normal = rotation.Rotate(Vector3.YAxis);
                MarkAsModified();
            };
            orientationField.OnFocusLost += ConfirmModify;
            orientationField.OnConfirmed += ConfirmModify;

            radiusField.OnChanged += x => { collider.Radius = x; MarkAsModified(); };
            radiusField.OnFocusLost += ConfirmModify;
            radiusField.OnConfirmed += ConfirmModify;

            halfHeightField.OnChanged += x => { collider.HalfHeight = x; MarkAsModified(); };
            halfHeightField.OnFocusLost += ConfirmModify;
            halfHeightField.OnConfirmed += ConfirmModify;

            Layout.AddElement(centerField);
            Layout.AddElement(orientationField);
            Layout.AddElement(radiusField);
            Layout.AddElement(halfHeightField);

            orientation = Quaternion.FromToRotation(Vector3.YAxis, collider.Normal).ToEuler();

            base.BuildGUI(collider);
        }
Esempio n. 2
0
 /// <summary>
 /// Creates a new rectangle.
 /// </summary>
 /// <param name="center">Origin of the rectangle. </param>
 /// <param name="axes">Two axes that define orientation of the rectangle. Axes extend from the origin. Axes should 
 ///                    be normalized.</param>
 /// <param name="extents">Two extents that define the size of the rectangle. Extends should be half the width/height
 ///                       as they are applied in both directions.</param>
 public Rect3(Vector3 center, Vector3[] axes, float[] extents)
 {
     this._center = center;
     _axisHorz = axes[0];
     _axisVert = axes[1];
     _extentHorz = extents[0];
     _extentVert = extents[1];
 }
        /// <summary>
        /// Creates GUI elements for fields specific to the plane collider.
        /// </summary>
        protected void BuildGUI(PlaneCollider collider)
        {
            normalField.OnChanged += x =>
            {
                normal = x;
                collider.Normal = x;

                MarkAsModified();
            };
            normalField.OnFocusLost += ConfirmModify;
            normalField.OnConfirmed += ConfirmModify;

            distanceField.OnChanged += x => { collider.Distance = x; MarkAsModified(); };
            distanceField.OnFocusLost += ConfirmModify;
            distanceField.OnConfirmed += ConfirmModify;

            Layout.AddElement(normalField);
            Layout.AddElement(distanceField);

            normal = collider.Normal;

            base.BuildGUI(collider);
        }
Esempio n. 4
0
        private void OnUpdate()
        {
            bool isOrtographic = camera.ProjectionType == ProjectionType.Orthographic;

            if (inputEnabled)
            {
                bool goingForward = VirtualInput.IsButtonHeld(moveForwardBtn);
                bool goingBack = VirtualInput.IsButtonHeld(moveBackwardBtn);
                bool goingLeft = VirtualInput.IsButtonHeld(moveLeftBtn);
                bool goingRight = VirtualInput.IsButtonHeld(moveRightBtn);
                bool goingUp = VirtualInput.IsButtonHeld(moveUpBtn);
                bool goingDown = VirtualInput.IsButtonHeld(moveDownBtn);
                bool fastMove = VirtualInput.IsButtonHeld(fastMoveBtn);
                bool camActive = VirtualInput.IsButtonHeld(activeBtn);
                bool isPanning = VirtualInput.IsButtonHeld(panBtn);

                bool hideCursor = camActive || isPanning;
                if (hideCursor != lastButtonState)
                {
                    if (hideCursor)
                    {
                        Cursor.Hide();

                        Rect2I clipRect;
                        clipRect.x = Input.PointerPosition.x - 2;
                        clipRect.y = Input.PointerPosition.y - 2;
                        clipRect.width = 4;
                        clipRect.height = 4;

                        Cursor.ClipToRect(clipRect);
                    }
                    else
                    {
                        Cursor.Show();
                        Cursor.ClipDisable();
                    }

                    lastButtonState = hideCursor;
                }

                float frameDelta = Time.FrameDelta;
                if (camActive)
                {
                    float horzValue = VirtualInput.GetAxisValue(horizontalAxis);
                    float vertValue = VirtualInput.GetAxisValue(verticalAxis);

                    float rotationAmount = RotationalSpeed * EditorSettings.MouseSensitivity * frameDelta;

                    yaw += new Degree(horzValue * rotationAmount);
                    pitch += new Degree(vertValue * rotationAmount);

                    yaw = MathEx.WrapAngle(yaw);
                    pitch = MathEx.WrapAngle(pitch);

                    Quaternion yRot = Quaternion.FromAxisAngle(Vector3.YAxis, yaw);
                    Quaternion xRot = Quaternion.FromAxisAngle(Vector3.XAxis, pitch);

                    Quaternion camRot = yRot*xRot;
                    camRot.Normalize();

                    SceneObject.Rotation = camRot;

                    // Handle movement using movement keys
                    Vector3 direction = Vector3.Zero;

                    if (goingForward) direction += SceneObject.Forward;
                    if (goingBack) direction -= SceneObject.Forward;
                    if (goingRight) direction += SceneObject.Right;
                    if (goingLeft) direction -= SceneObject.Right;
                    if (goingUp) direction += SceneObject.Up;
                    if (goingDown) direction -= SceneObject.Up;

                    if (direction.SqrdLength != 0)
                    {
                        direction.Normalize();

                        float multiplier = 1.0f;
                        if (fastMove)
                            multiplier = FastModeMultiplier;

                        currentSpeed = MathEx.Clamp(currentSpeed + Acceleration*frameDelta, StartSpeed, TopSpeed);
                        currentSpeed *= multiplier;
                    }
                    else
                    {
                        currentSpeed = 0.0f;
                    }

                    const float tooSmall = 0.0001f;
                    if (currentSpeed > tooSmall)
                    {
                        Vector3 velocity = direction*currentSpeed;
                        SceneObject.Move(velocity*frameDelta);
                    }
                }

                // Pan
                if (isPanning)
                {
                    float horzValue = VirtualInput.GetAxisValue(horizontalAxis);
                    float vertValue = VirtualInput.GetAxisValue(verticalAxis);

                    Vector3 direction = new Vector3(horzValue, -vertValue, 0.0f);
                    direction = camera.SceneObject.Rotation.Rotate(direction);

                    SceneObject.Move(direction*PanSpeed*frameDelta);
                }
            }
            else
            {
                Cursor.Show();
                Cursor.ClipDisable();
            }

            SceneWindow sceneWindow = EditorWindow.GetWindow<SceneWindow>();
            if (sceneWindow.Active)
            {
                Rect2I bounds = sceneWindow.Bounds;

                // Move using scroll wheel
                if (bounds.Contains(Input.PointerPosition))
                {
                    float scrollAmount = VirtualInput.GetAxisValue(scrollAxis);
                    if (!isOrtographic)
                    {
                        SceneObject.Move(SceneObject.Forward*scrollAmount*ScrollSpeed);
                    }
                    else
                    {
                        float orthoHeight = MathEx.Max(1.0f, camera.OrthoHeight - scrollAmount);
                        camera.OrthoHeight = orthoHeight;
                    }
                }
            }

            UpdateAnim();
        }
Esempio n. 5
0
        /// <summary>
        /// Orients the camera so it looks along the provided axis.
        /// </summary>
        public void LookAlong(Vector3 axis)
        {
            Vector3 up = Vector3.YAxis;
            if (MathEx.Abs(Vector3.Dot(axis, up)) > 0.9f)
                up = Vector3.ZAxis;

            CameraState state = new CameraState();
            state.Position = camera.SceneObject.Position;
            state.Rotation = Quaternion.LookRotation(axis, up);
            state.Ortographic = camera.ProjectionType == ProjectionType.Orthographic;
            state.FrustumWidth = frustumWidth;

            SetState(state);
        }
        /// <summary>
        /// Recreates all the GUI elements used by this inspector.
        /// </summary>
        private void BuildGUI()
        {
            CharacterController controller = InspectedObject as CharacterController;
            if (controller == null)
                return;

            radiusField.OnChanged += x => { controller.Radius = x; MarkAsModified(); };
            radiusField.OnConfirmed += ConfirmModify;
            radiusField.OnFocusLost += ConfirmModify;

            heightField.OnChanged += x => { controller.Height = x; MarkAsModified(); };
            heightField.OnConfirmed += ConfirmModify;
            heightField.OnFocusLost += ConfirmModify;

            orientationField.OnChanged += x =>
            {
                orientation = x;
                Quaternion rotation = Quaternion.FromEuler(x);

                controller.Up = rotation.Rotate(Vector3.YAxis);
                MarkAsModified();
            };
            orientationField.OnConfirmed += ConfirmModify;
            orientationField.OnFocusLost += ConfirmModify;

            contactOffsetField.OnChanged += x => { controller.ContactOffset = x; MarkAsModified(); };
            contactOffsetField.OnConfirmed += ConfirmModify;
            contactOffsetField.OnFocusLost += ConfirmModify;

            minMoveDistanceField.OnChanged += x => { controller.MinMoveDistance = x; MarkAsModified(); };
            minMoveDistanceField.OnConfirmed += ConfirmModify;
            minMoveDistanceField.OnFocusLost += ConfirmModify;

            climbingModeField.OnSelectionChanged += x =>
            {
                controller.ClimbingMode = (CharacterClimbingMode)x;

                MarkAsModified();
                ConfirmModify();
            };

            stepOffsetField.OnChanged += x => { controller.StepOffset = x; MarkAsModified(); };
            stepOffsetField.OnConfirmed += ConfirmModify;
            stepOffsetField.OnFocusLost += ConfirmModify;

            nonWalkableModeField.OnSelectionChanged += x =>
            {
                controller.NonWalkableMode = (CharacterNonWalkableMode)x;

                MarkAsModified();
                ConfirmModify();
            };

            slopeLimitField.OnChanged += x => { controller.SlopeLimit = new Degree(x); MarkAsModified(); };
            slopeLimitField.OnFocusLost += ConfirmModify;

            layerField.OnSelectionChanged += x =>
            {
                ulong layer = 0;
                bool[] states = layerField.States;
                for (int i = 0; i < states.Length; i++)
                    layer |= states[i] ? Layers.Values[i] : 0;

                layersValue = layer;
                controller.Layer = layer;

                MarkAsModified();
                ConfirmModify();
            };

            Layout.AddElement(radiusField);
            Layout.AddElement(heightField);
            Layout.AddElement(orientationField);
            Layout.AddElement(contactOffsetField);
            Layout.AddElement(minMoveDistanceField);
            Layout.AddElement(climbingModeField);
            Layout.AddElement(stepOffsetField);
            Layout.AddElement(nonWalkableModeField);
            Layout.AddElement(slopeLimitField);
            Layout.AddElement(layerField);

            orientation = Quaternion.FromToRotation(Vector3.YAxis, controller.Up).ToEuler();
        }
Esempio n. 7
0
        /// <inheritdoc/>
        protected internal override void PostInput()
        {
            delta = Vector3.Zero;

            if (Handles.MoveHandleSnapActive)
            {
                delta += Handles.SnapValue(xAxis.Delta, Handles.MoveSnapAmount) * GetXDir();
                delta += Handles.SnapValue(yAxis.Delta, Handles.MoveSnapAmount) * GetYDir();
                delta += Handles.SnapValue(zAxis.Delta, Handles.MoveSnapAmount) * GetZDir();

                delta += Handles.SnapValue(xyPlane.Delta.x, Handles.MoveSnapAmount) * GetXDir();
                delta += Handles.SnapValue(xyPlane.Delta.y, Handles.MoveSnapAmount) * GetYDir();
                delta += Handles.SnapValue(yzPlane.Delta.x, Handles.MoveSnapAmount) * GetYDir();
                delta += Handles.SnapValue(yzPlane.Delta.y, Handles.MoveSnapAmount) * GetZDir();
                delta += Handles.SnapValue(zxPlane.Delta.x, Handles.MoveSnapAmount) * GetZDir();
                delta += Handles.SnapValue(zxPlane.Delta.y, Handles.MoveSnapAmount) * GetXDir();
            }
            else
            {
                delta += xAxis.Delta * GetXDir();
                delta += yAxis.Delta * GetYDir();
                delta += zAxis.Delta * GetZDir();

                delta += xyPlane.Delta.x * GetXDir();
                delta += xyPlane.Delta.y * GetYDir();
                delta += yzPlane.Delta.x * GetYDir();
                delta += yzPlane.Delta.y * GetZDir();
                delta += zxPlane.Delta.x * GetZDir();
                delta += zxPlane.Delta.y * GetXDir();
            }
        }
Esempio n. 8
0
 /// <summary>
 /// Creates a new line segment.
 /// </summary>
 /// <param name="start">Line segment start position.</param>
 /// <param name="end">Line segment end position.</param>
 public LineSegment(Vector3 start, Vector3 end)
 {
     this.start = start;
     this.end = end;
 }
Esempio n. 9
0
        /// <inheritdoc/>
        protected internal override void PostInput()
        {
            delta = Vector3.Zero;

            delta += xAxis.Delta * GetXDir() * 0.1f;
            delta += yAxis.Delta * GetYDir() * 0.1f;
            delta += zAxis.Delta * GetZDir() * 0.1f;
            delta += (freeAxis.Delta.x + freeAxis.Delta.y) * Vector3.One * 0.1f;
        }
Esempio n. 10
0
        /// <inheritdoc/>
        protected internal override void Draw()
        {
            HandleDrawing.Layer = 1;
            HandleDrawing.Transform = Matrix4.TRS(Position, Rotation, Vector3.One);
            float handleSize = Handles.GetHandleSize(EditorApplication.SceneViewCamera, position);

            // Draw 1D sliders
            Vector3 smallCubeExtents = new Vector3(SMALL_CUBE_SIZE*0.5f, SMALL_CUBE_SIZE*0.5f, SMALL_CUBE_SIZE*0.5f);

            if (xAxis.State == HandleSlider.StateType.Active)
                HandleDrawing.Color = Color.White;
            else if (xAxis.State == HandleSlider.StateType.Hover)
                HandleDrawing.Color = Color.BansheeOrange;
            else
                HandleDrawing.Color = Color.Red;

            Vector3 xCubeOffset = Vector3.XAxis * SMALL_CUBE_SIZE * 0.5f;
            Vector3 xCubeStart = Vector3.XAxis - xCubeOffset;

            HandleDrawing.DrawLine(Vector3.Zero, xCubeStart, handleSize);
            HandleDrawing.DrawCube(xCubeStart + xCubeOffset, smallCubeExtents, handleSize);

            if (yAxis.State == HandleSlider.StateType.Active)
                HandleDrawing.Color = Color.White;
            else if (yAxis.State == HandleSlider.StateType.Hover)
                HandleDrawing.Color = Color.BansheeOrange;
            else
                HandleDrawing.Color = Color.Green;

            Vector3 yCubeOffset = Vector3.YAxis * SMALL_CUBE_SIZE * 0.5f;
            Vector3 yCubeStart = Vector3.YAxis - yCubeOffset;

            HandleDrawing.DrawLine(Vector3.Zero, yCubeStart, handleSize);
            HandleDrawing.DrawCube(yCubeStart + yCubeOffset, smallCubeExtents, handleSize);

            if (zAxis.State == HandleSlider.StateType.Active)
                HandleDrawing.Color = Color.White;
            else if (zAxis.State == HandleSlider.StateType.Hover)
                HandleDrawing.Color = Color.BansheeOrange;
            else
                HandleDrawing.Color = Color.Blue;

            Vector3 zCubeOffset = Vector3.ZAxis * SMALL_CUBE_SIZE * 0.5f;
            Vector3 zCubeStart = Vector3.ZAxis - zCubeOffset;

            HandleDrawing.DrawLine(Vector3.Zero, zCubeStart, handleSize);
            HandleDrawing.DrawCube(zCubeStart + zCubeOffset, smallCubeExtents, handleSize);

            // Draw free scale handle
            if (freeAxis.State == HandleSlider.StateType.Active)
                HandleDrawing.Color = Color.White;
            else if (freeAxis.State == HandleSlider.StateType.Hover)
                HandleDrawing.Color = Color.BansheeOrange;
            else
                HandleDrawing.Color = Color.White;

            //// Rotate it so it always faces the camera, and move it forward a bit to always render in front
            Vector3 bottomLeft = -Vector3.XAxis * 0.2f - Vector3.YAxis * 0.2f;
            Vector3 topLeft = -Vector3.XAxis * 0.2f + Vector3.YAxis * 0.2f;
            Vector3 topRight = Vector3.XAxis * 0.2f + Vector3.YAxis * 0.2f;
            Vector3 bottomRight = Vector3.XAxis * 0.2f - Vector3.YAxis * 0.2f;

            Vector3 offset = Vector3.ZAxis*0.1f;

            Quaternion cameraRot = EditorApplication.SceneViewCamera.SceneObject.Rotation;
            bottomLeft = cameraRot.Rotate(bottomLeft + offset);
            topLeft = cameraRot.Rotate(topLeft + offset);
            topRight = cameraRot.Rotate(topRight + offset);
            bottomRight = cameraRot.Rotate(bottomRight + offset);

            HandleDrawing.DrawLine(bottomLeft, bottomRight, handleSize);
            HandleDrawing.DrawLine(bottomLeft, topLeft, handleSize);
            HandleDrawing.DrawLine(topLeft, topRight, handleSize);
            HandleDrawing.DrawLine(bottomRight, topRight, handleSize);
        }
Esempio n. 11
0
 /// <summary>
 /// Triggered when the user changes the field value.
 /// </summary>
 /// <param name="newValue">New value of the 3D vector field.</param>
 private void OnFieldValueChanged(Vector3 newValue)
 {
     property.SetValue(newValue);
     state |= InspectableState.ModifyInProgress;
 }
Esempio n. 12
0
        /// <inheritdoc/>
        protected internal override void PostInput()
        {
            if (activeHandle != null)
            {
                if (activeHandle.IsDragged())
                {
                    if (!isDragged)
                    {
                        isDragged = true;

                        SceneObject[] selectedSceneObjects = Selection.SceneObjects;
                        activeSelection = new HandledObject[selectedSceneObjects.Length];
                        for (int i = 0; i < selectedSceneObjects.Length; i++)
                            activeSelection[i] = new HandledObject(selectedSceneObjects[i]);

                        initialHandlePosition = activeHandle.Position;
                        initialHandleRotation = activeHandle.Rotation;
                    }
                }
                else
                {
                    isDragged = false;
                    activeSelection = null;
                }

                activeHandle.PostInput();

                if (activeHandle.IsDragged())
                {
                    switch (activeHandleType)
                    {
                        case SceneViewTool.Move:
                            MoveHandle moveHandle = (MoveHandle) activeHandle;

                            foreach (var selectedObj in activeSelection)
                                selectedObj.so.LocalPosition = selectedObj.initialPosition + moveHandle.Delta;

                            break;
                        case SceneViewTool.Rotate:
                        {
                            RotateHandle rotateHandle = (RotateHandle) activeHandle;

                            // Make sure we transform relative to the handle position
                            SceneObject temporarySO = new SceneObject("Temp");
                            temporarySO.Position = initialHandlePosition;
                            temporarySO.LocalRotation = initialHandleRotation;

                            SceneObject[] originalParents = new SceneObject[activeSelection.Length];
                            for (int i = 0; i < activeSelection.Length; i++)
                            {
                                originalParents[i] = activeSelection[i].so.Parent;
                                activeSelection[i].so.LocalPosition = activeSelection[i].initialPosition;
                                activeSelection[i].so.LocalRotation = activeSelection[i].initialRotation;
                                activeSelection[i].so.Parent = temporarySO;
                            }

                            temporarySO.LocalRotation *= rotateHandle.Delta;

                            for (int i = 0; i < activeSelection.Length; i++)
                                activeSelection[i].so.Parent = originalParents[i];

                            temporarySO.Destroy();
                        }
                            break;
                        case SceneViewTool.Scale:
                        {
                            ScaleHandle scaleHandle = (ScaleHandle) activeHandle;

                            // Make sure we transform relative to the handle position
                            SceneObject temporarySO = new SceneObject("Temp");
                            temporarySO.Position = activeHandle.Position;

                            SceneObject[] originalParents = new SceneObject[activeSelection.Length];
                            for (int i = 0; i < activeSelection.Length; i++)
                            {
                                originalParents[i] = activeSelection[i].so.Parent;
                                activeSelection[i].so.LocalPosition = activeSelection[i].initialPosition;
                                activeSelection[i].so.LocalRotation = activeSelection[i].initialRotation;
                                activeSelection[i].so.LocalScale = activeSelection[i].initialScale;
                                activeSelection[i].so.Parent = temporarySO;
                            }

                            temporarySO.LocalScale += scaleHandle.Delta;

                            for (int i = 0; i < activeSelection.Length; i++)
                                activeSelection[i].so.Parent = originalParents[i];

                            temporarySO.Destroy();
                        }
                            break;
                    }

                    EditorApplication.SetSceneDirty();
                }
            }
            else
            {
                isDragged = false;
                activeSelection = null;
            }
        }
Esempio n. 13
0
 /// <summary>
 /// Creates a new scene object representation by recording the current object transform.
 /// </summary>
 /// <param name="so">Scene object that is being modified by a handle.</param>
 public HandledObject(SceneObject so)
 {
     this.so = so;
     initialPosition = so.LocalPosition;
     initialRotation = so.LocalRotation;
     initialScale = so.LocalScale;
 }
Esempio n. 14
0
        /// <summary>
        /// Transforms the bounding box by the given matrix.
        /// 
        /// As the resulting box will no longer be axis aligned, an axis align box is instead created by encompassing the 
        /// transformed oriented bounding box. Retrieving the value as an actual OBB would provide a tighter fit.
        /// </summary>
        /// <param name="tfrm">Affine matrix to transform the box with.</param>
        public void TransformAffine(Matrix4 tfrm)
        {
            Vector3 center = Center;
            Vector3 halfSize = Size*0.5f;

            Vector3 newCenter = tfrm.MultiplyAffine(center);
            Vector3 newHalfSize = new Vector3(
                MathEx.Abs(tfrm.m00) * halfSize.x + MathEx.Abs(tfrm.m01) * halfSize.y + MathEx.Abs(tfrm.m02) * halfSize.z,
                MathEx.Abs(tfrm.m10) * halfSize.x + MathEx.Abs(tfrm.m11) * halfSize.y + MathEx.Abs(tfrm.m12) * halfSize.z,
                MathEx.Abs(tfrm.m20) * halfSize.x + MathEx.Abs(tfrm.m21) * halfSize.y + MathEx.Abs(tfrm.m22) * halfSize.z);

            minimum = newCenter - newHalfSize;
            maximum = newCenter + newHalfSize;
        }
Esempio n. 15
0
 /// <summary>
 /// Creates a new sphere object.
 /// </summary>
 /// <param name="center">Center point of the sphere.</param>
 /// <param name="radius">Radius of the sphere.</param>
 public Sphere(Vector3 center, float radius)
 {
     _center = center;
     _radius = radius;
 }
Esempio n. 16
0
 /// <summary>
 /// Creates a new axis aligned box.
 /// </summary>
 /// <param name="min">Corner of the box with minimum values.</param>
 /// <param name="max">Corner of the box with maximum values.</param>
 public AABox(Vector3 min, Vector3 max)
 {
     minimum = min;
     maximum = max;
 }
Esempio n. 17
0
        /// <summary>
        /// Converts a point on the circle to an angle on the circle.
        /// </summary>
        /// <param name="up">Up vector determining the orientation of the circle.</param>
        /// <param name="point">Point along a unit circle centered around the origin.</param>
        /// <returns>Angle at which the provided point is located on the circle.</returns>
        private Degree PointOnCircleToAngle(Vector3 up, Vector3 point)
        {
            Quaternion rot = Quaternion.FromToRotation(up, Vector3.YAxis);

            Matrix4 worldToPlane = Matrix4.TRS(Vector3.Zero, rot, Vector3.One);
            point = worldToPlane.MultiplyDirection(point);

            return (MathEx.Atan2(-point.z, -point.x) + MathEx.Pi);
        }