public Action GetUpdateTransformAction(Transform newt) { if (WrappedObject is PARAM.Row || WrappedObject is MergedParamRow) { var actions = new List <Action>(); float roty = newt.EulerRotation.Y * Utils.Rad2Deg - 180.0f; actions.Add(GetPropertyChangeAction("PositionX", newt.Position.X)); actions.Add(GetPropertyChangeAction("PositionY", newt.Position.Y)); actions.Add(GetPropertyChangeAction("PositionZ", newt.Position.Z)); actions.Add(GetPropertyChangeAction("RotationX", newt.EulerRotation.X * Utils.Rad2Deg)); actions.Add(GetPropertyChangeAction("RotationY", roty)); actions.Add(GetPropertyChangeAction("RotationZ", newt.EulerRotation.Z * Utils.Rad2Deg)); var act = new CompoundAction(actions); act.SetPostExecutionAction((undo) => { UpdateRenderModel(); }); return(act); } else { var act = new PropertiesChangedAction(WrappedObject); var prop = WrappedObject.GetType().GetProperty("Position"); act.AddPropertyChange(prop, newt.Position); prop = WrappedObject.GetType().GetProperty("Rotation"); if (prop != null) { if (IsRotationPropertyRadians("Rotation")) { if (IsRotationXZY("Rotation")) { act.AddPropertyChange(prop, newt.EulerRotationXZY); } else { act.AddPropertyChange(prop, newt.EulerRotation); } } else { if (IsRotationXZY("Rotation")) { act.AddPropertyChange(prop, newt.EulerRotationXZY * Utils.Rad2Deg); } else { act.AddPropertyChange(prop, newt.EulerRotation * Utils.Rad2Deg); } } } act.SetPostExecutionAction((undo) => { UpdateRenderModel(); }); return(act); } }
public void Update(Ray ray, bool canCaptureMouse) { if (IsTransforming) { if (!InputTracker.GetMouseButton(MouseButton.Left)) { IsTransforming = false; var actlist = new List <Action>(); foreach (var sel in _selection.GetFilteredSelection <Entity>((o) => o.HasTransform)) { sel.ClearTemporaryTransform(false); actlist.Add(sel.GetUpdateTransformAction(ProjectTransformDelta(sel.GetLocalTransform()))); } var action = new CompoundAction(actlist); ActionManager.ExecuteAction(action); } else { if (Mode == GizmosMode.Translate) { var delta = GetSingleAxisProjection(ray, OriginalTransform, TransformAxis) - OriginProjection; CurrentTransform.Position = OriginalTransform.Position + delta; } else if (Mode == GizmosMode.Rotate) { Vector3 axis = Vector3.Zero; switch (TransformAxis) { case Axis.PosX: axis = Vector3.Transform(new Vector3(1.0f, 0.0f, 0.0f), OriginalTransform.Rotation); break; case Axis.PosY: axis = Vector3.Transform(new Vector3(0.0f, 1.0f, 0.0f), OriginalTransform.Rotation); break; case Axis.PosZ: axis = Vector3.Transform(new Vector3(0.0f, 0.0f, 1.0f), OriginalTransform.Rotation); break; } axis = Vector3.Normalize(axis); var newproj = GetAxisPlaneProjection(ray, OriginalTransform, TransformAxis); var delta = Vector3.Normalize(newproj - OriginalTransform.Position); var deltaorig = Vector3.Normalize(OriginProjection - OriginalTransform.Position); var side = Vector3.Cross(axis, deltaorig); float y = Math.Max(-1.0f, Math.Min(1.0f, Vector3.Dot(delta, deltaorig))); float x = Math.Max(-1.0f, Math.Min(1.0f, Vector3.Dot(delta, side))); float angle = (float)Math.Atan2(x, y); DebugAxis = axis; DebugAngle = angle; //CurrentTransform.EulerRotation.Y = OriginalTransform.EulerRotation.Y + angle; CurrentTransform.Rotation = Quaternion.Normalize(Quaternion.CreateFromAxisAngle(axis, angle) * OriginalTransform.Rotation); } if (_selection.IsSelection()) { //Selection.GetSingleSelection().SetTemporaryTransform(CurrentTransform); foreach (var sel in _selection.GetFilteredSelection <Entity>((o) => o.HasTransform)) { sel.SetTemporaryTransform(ProjectTransformDelta(sel.GetLocalTransform())); } } } } if (!IsTransforming) { if (_selection.IsFilteredSelection <Entity>((o) => o.HasTransform)) { if (_selection.IsSingleFilteredSelection <Entity>((o) => o.HasTransform)) { var sel = _selection.GetSingleFilteredSelection <Entity>((o) => o.HasTransform); OriginalTransform = sel.GetLocalTransform(); if (Origin == GizmosOrigin.BoundingBox && sel.RenderSceneMesh != null) { OriginalTransform.Position = sel.RenderSceneMesh.GetBounds().GetCenter(); } if (Space == GizmosSpace.World) { OriginalTransform.Rotation = Quaternion.Identity; } } else { // Average the positions of the selections and use a neutral rotation Vector3 accumPos = Vector3.Zero; foreach (var sel in _selection.GetFilteredSelection <Entity>((o) => o.HasTransform)) { accumPos += sel.GetLocalTransform().Position; } OriginalTransform = new Transform(accumPos / (float)_selection.GetSelection().Count, Vector3.Zero); } Axis hoveredAxis = Axis.None; switch (Mode) { case GizmosMode.Translate: if (TranslateGizmoX.GetRaycast(ray, TranslateGizmoXProxy.World)) { hoveredAxis = Axis.PosX; } else if (TranslateGizmoY.GetRaycast(ray, TranslateGizmoYProxy.World)) { hoveredAxis = Axis.PosY; } else if (TranslateGizmoZ.GetRaycast(ray, TranslateGizmoZProxy.World)) { hoveredAxis = Axis.PosZ; } TranslateGizmoXProxy.RenderSelectionOutline = (hoveredAxis == Axis.PosX); TranslateGizmoYProxy.RenderSelectionOutline = (hoveredAxis == Axis.PosY); TranslateGizmoZProxy.RenderSelectionOutline = (hoveredAxis == Axis.PosZ); break; case GizmosMode.Rotate: if (RotateGizmoX.GetRaycast(ray, RotateGizmoXProxy.World)) { hoveredAxis = Axis.PosX; } else if (RotateGizmoY.GetRaycast(ray, RotateGizmoYProxy.World)) { hoveredAxis = Axis.PosY; } else if (RotateGizmoZ.GetRaycast(ray, RotateGizmoZProxy.World)) { hoveredAxis = Axis.PosZ; } RotateGizmoXProxy.RenderSelectionOutline = (hoveredAxis == Axis.PosX); RotateGizmoYProxy.RenderSelectionOutline = (hoveredAxis == Axis.PosY); RotateGizmoZProxy.RenderSelectionOutline = (hoveredAxis == Axis.PosZ); break; } if (canCaptureMouse && InputTracker.GetMouseButtonDown(MouseButton.Left)) { if (hoveredAxis != Axis.None) { IsTransforming = true; TransformAxis = hoveredAxis; CurrentTransform = OriginalTransform; if (Mode == GizmosMode.Rotate) { OriginProjection = GetAxisPlaneProjection(ray, OriginalTransform, TransformAxis); } else { OriginProjection = GetSingleAxisProjection(ray, OriginalTransform, TransformAxis); } } } } } // Update gizmos transform and visibility if (_selection.IsSelection()) { //var selected = MsbEditor.Selection.Selected; //var center = selected.RenderSceneMesh.GetBounds().GetCenter(); //var center = selected.RenderSceneMesh.WorldMatrix.Translation; Vector3 center; Quaternion rot; if (IsTransforming) { center = CurrentTransform.Position; rot = CurrentTransform.Rotation; } else { center = OriginalTransform.Position; rot = OriginalTransform.Rotation; } float dist = (center - CameraPosition).Length(); Vector3 scale = new Vector3(dist * 0.04f); TranslateGizmoXProxy.World = new Transform(center, rot, scale).WorldMatrix; TranslateGizmoYProxy.World = new Transform(center, rot, scale).WorldMatrix; TranslateGizmoZProxy.World = new Transform(center, rot, scale).WorldMatrix; RotateGizmoXProxy.World = new Transform(center, rot, scale).WorldMatrix; RotateGizmoYProxy.World = new Transform(center, rot, scale).WorldMatrix; RotateGizmoZProxy.World = new Transform(center, rot, scale).WorldMatrix; if (Mode == GizmosMode.Translate) { TranslateGizmoXProxy.Visible = true; TranslateGizmoYProxy.Visible = true; TranslateGizmoZProxy.Visible = true; RotateGizmoXProxy.Visible = false; RotateGizmoYProxy.Visible = false; RotateGizmoZProxy.Visible = false; } else { TranslateGizmoXProxy.Visible = false; TranslateGizmoYProxy.Visible = false; TranslateGizmoZProxy.Visible = false; RotateGizmoXProxy.Visible = true; RotateGizmoYProxy.Visible = true; RotateGizmoZProxy.Visible = true; } } else { TranslateGizmoXProxy.Visible = false; TranslateGizmoYProxy.Visible = false; TranslateGizmoZProxy.Visible = false; RotateGizmoXProxy.Visible = false; RotateGizmoYProxy.Visible = false; RotateGizmoZProxy.Visible = false; } }