private static void InitInput() { InputBindingRegistry ipb = AssetLocator.GameLayer.GetResource <InputBindingRegistry>(); ipb.RegisterKeyEvent( new HashSet <VirtualKey>() { VirtualKey.ControlKey, VirtualKey.ShiftKey }, VirtualKeyState.KeyDown | VirtualKeyState.KeyUp, (key, state) => { lock (staticMutationLock) { switch (key) { case VirtualKey.ControlKey: ctrlIsDepressed = state == VirtualKeyState.KeyDown; break; case VirtualKey.ShiftKey: shiftIsDepressed = state == VirtualKeyState.KeyDown; break; } } EditorToolbar.Instance.BeginInvoke(new Action(EditorToolbar.Instance.UpdateSelectedEntities)); EditorToolbar.StartNewReversionStep(); } ); ipb.RegisterKeyEvent( new HashSet <VirtualKey> { VirtualKey.W, VirtualKey.Z, VirtualKey.B }, VirtualKeyState.KeyDown, (key, _) => { lock (staticMutationLock) { if (!ctrlIsDepressed) { return; } } switch (key) { case VirtualKey.W: EditorToolbar.CloneSelectedEntities(); break; case VirtualKey.Z: EditorToolbar.UndoLast(); break; case VirtualKey.B: EditorToolbar.BakeAll(); break; } } ); ipb.RegisterKeyEvent( new HashSet <VirtualKey>() { VirtualKey.LButton, VirtualKey.RButton }, VirtualKeyState.KeyDown | VirtualKeyState.KeyUp, (key, state) => { lock (staticMutationLock) { Window mainWindow = AssetLocator.MainWindow; switch (state) { case VirtualKeyState.KeyDown: switch (key) { case VirtualKey.LButton: lmbIsDepressed = true; lmbMoveDistance = Vector2.ZERO; lmbInitialClick = InputModule.CursorPosition; break; case VirtualKey.RButton: rmbIsDepressed = true; rmbMoveDistance = Vector2.ZERO; rmbInitialClick = InputModule.CursorPosition; break; } if (InputModule.CursorIsWithinWindow(mainWindow)) { InputModule.LockCursorToWindow(mainWindow); mainWindow.ShowCursor = false; windowLocked = true; } break; case VirtualKeyState.KeyUp: cumulativeTransformDelta = 0f; if (windowLocked && (!lmbIsDepressed || key == VirtualKey.LButton) && (!rmbIsDepressed || key == VirtualKey.RButton)) { InputModule.UnlockCursorFromWindow(mainWindow); mainWindow.ShowCursor = true; } switch (key) { case VirtualKey.LButton: lmbIsDepressed = false; if (InputModule.CursorIsWithinWindow(mainWindow) && !thisClickWasTransformAltering) { float lmbDistanceSq = lmbMoveDistance.LengthSquared; if (lmbDistanceSq <= MAX_CURSOR_MOVE_DISTANCE_FOR_PICKING_SQ) { Vector2 curPosRelative = lmbInitialClick - mainWindow.Position; curPosRelative = new Vector2( curPosRelative.X - mainWindow.Width * 0.5f, curPosRelative.Y - mainWindow.Height * 0.5f ); InputModule.CursorPosition = lmbInitialClick + lmbMoveDistance; // Disgusting anti-deadlock hax now, sorry Window mainWindowLocal = mainWindow; Monitor.Exit(staticMutationLock); try { EditorToolbar.SelectEntityViaRay(AssetLocator.MainCamera.PixelRayCast(mainWindowLocal, curPosRelative)); } finally { Monitor.Enter(staticMutationLock); } } } thisClickWasTransformAltering = false; break; case VirtualKey.RButton: rmbIsDepressed = false; if (InputModule.CursorIsWithinWindow(mainWindow) && !thisClickWasTransformAltering) { float rmbDistanceSq = rmbMoveDistance.LengthSquared; if (rmbDistanceSq <= MAX_CURSOR_MOVE_DISTANCE_FOR_PICKING_SQ) { Vector2 curPosRelative = rmbInitialClick - mainWindow.Position; curPosRelative = new Vector2( curPosRelative.X - mainWindow.Width * 0.5f, curPosRelative.Y - mainWindow.Height * 0.5f ); InputModule.CursorPosition = rmbInitialClick + rmbMoveDistance; // Disgusting anti-deadlock hax #2 Window mainWindowLocal = mainWindow; Monitor.Exit(staticMutationLock); try { EditorToolbar.AddGameObject(AssetLocator.MainCamera.PixelRayCast(mainWindowLocal, curPosRelative)); } finally { Monitor.Enter(staticMutationLock); } } } break; } break; } } EditorToolbar.StartNewReversionStep(); } ); ipb.RegisterMouseMoveEvent((_, curDelta) => { bool lockTranslationsToGrid = EditorToolbar.LockTranslationsToGrid; float maxDelta = curDelta.X; if (Math.Abs(curDelta.Y) > Math.Abs(curDelta.X)) { maxDelta = curDelta.Y; } lock (staticMutationLock) { if (!InputModule.CursorIsWithinWindow(AssetLocator.MainWindow)) { return; } if (shiftIsDepressed && ctrlIsDepressed) { float delta = (maxDelta * -0.0025f); if (lockTranslationsToGrid) { cumulativeTransformDelta += delta; if (Math.Abs(cumulativeTransformDelta) > TRANS_GRID_MIN_SCALE_DELTA) { float remainder = (cumulativeTransformDelta % TRANS_GRID_MIN_SCALE_DELTA); delta = cumulativeTransformDelta - remainder; cumulativeTransformDelta = remainder; } else { return; } } ScaleEntities(delta); } else if (shiftIsDepressed) { float rotRads = maxDelta / -350f; if (lockTranslationsToGrid) { cumulativeTransformDelta += rotRads; if (Math.Abs(cumulativeTransformDelta) > TRANS_GRID_MIN_ROT_RADS) { float remainder = (cumulativeTransformDelta % TRANS_GRID_MIN_ROT_RADS); rotRads = cumulativeTransformDelta - remainder; cumulativeTransformDelta = remainder; } else { return; } } RotateEntities(rotRads); } else if (ctrlIsDepressed) { float distance = maxDelta * -0.25f; if (lockTranslationsToGrid) { cumulativeTransformDelta += distance; if (Math.Abs(cumulativeTransformDelta) > TRANS_GRID_MIN_TRANSLATION) { float remainder = (cumulativeTransformDelta % TRANS_GRID_MIN_TRANSLATION); distance = cumulativeTransformDelta - remainder; cumulativeTransformDelta = remainder; } else { return; } } TranslateEntities(distance); } else { thisClickWasTransformAltering = false; MoveCamera(curDelta); } } }); InputModule.AlwaysNotifyOfInput = true; }