Ejemplo n.º 1
0
        private static void HandleRemoteCameraInput(MyGuiInput input)
        {
            if (input.IsGameControlPressed(MyGameControlEnums.CONTROL_SECONDARY_CAMERA))
            {
                var rotationIndicator = new Vector3(input.GetMouseYForGamePlay() - MyMinerGame.ScreenSizeHalf.Y, input.GetMouseXForGamePlay() - MyMinerGame.ScreenSizeHalf.X, 0) * MyGuiConstants.MOUSE_ROTATION_INDICATOR_MULTIPLIER;

                rotationIndicator.X -= input.GetGameControlAnalogState(MyGameControlEnums.ROTATION_UP) * MyRemoteCameraConstants.ROTATION_SENSITIVITY_NON_MOUSE;
                rotationIndicator.X += input.GetGameControlAnalogState(MyGameControlEnums.ROTATION_DOWN) * MyRemoteCameraConstants.ROTATION_SENSITIVITY_NON_MOUSE;
                rotationIndicator.Y -= input.GetGameControlAnalogState(MyGameControlEnums.ROTATION_LEFT) * MyRemoteCameraConstants.ROTATION_SENSITIVITY_NON_MOUSE;
                rotationIndicator.Y += input.GetGameControlAnalogState(MyGameControlEnums.ROTATION_RIGHT) * MyRemoteCameraConstants.ROTATION_SENSITIVITY_NON_MOUSE;

                rotationIndicator *= MyConstants.PHYSICS_STEPS_PER_SECOND * MyGuiConstants.ROTATION_INDICATOR_MULTIPLIER;

                if (rotationIndicator != Vector3.Zero)
                {
                    var remoteCamera = MySession.PlayerShip.GetSelectedRemoteCamera();
                    if (remoteCamera != null)
                        remoteCamera.Rotate(-rotationIndicator);
                }
            }
        }
Ejemplo n.º 2
0
        public static void HandleInput(MyGuiInput input)
        {
            // -- Select Gizmo Mode -- //
            if (input.IsEditorControlNewPressed(MyEditorControlEnums.SWITCH_GIZMO_MODE) && !input.IsAnyCtrlKeyPressed())
            {
                SwitchGizmoMode();
            }

            // -- Select Gizmo Mode -- //
            if (input.IsEditorControlNewPressed(MyEditorControlEnums.SWITCH_GIZMO_MODE) && input.IsAnyCtrlKeyPressed() )
            {
                SwitchRotateSnapping();
            }



            // -- Cycle TransformationSpaces -- //
            if (input.IsEditorControlNewPressed(MyEditorControlEnums.SWITCH_GIZMO_SPACE))
            {
                if (ActiveSpace == TransformSpace.LOCAL)
                    ActiveSpace = TransformSpace.WORLD;
                else
                {
                    ActiveSpace = TransformSpace.LOCAL;
                }
            }

            // Below are options, that we can add later, but gizmo is prepared for them
            // however, key mappings will be probably changed
            // -- Cycle PivotTypes -- //
            //if (input.IsNewKeyPress(Keys.P))
            //{
            //    ActivePivot++;
            //}

            // -- Toggle PrecisionMode -- //
            //if (input.IsKeyPress(Keys.K))
            //{
            //    m_precisionMode = true;
            //}
            //else
            //{
            //    m_precisionMode = false;
            //}

            // -- Toggle Snapping -- //
            //if (MyEditor.Static.IsEditingPrefabContainer() == false)
            //{
            if (input.IsNewKeyPress(Keys.G))            
            {
                SnapEnabled = !SnapEnabled;
            }
            //}

            if (Enabled)
            {
                if (input.IsEditorControlNewPressed(MyEditorControlEnums.PRIMARY_ACTION_KEY))
                {
                    // reset for intersection (plane vs. ray)
                    m_translationDelta = Vector3.Zero;
                    m_intersectPosition = Vector3.Zero;
                    // reset for snapping
                    m_translationScaleSnapDelta = Vector3.Zero;
                    m_rotationSnapDelta = 0;
                    m_lastCursorPosition = MyGuiManager.MouseCursorPosition;
                    m_oldCursorPosition = MyGuiManager.MouseCursorPosition;
                    m_gizmoDelta = null;
                    m_gizmoStartPosition = null;
                    m_mouseStartPosition = m_lastCursorPosition;

                    m_startCameraForward = MyCamera.ForwardVector;
                    m_startCameraUp = MyCamera.UpVector;
                    m_startObjectPosition = Position;
                }

                m_lastIntersectionPosition = m_intersectPosition;
                TransformationActive = false;

                if (input.IsEditorControlPressed(MyEditorControlEnums.PRIMARY_ACTION_KEY))
                {
                    if (MyEditor.TransformLocked)
                    {
                        ActiveAxis = LastActiveAxis;
                    }

                    if (ActiveAxis != GizmoAxis.NONE)
                    {

                        //this will help to disable rectangular selection of multiple objects during object transformation with mouse
                        TransformationActive = true;

                        if (ActiveMode == GizmoMode.TRANSLATE)
                        {
                            #region Translate

                            if (HasTransformationStarted())
                            {
                                StartTransformationData();
                            }
                            //if (input.IsAnyShiftKeyPressed() && input.IsNewLeftMousePressed())
                            //{
                            //    MyEditor.Static.CopySelected(false);
                            //}
                            //else if (HasTransformationStarted())
                            //{
                            //    StartTransformationData();
                            //}

                            Vector3 delta = Vector3.Zero;

                            Vector3 worldPosition = Position;

                            if (ActiveAxis == GizmoAxis.XY)
                            {
                                GizmoTranslation(Vector3.Left, Vector3.Up, ref worldPosition);
                            }
                            else if (ActiveAxis == GizmoAxis.YZ)
                            {
                                GizmoTranslation(Vector3.Up, Vector3.Forward, ref worldPosition);
                            }
                            else if (ActiveAxis == GizmoAxis.ZX)
                            {
                                GizmoTranslation(Vector3.Left, Vector3.Forward, ref worldPosition);
                            }
                            else if (ActiveAxis == GizmoAxis.X)
                            {
                                GizmoTranslation(Vector3.Left, null, ref worldPosition);
                            }
                            else if (ActiveAxis == GizmoAxis.Y)
                            {
                                GizmoTranslation(Vector3.Up, null, ref worldPosition);
                            }
                            else if (ActiveAxis == GizmoAxis.Z)
                            {
                                GizmoTranslation(Vector3.Forward, null, ref worldPosition);
                            }

                            // When object is half distance to far, stop it's movement
                            Plane maxMovePlane = MyCamera.GetBoundingFrustum().Far;
                            maxMovePlane.D *= TRANSLATION_MAX_DISTANCE_FROM_CAMERA / MyCamera.FAR_PLANE_DISTANCE;

                            Vector3 moveVector = worldPosition - Position;
                            Ray moveRay = new Ray(Position, -moveVector);

                            float? intersection = moveRay.Intersects(maxMovePlane);

                            Vector3 cam = MyCamera.Position;

                            // Intersection found and moving object towards far clip plane
                            if (intersection.HasValue && Vector3.Dot(MyCamera.ForwardVector, moveVector) > 0 && (worldPosition - cam).Length() > Math.Abs(maxMovePlane.D))
                            {
                                Vector3 intersectionPoint = (moveRay.Position + (moveRay.Direction * intersection.Value));
                                worldPosition = intersectionPoint;
                            }

                            moveVector = worldPosition - Position;

                            // copy selected object only when moved from his original position + LMB + Shift
                            bool copySelected = (moveVector.LengthSquared() >= 0f &&
                                input.IsAnyShiftKeyPressed() &&
                                input.IsNewLeftMousePressed());

                            if (copySelected)
                            {
                                MyEditor.Static.CopySelected(false);
                            }

                            bool applyTranslation = true;

                            PrepareSafeSelectedEntitiesIterationHelper();
                            foreach (var entity in m_safeIterationHelper)
                            {
                                Vector3 newPosition = entity.GetPosition() + moveVector;

                                BoundingSphere sphere = new BoundingSphere(newPosition + entity.LocalVolumeOffset, entity.WorldVolume.Radius);
                                if (!entity.CanMoveAndRotate(newPosition, entity.GetWorldRotation()) || MyMwcSectorConstants.SECTOR_SIZE_FOR_PHYS_OBJECTS_BOUNDING_BOX.Contains(sphere) != MinerWarsMath.ContainmentType.Contains)
                                {
                                    applyTranslation = false;
                                    break;
                                }
                            }

                            if (applyTranslation)
                            {
                                PrepareSafeSelectedEntitiesIterationHelper();

                                List<MyEntity> transformedEntities = new List<MyEntity>();

                                // apply
                                foreach (MyEntity entity in m_safeIterationHelper)
                                {
                                    // skip already transformed linked entities
                                    if (transformedEntities.Contains(entity))
                                    {
                                        continue;
                                    }

                                    Vector3 newPosition = entity.GetPosition() + moveVector;

                                    //snaping after mouse over
                                    /*
                                    // Snap to grid
                                    if (SnapEnabled && ActiveSpace == TransformSpace.WORLD && !MyEditor.Static.IsLinked(entity))
                                    {
                                        SnapToGrid(ref newPosition, TranslationSnapValue);
                                    }
                                    */


                                    MoveAndRotateObject(newPosition, entity.GetWorldRotation(), entity);

                                    MyEditor.Static.FixLinkedEntities(entity, transformedEntities, null);
                                    transformedEntities.Add(entity);
                                }

                                // test if some entities are intersection
                                //CheckCollisions(m_safeIterationHelper); 
                                //MyEditor.Static.CheckAllCollidingObjects();                                
                                MyEditor.Static.HighlightCollisions(m_safeIterationHelper);

                            }

                            #endregion
                        }
                        else if (ActiveMode == GizmoMode.ROTATE)
                        {
                            #region Rotate

                            if (HasTransformationStarted()) StartTransformationData();
                            Vector2 deltaCursorPosition;
                            float delta;
                            if (!MyVideoModeManager.IsHardwareCursorUsed())
                            {
                                Vector2 minMouseCoord = MyGuiManager.GetMinMouseCoord();
                                Vector2 maxMouseCoord = MyGuiManager.GetMaxMouseCoord();

                                Vector2 newCursorPosition = MyGuiManager.MouseCursorPosition;
                                if (MyGuiManager.MouseCursorPosition.X <= minMouseCoord.X) newCursorPosition = new Vector2(maxMouseCoord.X, MyGuiManager.MouseCursorPosition.Y);
                                if (MyGuiManager.MouseCursorPosition.X >= maxMouseCoord.X) newCursorPosition = new Vector2(minMouseCoord.X, MyGuiManager.MouseCursorPosition.Y);
                                if (MyGuiManager.MouseCursorPosition.Y <= minMouseCoord.Y) newCursorPosition = new Vector2(MyGuiManager.MouseCursorPosition.X, maxMouseCoord.Y);
                                if (MyGuiManager.MouseCursorPosition.Y >= maxMouseCoord.Y) newCursorPosition = new Vector2(MyGuiManager.MouseCursorPosition.X, minMouseCoord.Y);
                                MyGuiManager.MouseCursorPosition = newCursorPosition;
                                //KeenSoftwareHouse.Library.Trace.Trace.SendMsgLastCall(MyGuiManager.MouseCursorPosition.ToString() + " " + MyGuiManager.MouseCursorPosition.ToString());

                                float deltaX = MathHelper.ToRadians(input.GetMouseXForGamePlay() - MyMinerGame.ScreenSizeHalf.X);
                                float deltaY = MathHelper.ToRadians(input.GetMouseYForGamePlay() - MyMinerGame.ScreenSizeHalf.Y);

                                deltaX = MathHelper.Clamp(deltaX, -1, 1);
                                deltaY = MathHelper.Clamp(deltaY, -1, 1);

                                delta = deltaY + deltaX;
                                Vector2 cursorDelta = Vector2.Zero;
                                if (MyGuiManager.MouseCursorPosition.Y != 0.0 && MyGuiManager.MouseCursorPosition.Y != 1.0)
                                {
                                    cursorDelta = MyGuiManager.MouseCursorPosition - m_lastCursorPosition;
                                }
                                m_inputScale = MathHelper.Clamp(Math.Abs(cursorDelta.Y) * 100, 0, 1);
                                delta *= m_inputScale;
                                m_oldCursorPosition = MyGuiManager.MouseCursorPosition;

                            }
                            else
                            {

                                Vector2 minMouseCoord = MyGuiManager.GetMinMouseCoord();
                                Vector2 maxMouseCoord = MyGuiManager.GetMaxMouseCoord();
                                Vector2 newCursorPosition = MyGuiManager.MouseCursorPosition;

                                deltaCursorPosition = MyGuiManager.MouseCursorPosition - m_oldCursorPosition;

                                if (MyGuiManager.MouseCursorPosition.X - 0.03f <= minMouseCoord.X)
                                {
                                    deltaCursorPosition = new Vector2(0, 0);
                                    newCursorPosition = new Vector2(maxMouseCoord.X - 0.05f, MyGuiManager.MouseCursorPosition.Y);
                                }
                                if (MyGuiManager.MouseCursorPosition.X + 0.03f >= maxMouseCoord.X * 0.98f)
                                {
                                    deltaCursorPosition = new Vector2(0, 0);
                                    newCursorPosition = new Vector2(minMouseCoord.X + 0.05f, MyGuiManager.MouseCursorPosition.Y);
                                }
                                if (MyGuiManager.MouseCursorPosition.Y - 0.03f <= minMouseCoord.Y)
                                {
                                    deltaCursorPosition = new Vector2(0, 0);
                                    newCursorPosition = new Vector2(MyGuiManager.MouseCursorPosition.X, maxMouseCoord.Y - 0.05f);
                                }
                                if (MyGuiManager.MouseCursorPosition.Y + 0.03f >= maxMouseCoord.Y)
                                {
                                    deltaCursorPosition = new Vector2(0, 0);
                                    newCursorPosition = new Vector2(MyGuiManager.MouseCursorPosition.X, minMouseCoord.Y + 0.05f);
                                }
                                MyGuiManager.MouseCursorPosition = newCursorPosition;

                                delta = (deltaCursorPosition.X + deltaCursorPosition.Y) * 4.0f;
                                delta = MathHelper.Clamp(delta, -2.0f, 2.0f);
                                m_oldCursorPosition = MyGuiManager.MouseCursorPosition;
                            }

                            // Allow snapping of gizmo to make it move depending on the selected grid scale
                            if (ActiveRotateSnapping!=RotateSnapping.NONE)
                            {
                                float snapValue = MathHelper.ToRadians(GetRotateSnapValue());
                                if (m_precisionMode)
                                {
                                    delta *= m_precisionModeScale;
                                    snapValue *= m_precisionModeScale;
                                }

                                m_rotationSnapDelta += delta;

                                float snapped = (int)(m_rotationSnapDelta / snapValue) * snapValue;
                                m_rotationSnapDelta -= snapped;
                                delta = snapped;
                            }
                            else if (m_precisionMode)
                            {
                                delta *= m_precisionModeScale;
                            }

                            // rotation matrix to transform - if more than one objects selected, always use world-space.
                            Matrix rot = Matrix.Identity;
                            rot.Forward = m_sceneWorld.Forward;
                            rot.Up = m_sceneWorld.Up;
                            rot.Right = m_sceneWorld.Right;

                            // Create rotation delta matrix
                            if (ActiveAxis == GizmoAxis.X)
                            {
                                rot *= Matrix.CreateFromAxisAngle(Rotation.Right, delta);
                            }
                            else if (ActiveAxis == GizmoAxis.Y)
                            {
                                rot *= Matrix.CreateFromAxisAngle(Rotation.Up, delta);
                            }
                            else if (ActiveAxis == GizmoAxis.Z)
                            {
                                rot *= Matrix.CreateFromAxisAngle(Rotation.Forward, delta);
                            }

                            // store rotation parameters so that we can calculate the difference in rotation of "before" rotation and "after"
                            CalculateYawPitchRollFromRotationDelta(rot);

                            PrepareSafeSelectedEntitiesIterationHelper();

                            List<MyEntity> transformedEntities = new List<MyEntity>();

                            // -- Apply rotation -- //
                            foreach (MyEntity entity in m_safeIterationHelper)
                            {
                                // skip already transformed linked entities
                                if (transformedEntities.Contains(entity))
                                {
                                    continue;
                                }

                                // VoxelMaps cannot be rotated
                                if (entity is MyVoxelMap == false)
                                {
                                    // use gizmo position for all PivotTypes except for object-center, it should use the entity.position instead.
                                    Vector3 newPosition;
                                    Matrix newRotation;
                                    GetRotationAndPosition(entity, rot, out newPosition, out newRotation);


                                    Matrix normalizedMat = new Matrix();
                                    normalizedMat.Right = Vector3.Normalize(newRotation.Right);
                                    normalizedMat.Forward = Vector3.Normalize(Vector3.Cross(Vector3.Normalize(newRotation.Up), normalizedMat.Right));
                                    normalizedMat.Up = Vector3.Normalize(Vector3.Cross(normalizedMat.Right, normalizedMat.Forward));
                                    normalizedMat.Translation = newRotation.Translation;
                                    normalizedMat.M44 = newRotation.M44;

                                    //KeenSoftwareHouse.Library.Trace.Trace.SendMsgLastCall("{");
                                    //KeenSoftwareHouse.Library.Trace.Trace.SendMsgLastCall(normalizedMat.ToString());
                                    //KeenSoftwareHouse.Library.Trace.Trace.SendMsgLastCall(newRotation.ToString());
                                    //KeenSoftwareHouse.Library.Trace.Trace.SendMsgLastCall("}");

                                    MoveAndRotateObject(newPosition, normalizedMat, entity);

                                    MyEditor.Static.FixLinkedEntities(entity, transformedEntities, null);
                                    transformedEntities.Add(entity);
                                }
                            }

                            SetPosition();
                            Vector3 moveVector = m_startObjectPosition - Position;
                            PrepareSafeSelectedEntitiesIterationHelper();
                            transformedEntities = new List<MyEntity>();
                            // apply
                            foreach (MyEntity entity in m_safeIterationHelper)
                            {
                                // skip already transformed linked entities
                                if (transformedEntities.Contains(entity))
                                {
                                    continue;
                                }

                                Vector3 newPosition = entity.GetPosition() + moveVector;

                                MoveAndRotateObject(newPosition, entity.GetWorldRotation(), entity);

                                MyEditor.Static.FixLinkedEntities(entity, transformedEntities, null);
                                transformedEntities.Add(entity);
                            }

                            #endregion
                        }
                    }
                }
                else
                {
                    PrepareSafeSelectedEntitiesIterationHelper();

                    foreach (MyEntity entity in m_safeIterationHelper)
                    {

                        float moveObjectDistanceInMeters = MyEditorGrid.GetGridStepInMeters();
                        float rotationAngleInRadians = MathHelper.ToRadians(GetRotationDelta());
                        Matrix entityOrientation = entity.GetWorldRotation();

                        bool isVoxelMap = entity is MyVoxelMap;

                        Vector3 entityPosition = entity.GetPosition();

                        #region Translate and Rotate with keyboard

                        Vector3 newPosition = entityPosition;
                        Matrix newRotation = entityOrientation;

                        // Keyboard translation
                        if (IsTransformationKeyPressed(input, Keys.NumPad1))
                        {
                            newPosition = GetTransformInAxis(GizmoAxis.X, entityPosition, Rotation, -moveObjectDistanceInMeters);
                        }
                        if (IsTransformationKeyPressed(input, Keys.NumPad3))
                        {
                            newPosition = GetTransformInAxis(GizmoAxis.X, entityPosition, Rotation, +moveObjectDistanceInMeters);
                        }
                        if (IsTransformationKeyPressed(input, Keys.NumPad2))
                        {
                            newPosition = GetTransformInAxis(GizmoAxis.Z, entityPosition, Rotation, +moveObjectDistanceInMeters);
                        }
                        if (IsTransformationKeyPressed(input, Keys.NumPad5))
                        {
                            newPosition = GetTransformInAxis(GizmoAxis.Z, entityPosition, Rotation, -moveObjectDistanceInMeters);

                        }
                        if (IsTransformationKeyPressed(input, Keys.NumPad9))
                        {
                            newPosition = GetTransformInAxis(GizmoAxis.Y, entityPosition, Rotation, +moveObjectDistanceInMeters);
                        }
                        if (IsTransformationKeyPressed(input, Keys.NumPad6))
                        {
                            newPosition = GetTransformInAxis(GizmoAxis.Y, entityPosition, Rotation, -moveObjectDistanceInMeters);
                        }

                        // Keyboard rotation
                        Matrix oneStepRotationDelta = Matrix.Identity;
                        if (IsTransformationKeyPressed(input, Keys.NumPad7) && !isVoxelMap)
                        {
                            oneStepRotationDelta = Matrix.CreateFromAxisAngle(Rotation.Right, rotationAngleInRadians);
                            GetRotationAndPosition(entity, oneStepRotationDelta, out newPosition, out newRotation);
                        }
                        if (IsTransformationKeyPressed(input, Keys.NumPad4) && !isVoxelMap)
                        {
                            oneStepRotationDelta = Matrix.CreateFromAxisAngle(Rotation.Up, rotationAngleInRadians);
                            GetRotationAndPosition(entity, oneStepRotationDelta, out newPosition, out newRotation);
                        }
                        if (IsTransformationKeyPressed(input, Keys.NumPad8) && !isVoxelMap)
                        {
                            oneStepRotationDelta = Matrix.CreateFromAxisAngle(Rotation.Forward, rotationAngleInRadians);
                            GetRotationAndPosition(entity, oneStepRotationDelta, out newPosition, out newRotation);
                        }

                        if (HasTransformationStarted()) StartTransformationData();

                        // Transform
                        bool translated = newPosition != entityPosition;
                        bool rotated = newRotation != entityOrientation;

                        if (translated || rotated)
                        {
                            if (translated) ActiveMode = GizmoMode.TRANSLATE;
                            if (rotated)
                            {
                                ActiveMode = GizmoMode.ROTATE;
                                if (IsDelayForSmoothMovementReached())
                                {
                                    RotationAmountInDegrees += (int)GetRotationDelta();
                                }
                                else
                                {
                                    RotationAmountInDegrees = (int)GetRotationDelta();
                                }
                            }

                            MoveAndRotateObject(newPosition, newRotation, entity);
                        }
                        #endregion
                    }


                    UpdateAxisSelection(MyGuiManager.GetScreenCoordinateFromNormalizedCoordinate(MyGuiManager.MouseCursorPosition));

                    /*
                    if (GetSnapPoint(true) == null)
                    {
                        
                    }
                    else
                    {
                        ActiveAxis = GizmoAxis.NONE;
                    }
                    */
                }

                if (HasTransformationEnded()) EndTransformationData();

                // previous is used to detect, when is right time to create undo/redo editor action(start of transform, and end of transform)
                TransformationActivePrevious = TransformationActive;
            }
            else
            {
                ActiveAxis = GizmoAxis.NONE;
            }
        }