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); } } }
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; } }