Add improvements for objects spawning and snapping in Editor to include object bounds
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -917,23 +917,6 @@ namespace FlaxEditor
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the actor bounding box (including child actors).
|
||||
/// </summary>
|
||||
/// <param name="actor">The actor.</param>
|
||||
/// <param name="box">The bounding box.</param>
|
||||
public static void GetActorEditorBox(Actor actor, out BoundingBox box)
|
||||
{
|
||||
if (actor)
|
||||
{
|
||||
Internal_GetEditorBoxWithChildren(FlaxEngine.Object.GetUnmanagedPtr(actor), out box);
|
||||
}
|
||||
else
|
||||
{
|
||||
box = BoundingBox.Zero;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Closes editor splash screen popup window.
|
||||
/// </summary>
|
||||
|
||||
@@ -85,6 +85,56 @@ namespace FlaxEditor.Gizmo
|
||||
return node;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -510,42 +510,6 @@ namespace FlaxEditor.Gizmo
|
||||
UpdateMatrices();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this tool can transform objects.
|
||||
/// </summary>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user