From cd333f4f024e8dd8dbc2d3d20e21e9fc27db77d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20L=C3=BCbe=C3=9F?= Date: Tue, 5 Sep 2023 23:14:51 +0200 Subject: [PATCH] EditVector: Allow Disabling individual components + Disable XY-Angle when Entity has Rigidbody2D Component (This is something for future me, I couldn't figure it out...) + Start of handling of non trivial tranform nesting and rotations on XY axes + TranformComponent.RotationEuler: Normalize quaternion before converison --- .../src/EditWindows/ComponentEditWindow.bf | 13 ++++++++++-- GlitchyEngine/src/ImGui/ImGuiExtension.bf | 21 +++++++++++-------- .../World/Components/TransformComponent.bf | 2 +- GlitchyEngine/src/World/Scene.bf | 20 +++++++++++++++--- 4 files changed, 41 insertions(+), 15 deletions(-) diff --git a/GlitchyEditor/src/EditWindows/ComponentEditWindow.bf b/GlitchyEditor/src/EditWindows/ComponentEditWindow.bf index 8c9c7d9..e700a4b 100644 --- a/GlitchyEditor/src/EditWindows/ComponentEditWindow.bf +++ b/GlitchyEditor/src/EditWindows/ComponentEditWindow.bf @@ -81,7 +81,7 @@ namespace GlitchyEditor.EditWindows { DrawComponenSceneGUI(entity, => ShowPolygonColliderSceneGUI); } - + static void ShowPolygonColliderSceneGUI(Entity entity, PolygonCollider2DComponent* collider) { for (int i < collider.VertexCount) @@ -208,7 +208,16 @@ namespace GlitchyEditor.EditWindows } float3 rotationEuler = MathHelper.ToDegrees(transform.EditorRotationEuler); - if (ImGui.Editfloat3("Rotation", ref rotationEuler, .Zero, 0.1f, textWidth)) + + bool3 componentEditable = true; + + if (entity.HasComponent()) + { + componentEditable.XY = false; + rotationEuler.XY = 0; + } + + if (ImGui.Editfloat3("Rotation", ref rotationEuler, .Zero, 0.1f, textWidth, componentEnabled: componentEditable)) { transform.EditorRotationEuler = MathHelper.ToRadians(rotationEuler); diff --git a/GlitchyEngine/src/ImGui/ImGuiExtension.bf b/GlitchyEngine/src/ImGui/ImGuiExtension.bf index 266979e..ba32aa7 100644 --- a/GlitchyEngine/src/ImGui/ImGuiExtension.bf +++ b/GlitchyEngine/src/ImGui/ImGuiExtension.bf @@ -119,21 +119,21 @@ namespace ImGui protected internal static extern void CleanupFrame(); /// Control to edit a vector 2 with drag functionality and reset buttons - public static bool Editfloat2(StringView label, ref float2 value, float2 resetValues = .Zero, float dragSpeed = 0.1f, float columnWidth = 100f, float2 minValue = .Zero, float2 maxValue = .Zero) + public static bool Editfloat2(StringView label, ref float2 value, float2 resetValues = .Zero, float dragSpeed = 0.1f, float columnWidth = 100f, float2 minValue = .Zero, float2 maxValue = .Zero, bool2 componentEnabled = true) { - return EditVector<2>(label, ref *(float[2]*)&value, (float[2])resetValues, dragSpeed, columnWidth, (float[2])minValue, (float[2])maxValue); + return EditVector<2>(label, ref *(float[2]*)&value, (float[2])resetValues, dragSpeed, columnWidth, (float[2])minValue, (float[2])maxValue, (bool[2])componentEnabled); } /// Control to edit a vector 3 with drag functionality and reset buttons - public static bool Editfloat3(StringView label, ref float3 value, float3 resetValues = .Zero, float dragSpeed = 0.1f, float columnWidth = 100f, float3 minValue = .Zero, float3 maxValue = .Zero) + public static bool Editfloat3(StringView label, ref float3 value, float3 resetValues = .Zero, float dragSpeed = 0.1f, float columnWidth = 100f, float3 minValue = .Zero, float3 maxValue = .Zero, bool3 componentEnabled = true) { - return EditVector<3>(label, ref *(float[3]*)&value, (float[3])resetValues, dragSpeed, columnWidth, (float[3])minValue, (float[3])maxValue); + return EditVector<3>(label, ref *(float[3]*)&value, (float[3])resetValues, dragSpeed, columnWidth, (float[3])minValue, (float[3])maxValue, (bool[3])componentEnabled); } /// Control to edit a vector 4 with drag functionality and reset buttons - public static bool Editfloat4(StringView label, ref float4 value, float4 resetValues = .Zero, float dragSpeed = 0.1f, float columnWidth = 100f, float4 minValue = .Zero, float4 maxValue = .Zero) + public static bool Editfloat4(StringView label, ref float4 value, float4 resetValues = .Zero, float dragSpeed = 0.1f, float columnWidth = 100f, float4 minValue = .Zero, float4 maxValue = .Zero, bool4 componentEnabled = true) { - return EditVector<4>(label, ref *(float[4]*)&value, (float[4])resetValues, dragSpeed, columnWidth, (float[4])minValue, (float[4])maxValue); + return EditVector<4>(label, ref *(float[4]*)&value, (float[4])resetValues, dragSpeed, columnWidth, (float[4])minValue, (float[4])maxValue, (bool[4])componentEnabled); } static (ColorRGBA Default, ColorRGBA Hovered, ColorRGBA Active)[?] VectorButtonColors = .( @@ -142,7 +142,7 @@ namespace ImGui (.(55, 55, 230), .(55, 55, 150), .(90, 90, 230)), (.(230, 25, 45), .(230, 25, 45), .(230, 25, 45))); - public static bool EditVector(StringView label, ref float[NumComponents] value, float[NumComponents] resetValues = .(), float dragSpeed = 0.1f, float columnWidth = 100f, float[NumComponents] minValue = .(), float[NumComponents] maxValue = .()) where NumComponents : const int32 + public static bool EditVector(StringView label, ref float[NumComponents] value, float[NumComponents] resetValues = .(), float dragSpeed = 0.1f, float columnWidth = 100f, float[NumComponents] minValue = .(), float[NumComponents] maxValue = .(), bool[NumComponents] componentEnabled = .()) where NumComponents : const int32 { const String[?] componentNames = .("X", "Y", "Z", "W"); const String[?] componentIds = .("##X", "##Y", "##Z", "##W"); @@ -182,7 +182,9 @@ namespace ImGui PushStyleColor(.Button, VectorButtonColors[i].Default.ImGuiU32); PushStyleColor(.ButtonHovered, VectorButtonColors[i].Hovered.ImGuiU32); PushStyleColor(.ButtonActive, VectorButtonColors[i].Active.ImGuiU32); - + + ImGui.BeginDisabled(!componentEnabled[i]); + if (Button(componentNames[i], buttonSize)) { value[i] = resetValues[i]; @@ -202,7 +204,8 @@ namespace ImGui Mouse.LockCurrentPosition(mouseLockId); }*/ } - + + ImGui.EndDisabled(); /*if (IsItemDeactivatedAfterEdit()) { deactivated = true; diff --git a/GlitchyEngine/src/World/Components/TransformComponent.bf b/GlitchyEngine/src/World/Components/TransformComponent.bf index 68bd731..6d188e3 100644 --- a/GlitchyEngine/src/World/Components/TransformComponent.bf +++ b/GlitchyEngine/src/World/Components/TransformComponent.bf @@ -103,7 +103,7 @@ namespace GlitchyEngine.World */ public float3 RotationEuler { - get => Quaternion.ToEulerAngles(_rotation); + get => Quaternion.ToEulerAngles(normalize(_rotation)); set mut => Rotation = Quaternion.FromEulerAngles(value.Y, value.X, value.Z); } diff --git a/GlitchyEngine/src/World/Scene.bf b/GlitchyEngine/src/World/Scene.bf index f2de5e2..b7dd073 100644 --- a/GlitchyEngine/src/World/Scene.bf +++ b/GlitchyEngine/src/World/Scene.bf @@ -644,7 +644,13 @@ namespace GlitchyEngine.World b2Body* body = rigidbody.RuntimeBody; b2Vec2 position = Box2D.Body.GetPosition(body); float angle = Box2D.Body.GetAngle(body); + b2Transform bodyTransform = Box2D.Body.GetTransform(body); + float cos = sqrt((1 + bodyTransform.q.c) / 2); + float sin = sqrt((1 - bodyTransform.q.c) / 2) * sign(bodyTransform.q.s); + + Quaternion rotation = .(0, 0, sin, cos)..Normalize(); + if (entity.Parent != null) { Matrix worldToParent = entity.Parent.Value.Transform.WorldTransform.Invert(); @@ -654,14 +660,22 @@ namespace GlitchyEngine.World // TODO: when the parent of the rigidbody-entity is rotated, the rotation is applied wrong... Matrix.Decompose(worldToParent, let p, var worldToParentRotation, let s); - Quaternion newLocalRotation = (worldToParentRotation * Quaternion.FromEulerAngles(0, 0, angle))..Normalize(); + //Quaternion newLocalRotation = (worldToParentRotation..Normalize() * rotation..Normalize())..Normalize(); + //Quaternion newLocalRotation = (rotation * worldToParentRotation..Normalize())..Normalize(); + //Quaternion newLocalRotation = (worldToParentRotation * rotation)..Normalize(); + Quaternion newLocalRotation = rotation..Normalize(); + //Quaternion newLocalRotation = Quaternion.FromEulerAngles(0, 0, angle)..Normalize(); // TODO: when the parent has rotation on X or Y everything breaks even more... - transform.Rotation = (newLocalRotation * Quaternion.FromEulerAngles(transform.RotationEuler.Y, transform.RotationEuler.X, 0))..Normalize(); + //transform.Rotation = (Quaternion.FromEulerAngles(transform.RotationEuler.Y, transform.RotationEuler.X, 0)..Normalize() * newLocalRotation)..Normalize();//(newLocalRotation * Quaternion.FromEulerAngles(transform.RotationEuler.Y, transform.RotationEuler.X, 0))..Normalize(); + //transform.Rotation = ((transform.Rotation..Normalize() * Quaternion.FromEulerAngles(0, 0, transform.RotationEuler.Z)..Normalize())..Normalize() * newLocalRotation)..Normalize();//(newLocalRotation * Quaternion.FromEulerAngles(transform.RotationEuler.Y, transform.RotationEuler.X, 0))..Normalize(); + transform.Rotation = (newLocalRotation)..Normalize();//(newLocalRotation * Quaternion.FromEulerAngles(transform.RotationEuler.Y, transform.RotationEuler.X, 0))..Normalize(); } else { transform.Position = .(position.x, position.y, transform.Position.Z); - transform.RotationEuler = .(transform.RotationEuler.XY, angle); + //transform.RotationEuler = .(transform.RotationEuler.XY, angle); + //transform.RotationEuler = .(0, 0, angle); + transform.Rotation = normalize(rotation * normalize(Quaternion.FromEulerAngles(transform.RotationEuler.X, transform.RotationEuler.Y, 0))); } } }