public override void HandleInput(MyGuiInput input, bool receivedFocusInThisUpdate) { base.HandleInput(input, receivedFocusInThisUpdate); if (MyGuiInput.ENABLE_DEVELOPER_KEYS) { if (input.IsNewKeyPress(Keys.C) && input.IsAnyCtrlKeyPressed()) { CopySector(); } if (input.IsNewKeyPress(Keys.V) && input.IsAnyCtrlKeyPressed()) { PasteSector(); } } if (MyFakes.DRAW_FACTION_AREAS_IN_SOLAR_MAP) { MySolarMapAreaInput.HandleInput(m_solarMapRender, input, receivedFocusInThisUpdate); } float rollIndicator = input.GetRoll(); Vector2 rotationIndicator = Vector2.Zero; if (input.IsNewRightMousePressed() && MyVideoModeManager.IsHardwareCursorUsed()) { m_oldRotationIndicator = input.GetRotation(); } if (input.IsRightMousePressed()) { if (MyVideoModeManager.IsHardwareCursorUsed()) { rotationIndicator = m_oldRotationIndicator - input.GetRotation(); m_oldRotationIndicator = input.GetRotation(); } else rotationIndicator = input.GetRotation(); } Vector3 moveIndicator = input.GetPositionDelta(); if (input.IsKeyPress(Keys.Left)) moveIndicator.X = -1; if (input.IsKeyPress(Keys.Right)) moveIndicator.X = 1; if (input.IsKeyPress(Keys.Up)) moveIndicator.Z = -1; if (input.IsKeyPress(Keys.Down)) moveIndicator.Z = 1; m_camera.Zoom(input.DeltaMouseScrollWheelValue()); m_camera.MoveAndRotate(moveIndicator, rotationIndicator, rollIndicator, 1); bool sectorChanged = false; if (m_lastSector != m_camera.TargetSector) { sectorChanged = true; m_lastSector = m_camera.TargetSector; } MySolarSystemMapNavigationMark navigationMarkUnderMouse = GetNearestNavigationMarkUnderMouseCursor(); const float maxHeightForEnter = MySolarSystemMapCamera.SECTOR_SIZE_GAMEUNITS * 16; if (sectorChanged) // we have moved camera so deselect sector { m_selectedSector = null; } // tool tips if (m_lastNavigationMarkUnderMouse != navigationMarkUnderMouse) { m_toolTip.ClearToolTips(); if (navigationMarkUnderMouse != null) { m_toolTip.AddToolTip(new StringBuilder(GetSectorName(navigationMarkUnderMouse))); if (!String.IsNullOrEmpty(navigationMarkUnderMouse.Description)) { m_toolTip.AddToolTip(new StringBuilder(navigationMarkUnderMouse.Description), Color.LightGray); } m_toolTip.AddToolTip(new StringBuilder(navigationMarkUnderMouse.Sector.ToString()), Color.LightGray); } m_lastNavigationMarkUnderMouse = navigationMarkUnderMouse; } if (navigationMarkUnderMouse != null) { MyGuiManager.SetMouseCursorTexture(MyGuiManager.GetMouseCursorHandTexture()); if (input.IsNewLeftMousePressed() && !m_travelButton.IsMouseOver()) { MyAudio.AddCue2D(MySoundCuesEnum.GuiMouseClick); if (m_selectedNavigationMark != null) m_selectedNavigationMark.Highlight = false; m_selectedNavigationMark = navigationMarkUnderMouse; m_selectedNavigationMark.Highlight = true; sectorChanged = true; m_slectionLocked = true; m_travelButton.Visible = false; } if (input.IsNewLeftMouseDoubleClick()) { TravelToSector(navigationMarkUnderMouse.Sector, navigationMarkUnderMouse.MissionID); } } else if (m_camera.CameraDistance < maxHeightForEnter && !m_slectionLocked) { if (MyGuiScreenGamePlay.CanTravelToSector(m_camera.TargetSector)) { //MyGuiManager.SetMouseCursorTexture(MyGuiManager.GetMouseCursorHandTexture()); if (m_selectedNavigationMark != null) m_selectedNavigationMark.Highlight = false; var navigationMarkUnderCamera = GetNavigationMarkUnderCamera(); if (navigationMarkUnderCamera != null && navigationMarkUnderCamera.Sector == m_camera.TargetSector) { m_selectedNavigationMark = navigationMarkUnderCamera; } else { m_selectedNavigationMark = new MySolarSystemMapNavigationMark(m_camera.TargetSector, ""); m_travelButton.Visible = false; } } else { m_selectedNavigationMark = null; } } else if (input.IsNewLeftMousePressed()) { if (m_selectedNavigationMark != null) m_selectedNavigationMark.Highlight = false; if (!m_travelButton.IsMouseOver()) { m_selectedNavigationMark = null; } m_slectionLocked = false; } else if (sectorChanged && m_camera.CameraDistance > maxHeightForEnter && !m_slectionLocked) { m_selectedNavigationMark = null; } else { MyGuiManager.SetMouseCursorTexture(MyGuiManager.GetMouseCursorArrowTexture()); } if (m_selectedNavigationMark != null) { if (!m_travelButton.Visible) { m_travelButton.Text.Clear(); string text = GetSectorName(m_selectedNavigationMark); if (text.Length > 21) { text = text.Substring(0, 20); text += "…"; } m_travelButton.Text.Append(MyTextsWrapper.GetFormatString(MyTextsWrapperEnum.TravelTo, text)); // float width = MyGuiManager.GetNormalizedSize( MyGuiManager.GetFontMinerWarsBlue(), m_travelButton.Text, 1).X + 0.05f; // m_travelButton.SetSize(new Vector2(width, MyGuiConstants.BACK_BUTTON_SIZE.Y)); m_travelButton.Visible = true; } } else { m_travelButton.Visible = false; } }
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; } }