Example #1
0
        public void ProcessGizmos()
        {
            var selected = _guiService.SelectedEntity;

            if (selected != default && selected.Has <TransformComponent>())
            {
                foreach (var camera in _cameras)
                {
                    ref var cam = ref _cameras.Get1(camera);
                    if (cam.Camera.Active && _guiService.GizmoType.HasValue)
                    {
                        if (duplicated && (!InputManager.Instance.GetKeyDown(KeyCodes.AltLeft) || InputManager.Instance.GetMouseButtonUp(MouseButtonCodes.Left)))
                        {
                            duplicated = false;
                        }

                        ImGuizmo.SetID(camera);
                        ImGuizmo.SetOrthographic(cam.Camera.ProjectionType == BootEngine.Renderer.Cameras.ProjectionType.Orthographic);
                        ImGuizmo.SetDrawlist(ImGui.GetWindowDrawList());

                        float windowWidth  = ImGui.GetWindowWidth();
                        float windowHeight = ImGui.GetWindowHeight();
                        ImGuizmo.SetRect(ImGui.GetWindowPos().X, ImGui.GetWindowPos().Y, windowWidth, windowHeight);

                        bool  snap      = InputManager.Instance.GetKeyDown(KeyCodes.LControl);
                        float snapValue = .1f;

                        if (_guiService.GizmoType == OPERATION.ROTATE)
                        {
                            snapValue = 45f;
                        }

                        float[] snapValues = new float[] { snapValue, snapValue, snapValue };

                        ref var tc = ref selected.Get <TransformComponent>();

                        var     rotTmp    = MathUtil.Rad2Deg(tc.Rotation);
                        float[] pos       = new float[] { tc.Translation.X, tc.Translation.Y, tc.Translation.Z };
                        float[] rot       = new float[] { rotTmp.X, rotTmp.Y, rotTmp.Z };
                        float[] sca       = new float[] { tc.Scale.X, tc.Scale.Y, tc.Scale.Z };
                        float[] transform = new float[16];

                        ImGuizmo.RecomposeMatrixFromComponents(ref pos[0], ref rot[0], ref sca[0], ref transform[0]);

                        // using the component's transform breaks guizmos for some reason
                        // TODO: investigate
                        //transform = tc.Transform.ToFloatArray();

                        ref var cameraTc = ref _cameras.Get2(camera);
                        Matrix4x4.Invert(cameraTc.Transform, out Matrix4x4 cameraViewMat);
                        float[] cameraView = cameraViewMat.ToFloatArray();
                        float[] cameraProj;
                        if (cam.Camera.SwapYAxis)
                        {
                            // de-swapping Y axis for gizmo rendering
                            cameraProj = (cam.Camera.ProjectionMatrix * new Matrix4x4(
                                              1, 0, 0, 0,
                                              0, -1, 0, 0,
                                              0, 0, 1, 0,
                                              0, 0, 0, 1)).ToFloatArray();
                        }
                        else
                        {
                            cameraProj = cam.Camera.ProjectionMatrix.ToFloatArray();
                        }
                        float[] deltaTransform = new float[16];

                        if (snap)
                        {
                            ImGuizmo.Manipulate(ref cameraView[0], ref cameraProj[0], _guiService.GizmoType.Value, MODE.LOCAL, ref transform[0], ref deltaTransform[0], ref snapValues[0]);
                        }
                        else
                        {
                            ImGuizmo.Manipulate(ref cameraView[0], ref cameraProj[0], _guiService.GizmoType.Value, MODE.LOCAL, ref transform[0], ref deltaTransform[0]);
                        }

                        if (ImGuizmo.IsOver() && ImGuizmo.IsUsing())
                        {
                            if (InputManager.Instance.GetKeyDown(KeyCodes.AltLeft) && !duplicated)
                            {
                                // copy current entity
                                _guiService.SelectedEntity = _guiService.SelectedEntity.Copy();
                                ref var tag = ref _guiService.SelectedEntity.Get <TagComponent>();
#pragma warning disable S1643 // Strings should not be concatenated using '+' in a loop
                                tag.Tag += " (Copy)";
#pragma warning restore S1643 // Strings should not be concatenated using '+' in a loop
                                duplicated = true;
                            }
                            float[] translation = new float[3];
                            float[] rotation    = new float[3];
                            float[] scale       = new float[3];

                            switch (_guiService.GizmoType)
                            {
                            case OPERATION.TRANSLATE:
                                ImGuizmo.DecomposeMatrixToComponents(ref deltaTransform[0], ref translation[0], ref rotation[0], ref scale[0]);
                                tc.Translation += new Vector3(translation[0], translation[1], translation[2]);
                                break;

                            case OPERATION.ROTATE:
                                ImGuizmo.DecomposeMatrixToComponents(ref deltaTransform[0], ref translation[0], ref rotation[0], ref scale[0]);
                                tc.Rotation -= MathUtil.Deg2Rad(new Vector3(rotation[0], rotation[1], rotation[2]));
                                break;

                            case OPERATION.SCALE:
                                // for some reason, scale part from deltaTransform does not return deltaScale
                                ImGuizmo.DecomposeMatrixToComponents(ref transform[0], ref translation[0], ref rotation[0], ref scale[0]);
                                tc.Scale = new Vector3(scale[0], scale[1], scale[2]);
                                break;
                            }
                        }