diff --git a/Source/Editor/Content/Proxy/PrefabProxy.cs b/Source/Editor/Content/Proxy/PrefabProxy.cs
index d597919ff..81d0ba8c6 100644
--- a/Source/Editor/Content/Proxy/PrefabProxy.cs
+++ b/Source/Editor/Content/Proxy/PrefabProxy.cs
@@ -164,7 +164,7 @@ namespace FlaxEditor.Content
// Auto fit actor to camera
float targetSize = 30.0f;
- Editor.GetActorEditorBox(_preview.Instance, out var bounds);
+ var bounds = _preview.Instance.EditorBoxChildren;
float maxSize = Mathf.Max(0.001f, bounds.Size.MaxValue);
_preview.Instance.Scale = new Vector3(targetSize / maxSize);
_preview.Instance.Position = Vector3.Zero;
diff --git a/Source/Editor/Editor.cs b/Source/Editor/Editor.cs
index d96f6f55f..40923e97f 100644
--- a/Source/Editor/Editor.cs
+++ b/Source/Editor/Editor.cs
@@ -917,23 +917,6 @@ namespace FlaxEditor
}
}
- ///
- /// Gets the actor bounding box (including child actors).
- ///
- /// The actor.
- /// The bounding box.
- public static void GetActorEditorBox(Actor actor, out BoundingBox box)
- {
- if (actor)
- {
- Internal_GetEditorBoxWithChildren(FlaxEngine.Object.GetUnmanagedPtr(actor), out box);
- }
- else
- {
- box = BoundingBox.Zero;
- }
- }
-
///
/// Closes editor splash screen popup window.
///
diff --git a/Source/Editor/Gizmo/TransformGizmo.cs b/Source/Editor/Gizmo/TransformGizmo.cs
index feed70b57..db4c0aa1d 100644
--- a/Source/Editor/Gizmo/TransformGizmo.cs
+++ b/Source/Editor/Gizmo/TransformGizmo.cs
@@ -85,6 +85,56 @@ namespace FlaxEditor.Gizmo
return node;
}
+ ///
+ public override void SnapToGround()
+ {
+ if (Owner.SceneGraphRoot == null)
+ return;
+ var ray = new Ray(Position, Vector3.Down);
+ while (true)
+ {
+ var view = new Ray(Owner.ViewPosition, Owner.ViewDirection);
+ var rayCastFlags = SceneGraphNode.RayCastData.FlagTypes.SkipEditorPrimitives;
+ var hit = Owner.SceneGraphRoot.RayCast(ref ray, ref view, out var distance, out _, rayCastFlags);
+ if (hit != null)
+ {
+ // Skip snapping selection to itself
+ bool isSelected = false;
+ for (var e = hit; e != null && !isSelected; e = e.ParentNode)
+ isSelected |= IsSelected(e);
+ if (isSelected)
+ {
+ GetSelectedObjectsBounds(out var selectionBounds, out _);
+ ray.Position = ray.GetPoint(selectionBounds.Size.Y * 0.5f);
+ continue;
+ }
+
+ // Include objects bounds into target snap location
+ var editorBounds = BoundingBox.Empty;
+ var bottomToCenter = 100000.0f;
+ for (int i = 0; i < _selectionParents.Count; i++)
+ {
+ if (_selectionParents[i] is ActorNode actorNode)
+ {
+ var b = actorNode.Actor.EditorBoxChildren;
+ BoundingBox.Merge(ref editorBounds, ref b, out editorBounds);
+ bottomToCenter = Mathf.Min(bottomToCenter, actorNode.Actor.Position.Y - editorBounds.Minimum.Y);
+ }
+ }
+ var newPosition = ray.GetPoint(distance) + new Vector3(0, bottomToCenter, 0);
+
+ // Snap
+ StartTransforming();
+ var translationDelta = newPosition - Position;
+ var rotationDelta = Quaternion.Identity;
+ var scaleDelta = Vector3.Zero;
+ OnApplyTransformation(ref translationDelta, ref rotationDelta, ref scaleDelta);
+ EndTransforming();
+ }
+ break;
+ }
+ }
+
///
public override void Pick()
{
@@ -211,10 +261,7 @@ namespace FlaxEditor.Gizmo
if (_selectionParents[i] is ActorNode actorNode)
{
bounds = BoundingBox.Merge(bounds, actorNode.Actor.BoxWithChildren);
- if (actorNode.AffectsNavigationWithChildren)
- {
- navigationDirty |= actorNode.Actor.HasStaticFlag(StaticFlags.Navigation);
- }
+ navigationDirty |= actorNode.AffectsNavigationWithChildren;
}
}
}
diff --git a/Source/Editor/Gizmo/TransformGizmoBase.cs b/Source/Editor/Gizmo/TransformGizmoBase.cs
index 518b312ad..d0b10f2a8 100644
--- a/Source/Editor/Gizmo/TransformGizmoBase.cs
+++ b/Source/Editor/Gizmo/TransformGizmoBase.cs
@@ -510,42 +510,6 @@ namespace FlaxEditor.Gizmo
UpdateMatrices();
}
- ///
- public override void SnapToGround()
- {
- if (Owner.SceneGraphRoot == null)
- return;
- var ray = new Ray(Position, Vector3.Down);
- while (true)
- {
- var view = new Ray(Owner.ViewPosition, Owner.ViewDirection);
- var rayCastFlags = SceneGraphNode.RayCastData.FlagTypes.SkipEditorPrimitives;
- var hit = Owner.SceneGraphRoot.RayCast(ref ray, ref view, out var distance, out _, rayCastFlags);
- if (hit != null)
- {
- // Skip snapping selection to itself
- bool isSelected = false;
- for (var e = hit; e != null && !isSelected; e = e.ParentNode)
- isSelected |= IsSelected(e);
- if (isSelected)
- {
- GetSelectedObjectsBounds(out var selectionBounds, out _);
- ray.Position = ray.GetPoint(selectionBounds.Size.Y * 0.5f);
- continue;
- }
-
- // Snap
- StartTransforming();
- var translationDelta = ray.GetPoint(distance) - Position;
- var rotationDelta = Quaternion.Identity;
- var scaleDelta = Vector3.Zero;
- OnApplyTransformation(ref translationDelta, ref rotationDelta, ref scaleDelta);
- EndTransforming();
- }
- break;
- }
- }
-
///
/// Gets a value indicating whether this tool can transform objects.
///
diff --git a/Source/Editor/Tools/Foliage/EditFoliageGizmo.cs b/Source/Editor/Tools/Foliage/EditFoliageGizmo.cs
index 5401000c9..e965532c7 100644
--- a/Source/Editor/Tools/Foliage/EditFoliageGizmo.cs
+++ b/Source/Editor/Tools/Foliage/EditFoliageGizmo.cs
@@ -86,6 +86,13 @@ namespace FlaxEditor.Tools.Foliage
{
bounds = BoundingBox.Empty;
navigationDirty = false;
+ var foliage = GizmoMode.SelectedFoliage;
+ var instanceIndex = GizmoMode.SelectedInstanceIndex;
+ if (foliage && instanceIndex >= 0 && instanceIndex < foliage.InstancesCount)
+ {
+ var instance = foliage.GetInstance(instanceIndex);
+ BoundingBox.FromSphere(ref instance.Bounds, out bounds);
+ }
}
///
diff --git a/Source/Editor/Viewport/MainEditorGizmoViewport.cs b/Source/Editor/Viewport/MainEditorGizmoViewport.cs
index 4bf399bd8..268d55492 100644
--- a/Source/Editor/Viewport/MainEditorGizmoViewport.cs
+++ b/Source/Editor/Viewport/MainEditorGizmoViewport.cs
@@ -887,11 +887,15 @@ namespace FlaxEditor.Viewport
private Vector3 PostProcessSpawnedActorLocation(Actor actor, ref Vector3 hitLocation)
{
- Editor.GetActorEditorBox(actor, out _);
+ // Refresh actor position to ensure that cached bounds are valid
+ actor.Position = Vector3.One;
+ actor.Position = Vector3.Zero;
// Place the object
//var location = hitLocation - (box.Size.Length * 0.5f) * ViewDirection;
- var location = hitLocation;
+ var editorBounds = actor.EditorBoxChildren;
+ var bottomToCenter = actor.Position.Y - editorBounds.Minimum.Y;
+ var location = hitLocation + new Vector3(0, bottomToCenter, 0);
// Apply grid snapping if enabled
if (UseSnapping || TransformGizmo.TranslationSnapEnable)
diff --git a/Source/Editor/Viewport/PrefabWindowViewport.cs b/Source/Editor/Viewport/PrefabWindowViewport.cs
index 0ed67ab8e..c83e738f3 100644
--- a/Source/Editor/Viewport/PrefabWindowViewport.cs
+++ b/Source/Editor/Viewport/PrefabWindowViewport.cs
@@ -702,10 +702,9 @@ namespace FlaxEditor.Viewport
private Vector3 PostProcessSpawnedActorLocation(Actor actor, ref Vector3 hitLocation)
{
- Editor.GetActorEditorBox(actor, out BoundingBox box);
-
// Place the object
- var location = hitLocation - (box.Size.Length * 0.5f) * ViewDirection;
+ //var location = hitLocation - (box.Size.Length * 0.5f) * ViewDirection;
+ var location = hitLocation;
// Apply grid snapping if enabled
if (UseSnapping || TransformGizmo.TranslationSnapEnable)
diff --git a/Source/Engine/Level/Actors/AnimatedModel.cpp b/Source/Engine/Level/Actors/AnimatedModel.cpp
index 9fc6672d1..17e59e37c 100644
--- a/Source/Engine/Level/Actors/AnimatedModel.cpp
+++ b/Source/Engine/Level/Actors/AnimatedModel.cpp
@@ -745,6 +745,13 @@ void AnimatedModel::OnDebugDrawSelected()
ModelInstanceActor::OnDebugDrawSelected();
}
+BoundingBox AnimatedModel::GetEditorBox() const
+{
+ if (SkinnedModel)
+ SkinnedModel->WaitForLoaded(100);
+ return BoundingBox::MakeScaled(_box, 1.0f / BoundsScale);
+}
+
#endif
bool AnimatedModel::IntersectsItself(const Ray& ray, float& distance, Vector3& normal)
diff --git a/Source/Engine/Level/Actors/AnimatedModel.h b/Source/Engine/Level/Actors/AnimatedModel.h
index f3eb2500b..eec987831 100644
--- a/Source/Engine/Level/Actors/AnimatedModel.h
+++ b/Source/Engine/Level/Actors/AnimatedModel.h
@@ -378,6 +378,7 @@ public:
void DrawGeneric(RenderContext& renderContext) override;
#if USE_EDITOR
void OnDebugDrawSelected() override;
+ BoundingBox GetEditorBox() const override;
#endif
bool IntersectsItself(const Ray& ray, float& distance, Vector3& normal) override;
void Serialize(SerializeStream& stream, const void* otherObj) override;
diff --git a/Source/Engine/Level/Actors/Decal.cpp b/Source/Engine/Level/Actors/Decal.cpp
index 994b0fb72..200a635da 100644
--- a/Source/Engine/Level/Actors/Decal.cpp
+++ b/Source/Engine/Level/Actors/Decal.cpp
@@ -58,6 +58,12 @@ void Decal::OnDebugDrawSelected()
Actor::OnDebugDrawSelected();
}
+BoundingBox Decal::GetEditorBox() const
+{
+ const Vector3 size(10.0f);
+ return BoundingBox(_transform.Translation - size, _transform.Translation + size);
+}
+
#endif
void Decal::OnLayerChanged()
diff --git a/Source/Engine/Level/Actors/Decal.h b/Source/Engine/Level/Actors/Decal.h
index 7bff6dbff..f026da8bb 100644
--- a/Source/Engine/Level/Actors/Decal.h
+++ b/Source/Engine/Level/Actors/Decal.h
@@ -77,6 +77,7 @@ public:
// [Actor]
#if USE_EDITOR
void OnDebugDrawSelected() override;
+ BoundingBox GetEditorBox() const override;
#endif
void OnLayerChanged() override;
void Draw(RenderContext& renderContext) override;