From 4e54e945efb0898ba20ff9a0de61f4f9593cb036 Mon Sep 17 00:00:00 2001 From: Menotdan <32620310+Menotdan@users.noreply.github.com> Date: Sat, 9 Dec 2023 17:43:06 -0500 Subject: [PATCH 1/8] Implement auto-sizing for box colliders when they are added to the scene. --- Source/Editor/Modules/SceneModule.cs | 2 ++ Source/Engine/Level/Actor.cs | 9 ++++++++ Source/Engine/Level/Actors/BoxCollider.cs | 27 +++++++++++++++++++++++ 3 files changed, 38 insertions(+) create mode 100644 Source/Engine/Level/Actors/BoxCollider.cs diff --git a/Source/Editor/Modules/SceneModule.cs b/Source/Editor/Modules/SceneModule.cs index 954e3bd50..f5471ec33 100644 --- a/Source/Editor/Modules/SceneModule.cs +++ b/Source/Editor/Modules/SceneModule.cs @@ -534,6 +534,8 @@ namespace FlaxEditor.Modules { node.ParentNode = parentNode; } + + actor.OnActorSpawned(); } private void OnActorDeleted(Actor actor) diff --git a/Source/Engine/Level/Actor.cs b/Source/Engine/Level/Actor.cs index dbe8a89b5..7c34b5d7e 100644 --- a/Source/Engine/Level/Actor.cs +++ b/Source/Engine/Level/Actor.cs @@ -116,6 +116,15 @@ namespace FlaxEngine LocalTransform = Transform.Identity; } + /// + /// Called in-editor when an actor is added to the scene. + /// If not in the editor, this function will not be called. + /// + public virtual void OnActorSpawned() + { + + } + /// /// Creates a new child actor of the given type. /// diff --git a/Source/Engine/Level/Actors/BoxCollider.cs b/Source/Engine/Level/Actors/BoxCollider.cs new file mode 100644 index 000000000..f9343eb74 --- /dev/null +++ b/Source/Engine/Level/Actors/BoxCollider.cs @@ -0,0 +1,27 @@ +using System; + +namespace FlaxEngine +{ + partial class BoxCollider + { + /// + public override void OnActorSpawned() + { + base.OnActorSpawned(); + if (Parent is StaticModel model) + { + Vector3 modelScale = model.Scale; + Vector3 modelSize = model.Box.Size; + Vector3 modelCenter = model.Box.Center - model.Position; + Vector3 colliderSize = modelSize / modelScale; + Vector3 colliderCenter = modelCenter / modelScale; + + Size = colliderSize; + Center = colliderCenter; + + // Undo Rotation + Orientation *= Quaternion.Invert(Orientation); + } + } + } +} From 2f500425239d206f9afd0afa43656999d9e35027 Mon Sep 17 00:00:00 2001 From: Menotdan <32620310+Menotdan@users.noreply.github.com> Date: Sat, 9 Dec 2023 17:56:09 -0500 Subject: [PATCH 2/8] Simplify code and allow any actor as parent. --- Source/Engine/Level/Actors/BoxCollider.cs | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/Source/Engine/Level/Actors/BoxCollider.cs b/Source/Engine/Level/Actors/BoxCollider.cs index f9343eb74..8f2d0e366 100644 --- a/Source/Engine/Level/Actors/BoxCollider.cs +++ b/Source/Engine/Level/Actors/BoxCollider.cs @@ -8,20 +8,15 @@ namespace FlaxEngine public override void OnActorSpawned() { base.OnActorSpawned(); - if (Parent is StaticModel model) - { - Vector3 modelScale = model.Scale; - Vector3 modelSize = model.Box.Size; - Vector3 modelCenter = model.Box.Center - model.Position; - Vector3 colliderSize = modelSize / modelScale; - Vector3 colliderCenter = modelCenter / modelScale; + Vector3 parentScale = Parent.Scale; + Vector3 parentSize = Parent.Box.Size; + Vector3 parentCenter = Parent.Box.Center - Parent.Position; - Size = colliderSize; - Center = colliderCenter; + Size = parentSize / parentScale; + Center = parentCenter / parentScale; - // Undo Rotation - Orientation *= Quaternion.Invert(Orientation); - } + // Undo Rotation + Orientation *= Quaternion.Invert(Orientation); } } } From c895e310cbec7a6fbca418ff419cd64e08b13cb4 Mon Sep 17 00:00:00 2001 From: Menotdan <32620310+Menotdan@users.noreply.github.com> Date: Sat, 9 Dec 2023 19:19:03 -0500 Subject: [PATCH 3/8] Improve box collider creation behavior to account for child actors of the collider's parent. --- Source/Engine/Level/Actors/BoxCollider.cs | 29 ++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/Source/Engine/Level/Actors/BoxCollider.cs b/Source/Engine/Level/Actors/BoxCollider.cs index 8f2d0e366..a21f30aeb 100644 --- a/Source/Engine/Level/Actors/BoxCollider.cs +++ b/Source/Engine/Level/Actors/BoxCollider.cs @@ -1,16 +1,39 @@ -using System; +using FlaxEditor.Windows; namespace FlaxEngine { partial class BoxCollider { + private void BoxExcluding(Actor target, ref BoundingBox output, Actor excluded) + { + foreach (Actor child in target.Children) + { + if (child == excluded) + { + continue; + } + + output = BoundingBox.Merge(output, child.Box); + BoxExcluding(child, ref output, excluded); + } + } + /// public override void OnActorSpawned() { base.OnActorSpawned(); Vector3 parentScale = Parent.Scale; - Vector3 parentSize = Parent.Box.Size; - Vector3 parentCenter = Parent.Box.Center - Parent.Position; + BoundingBox parentBox = Parent.Box; + BoxExcluding(Parent, ref parentBox, this); + + Vector3 parentSize = parentBox.Size; + Vector3 parentCenter = parentBox.Center - Parent.Position; + + // Avoid division by zero + if (parentScale.X == 0 || parentScale.Y == 0 || parentScale.Z == 0) + { + return; + } Size = parentSize / parentScale; Center = parentCenter / parentScale; From 01b233af109171b1ce8b9e317ded04d869e5fe77 Mon Sep 17 00:00:00 2001 From: Menotdan <32620310+Menotdan@users.noreply.github.com> Date: Sat, 9 Dec 2023 19:57:52 -0500 Subject: [PATCH 4/8] Factor out AutoResize() function for external use. Fix build regression due to unwanted import. --- Source/Engine/Level/Actors/BoxCollider.cs | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/Source/Engine/Level/Actors/BoxCollider.cs b/Source/Engine/Level/Actors/BoxCollider.cs index a21f30aeb..9c816eac4 100644 --- a/Source/Engine/Level/Actors/BoxCollider.cs +++ b/Source/Engine/Level/Actors/BoxCollider.cs @@ -1,5 +1,3 @@ -using FlaxEditor.Windows; - namespace FlaxEngine { partial class BoxCollider @@ -18,10 +16,16 @@ namespace FlaxEngine } } - /// - public override void OnActorSpawned() + /// + /// Resizes the box collider based on the bounds of it's parent. + /// + public void AutoResize() { - base.OnActorSpawned(); + if (Parent is Scene) + { + return; + } + Vector3 parentScale = Parent.Scale; BoundingBox parentBox = Parent.Box; BoxExcluding(Parent, ref parentBox, this); @@ -41,5 +45,12 @@ namespace FlaxEngine // Undo Rotation Orientation *= Quaternion.Invert(Orientation); } + + /// + public override void OnActorSpawned() + { + base.OnActorSpawned(); + AutoResize(); + } } } From 19dbd3c4e4f6c562adc9dde920dca5b825e7a264 Mon Sep 17 00:00:00 2001 From: Menotdan <32620310+Menotdan@users.noreply.github.com> Date: Sat, 9 Dec 2023 21:00:45 -0500 Subject: [PATCH 5/8] Add button to resize collider manually. --- Source/Engine/Level/Actors/BoxCollider.cs | 27 +++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/Source/Engine/Level/Actors/BoxCollider.cs b/Source/Engine/Level/Actors/BoxCollider.cs index 9c816eac4..ff560aa64 100644 --- a/Source/Engine/Level/Actors/BoxCollider.cs +++ b/Source/Engine/Level/Actors/BoxCollider.cs @@ -1,5 +1,30 @@ +#if FLAX_EDITOR +using FlaxEditor.CustomEditors; +using FlaxEditor.CustomEditors.Dedicated; +#endif + namespace FlaxEngine { +#if FLAX_EDITOR + /// + /// Dedicated custom editor for BoxCollider objects. + /// + [CustomEditor(typeof(BoxCollider)), DefaultEditor] + public class BoxColliderEditor : ActorEditor + { + /// + public override void Initialize(LayoutElementsContainer layout) + { + base.Initialize(layout); + layout.Space(20f); + var autoResizeButton = layout.Button("Resize to Fit", "Resize the box collider to fit it's parent's bounds."); + + BoxCollider collider = Values[0] as BoxCollider; + autoResizeButton.Button.Clicked += collider.AutoResize; + } + } +#endif + partial class BoxCollider { private void BoxExcluding(Actor target, ref BoundingBox output, Actor excluded) @@ -26,6 +51,8 @@ namespace FlaxEngine return; } + LocalPosition = Vector3.Zero; + Vector3 parentScale = Parent.Scale; BoundingBox parentBox = Parent.Box; BoxExcluding(Parent, ref parentBox, this); From 945438568341cf16988910d62e5103652d8cd266 Mon Sep 17 00:00:00 2001 From: Menotdan <32620310+Menotdan@users.noreply.github.com> Date: Tue, 12 Dec 2023 15:46:15 -0500 Subject: [PATCH 6/8] Use the BoxColliderNode class for handling actor spawn events. --- Source/Editor/Modules/SceneModule.cs | 2 -- .../SceneGraph/Actors/BoxColliderNode.cs | 33 +++++++++++++++++++ Source/Engine/Level/Actor.cs | 9 ----- Source/Engine/Level/Actors/BoxCollider.cs | 27 --------------- 4 files changed, 33 insertions(+), 38 deletions(-) diff --git a/Source/Editor/Modules/SceneModule.cs b/Source/Editor/Modules/SceneModule.cs index f5471ec33..954e3bd50 100644 --- a/Source/Editor/Modules/SceneModule.cs +++ b/Source/Editor/Modules/SceneModule.cs @@ -534,8 +534,6 @@ namespace FlaxEditor.Modules { node.ParentNode = parentNode; } - - actor.OnActorSpawned(); } private void OnActorDeleted(Actor actor) diff --git a/Source/Editor/SceneGraph/Actors/BoxColliderNode.cs b/Source/Editor/SceneGraph/Actors/BoxColliderNode.cs index 1f92eceea..8c00318db 100644 --- a/Source/Editor/SceneGraph/Actors/BoxColliderNode.cs +++ b/Source/Editor/SceneGraph/Actors/BoxColliderNode.cs @@ -8,8 +8,33 @@ using Real = System.Single; using FlaxEngine; +#if FLAX_EDITOR +using FlaxEditor.CustomEditors.Dedicated; +using FlaxEditor.CustomEditors; +#endif + namespace FlaxEditor.SceneGraph.Actors { +#if FLAX_EDITOR + /// + /// Dedicated custom editor for BoxCollider objects. + /// + [CustomEditor(typeof(BoxCollider)), DefaultEditor] + public class BoxColliderEditor : ActorEditor + { + /// + public override void Initialize(LayoutElementsContainer layout) + { + base.Initialize(layout); + layout.Space(20f); + var autoResizeButton = layout.Button("Resize to Fit", "Resize the box collider to fit it's parent's bounds."); + + BoxCollider collider = Values[0] as BoxCollider; + autoResizeButton.Button.Clicked += collider.AutoResize; + } + } +#endif + /// /// Scene tree node for actor type. /// @@ -37,5 +62,13 @@ namespace FlaxEditor.SceneGraph.Actors return base.RayCastSelf(ref ray, out distance, out normal); } + + /// + public override void PostSpawn() + { + base.PostSpawn(); + BoxCollider boxCollider = Actor as BoxCollider; + boxCollider.AutoResize(); + } } } diff --git a/Source/Engine/Level/Actor.cs b/Source/Engine/Level/Actor.cs index 7c34b5d7e..dbe8a89b5 100644 --- a/Source/Engine/Level/Actor.cs +++ b/Source/Engine/Level/Actor.cs @@ -116,15 +116,6 @@ namespace FlaxEngine LocalTransform = Transform.Identity; } - /// - /// Called in-editor when an actor is added to the scene. - /// If not in the editor, this function will not be called. - /// - public virtual void OnActorSpawned() - { - - } - /// /// Creates a new child actor of the given type. /// diff --git a/Source/Engine/Level/Actors/BoxCollider.cs b/Source/Engine/Level/Actors/BoxCollider.cs index ff560aa64..cfb6e9dde 100644 --- a/Source/Engine/Level/Actors/BoxCollider.cs +++ b/Source/Engine/Level/Actors/BoxCollider.cs @@ -5,26 +5,6 @@ using FlaxEditor.CustomEditors.Dedicated; namespace FlaxEngine { -#if FLAX_EDITOR - /// - /// Dedicated custom editor for BoxCollider objects. - /// - [CustomEditor(typeof(BoxCollider)), DefaultEditor] - public class BoxColliderEditor : ActorEditor - { - /// - public override void Initialize(LayoutElementsContainer layout) - { - base.Initialize(layout); - layout.Space(20f); - var autoResizeButton = layout.Button("Resize to Fit", "Resize the box collider to fit it's parent's bounds."); - - BoxCollider collider = Values[0] as BoxCollider; - autoResizeButton.Button.Clicked += collider.AutoResize; - } - } -#endif - partial class BoxCollider { private void BoxExcluding(Actor target, ref BoundingBox output, Actor excluded) @@ -72,12 +52,5 @@ namespace FlaxEngine // Undo Rotation Orientation *= Quaternion.Invert(Orientation); } - - /// - public override void OnActorSpawned() - { - base.OnActorSpawned(); - AutoResize(); - } } } From b87a7d16fb57f02c9430c539b2f56f6dc75bcecf Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Thu, 14 Dec 2023 11:03:58 +0100 Subject: [PATCH 7/8] Move managed code into native impl for #2063 --- Source/Engine/Level/Actors/BoxCollider.cs | 56 ------------------- .../Engine/Physics/Colliders/BoxCollider.cpp | 27 +++++++++ Source/Engine/Physics/Colliders/BoxCollider.h | 5 ++ 3 files changed, 32 insertions(+), 56 deletions(-) delete mode 100644 Source/Engine/Level/Actors/BoxCollider.cs diff --git a/Source/Engine/Level/Actors/BoxCollider.cs b/Source/Engine/Level/Actors/BoxCollider.cs deleted file mode 100644 index cfb6e9dde..000000000 --- a/Source/Engine/Level/Actors/BoxCollider.cs +++ /dev/null @@ -1,56 +0,0 @@ -#if FLAX_EDITOR -using FlaxEditor.CustomEditors; -using FlaxEditor.CustomEditors.Dedicated; -#endif - -namespace FlaxEngine -{ - partial class BoxCollider - { - private void BoxExcluding(Actor target, ref BoundingBox output, Actor excluded) - { - foreach (Actor child in target.Children) - { - if (child == excluded) - { - continue; - } - - output = BoundingBox.Merge(output, child.Box); - BoxExcluding(child, ref output, excluded); - } - } - - /// - /// Resizes the box collider based on the bounds of it's parent. - /// - public void AutoResize() - { - if (Parent is Scene) - { - return; - } - - LocalPosition = Vector3.Zero; - - Vector3 parentScale = Parent.Scale; - BoundingBox parentBox = Parent.Box; - BoxExcluding(Parent, ref parentBox, this); - - Vector3 parentSize = parentBox.Size; - Vector3 parentCenter = parentBox.Center - Parent.Position; - - // Avoid division by zero - if (parentScale.X == 0 || parentScale.Y == 0 || parentScale.Z == 0) - { - return; - } - - Size = parentSize / parentScale; - Center = parentCenter / parentScale; - - // Undo Rotation - Orientation *= Quaternion.Invert(Orientation); - } - } -} diff --git a/Source/Engine/Physics/Colliders/BoxCollider.cpp b/Source/Engine/Physics/Colliders/BoxCollider.cpp index b80b68de0..d74b3efba 100644 --- a/Source/Engine/Physics/Colliders/BoxCollider.cpp +++ b/Source/Engine/Physics/Colliders/BoxCollider.cpp @@ -2,6 +2,7 @@ #include "BoxCollider.h" #include "Engine/Physics/PhysicsBackend.h" +#include "Engine/Level/Scene/Scene.h" BoxCollider::BoxCollider(const SpawnParams& params) : Collider(params) @@ -19,6 +20,32 @@ void BoxCollider::SetSize(const Float3& value) UpdateBounds(); } +void BoxCollider::AutoResize() +{ + Actor* parent = GetParent(); + if (Cast(parent)) + return; + + // Get bounds of all siblings (excluding itself) + const Vector3 parentScale = parent->GetScale(); + if (parentScale.IsAnyZero()) + return; // Avoid division by zero + BoundingBox parentBox = parent->GetBox(); + for (const Actor* sibling : parent->Children) + { + if (sibling != this) + BoundingBox::Merge(parentBox, sibling->GetBoxWithChildren(), parentBox); + } + const Vector3 parentSize = parentBox.GetSize(); + const Vector3 parentCenter = parentBox.GetCenter() - parent->GetPosition(); + + // Update bounds + SetLocalPosition(Vector3::Zero); + SetSize(parentSize / parentScale); + SetCenter(parentCenter / parentScale); + SetOrientation(GetOrientation() * Quaternion::Invert(GetOrientation())); +} + #if USE_EDITOR #include "Engine/Debug/DebugDraw.h" diff --git a/Source/Engine/Physics/Colliders/BoxCollider.h b/Source/Engine/Physics/Colliders/BoxCollider.h index 5bcc21b45..3c15ce640 100644 --- a/Source/Engine/Physics/Colliders/BoxCollider.h +++ b/Source/Engine/Physics/Colliders/BoxCollider.h @@ -43,6 +43,11 @@ public: return _bounds; } + /// + /// Resizes the collider based on the bounds of it's parent to contain it whole (including any siblings). + /// + API_FUNCTION() void AutoResize(); + public: // [Collider] #if USE_EDITOR From 51fc4c68cdb8382579af5fe07798ff703b1c586c Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Thu, 14 Dec 2023 11:04:24 +0100 Subject: [PATCH 8/8] Use tooltip from native function docs and support multiple colliders selected at once #2063 --- .../SceneGraph/Actors/BoxColliderNode.cs | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/Source/Editor/SceneGraph/Actors/BoxColliderNode.cs b/Source/Editor/SceneGraph/Actors/BoxColliderNode.cs index 8c00318db..566cefb5e 100644 --- a/Source/Editor/SceneGraph/Actors/BoxColliderNode.cs +++ b/Source/Editor/SceneGraph/Actors/BoxColliderNode.cs @@ -7,15 +7,12 @@ using Real = System.Single; #endif using FlaxEngine; - -#if FLAX_EDITOR using FlaxEditor.CustomEditors.Dedicated; using FlaxEditor.CustomEditors; -#endif +using FlaxEditor.Scripting; namespace FlaxEditor.SceneGraph.Actors { -#if FLAX_EDITOR /// /// Dedicated custom editor for BoxCollider objects. /// @@ -26,14 +23,20 @@ namespace FlaxEditor.SceneGraph.Actors public override void Initialize(LayoutElementsContainer layout) { base.Initialize(layout); - layout.Space(20f); - var autoResizeButton = layout.Button("Resize to Fit", "Resize the box collider to fit it's parent's bounds."); - BoxCollider collider = Values[0] as BoxCollider; - autoResizeButton.Button.Clicked += collider.AutoResize; + layout.Space(20f); + layout.Button("Resize to Fit", Editor.Instance.CodeDocs.GetTooltip(new ScriptMemberInfo(typeof(BoxCollider).GetMethod("AutoResize")))).Button.Clicked += OnResizeClicked; + } + + private void OnResizeClicked() + { + foreach (var value in Values) + { + if (value is BoxCollider collider) + collider.AutoResize(); + } } } -#endif /// /// Scene tree node for actor type. @@ -67,8 +70,8 @@ namespace FlaxEditor.SceneGraph.Actors public override void PostSpawn() { base.PostSpawn(); - BoxCollider boxCollider = Actor as BoxCollider; - boxCollider.AutoResize(); + + ((BoxCollider)Actor).AutoResize(); } } }