Add decals spawning in editor for drag&drop

This commit is contained in:
2022-01-10 17:47:10 +01:00
parent d11166082c
commit 7dd97a2d9f
3 changed files with 42 additions and 20 deletions
+10
View File
@@ -120,6 +120,16 @@ namespace FlaxEditor.SceneGraph
return RayCast(ref data, out distance, out normal);
}
internal static Quaternion RaycastNormalRotation(ref Vector3 normal)
{
Quaternion rotation;
if (normal == Vector3.Down)
rotation = Quaternion.RotationZ(Mathf.Pi);
else
rotation = Quaternion.LookRotation(Vector3.Cross(Vector3.Cross(normal, Vector3.Forward), normal), normal);
return rotation;
}
/// <inheritdoc />
public override bool RayCastSelf(ref RayCastData ray, out float distance, out Vector3 normal)
{
+1 -5
View File
@@ -634,11 +634,7 @@ namespace FlaxEditor.Tools
{
_brushMaterial.SetParameterValue("Color", new Color(1.0f, 0.85f, 0.0f)); // TODO: expose to editor options
_brushMaterial.SetParameterValue("DepthBuffer", Owner.RenderTask.Buffers.DepthBuffer);
Quaternion rotation;
if (_hitNormal == Vector3.Down)
rotation = Quaternion.RotationZ(Mathf.Pi);
else
rotation = Quaternion.LookRotation(Vector3.Cross(Vector3.Cross(_hitNormal, Vector3.Forward), _hitNormal), _hitNormal);
Quaternion rotation = RootNode.RaycastNormalRotation(ref _hitNormal);
Matrix transform = Matrix.Scaling(_gizmoMode.BrushSize * 0.01f) * Matrix.RotationQuaternion(rotation) * Matrix.Translation(_hitLocation);
_brushModel.Draw(ref renderContext, _brushMaterial, ref transform);
}
@@ -770,28 +770,31 @@ namespace FlaxEditor.Viewport
base.OnLeftMouseButtonUp();
}
private void GetHitLocation(ref Vector2 location, out SceneGraphNode hit, out Vector3 hitLocation)
private void GetHitLocation(ref Vector2 location, out SceneGraphNode hit, out Vector3 hitLocation, out Vector3 hitNormal)
{
// Get mouse ray and try to hit any object
var ray = ConvertMouseToRay(ref location);
var view = new Ray(ViewPosition, ViewDirection);
var gridPlane = new Plane(Vector3.Zero, Vector3.Up);
var flags = SceneGraphNode.RayCastData.FlagTypes.SkipColliders | SceneGraphNode.RayCastData.FlagTypes.SkipEditorPrimitives;
hit = Editor.Instance.Scene.Root.RayCast(ref ray, ref view, out var closest, flags);
hit = Editor.Instance.Scene.Root.RayCast(ref ray, ref view, out var closest, out var normal, flags);
if (hit != null)
{
// Use hit location
hitLocation = ray.Position + ray.Direction * closest;
hitNormal = normal;
}
else if (Grid.Enabled && CollisionsHelper.RayIntersectsPlane(ref ray, ref gridPlane, out closest) && closest < 4000.0f)
{
// Use grid location
hitLocation = ray.Position + ray.Direction * closest;
hitNormal = Vector3.Up;
}
else
{
// Use area in front of the viewport
hitLocation = ViewPosition + ViewDirection * 100;
hitNormal = Vector3.Up;
}
}
@@ -799,8 +802,11 @@ namespace FlaxEditor.Viewport
{
if (_dragAssets.HasValidDrag && _dragAssets.Objects[0].IsOfType<MaterialBase>())
{
GetHitLocation(ref location, out var hit, out _);
GetHitLocation(ref location, out var hit, out _, out _);
ClearDragEffects();
var material = FlaxEngine.Content.LoadAsync<MaterialBase>(_dragAssets.Objects[0].ID);
if (material.IsDecal)
return;
if (hit is StaticModelNode staticModelNode)
{
@@ -910,7 +916,7 @@ namespace FlaxEditor.Viewport
return location;
}
private void Spawn(Actor actor, ref Vector3 hitLocation)
private void Spawn(Actor actor, ref Vector3 hitLocation, ref Vector3 hitNormal)
{
actor.Position = PostProcessSpawnedActorLocation(actor, ref hitLocation);
var parent = actor.Parent ?? Level.GetScene(0);
@@ -919,24 +925,34 @@ namespace FlaxEditor.Viewport
Focus();
}
private void Spawn(AssetItem item, SceneGraphNode hit, ref Vector2 location, ref Vector3 hitLocation)
private void Spawn(AssetItem item, SceneGraphNode hit, ref Vector2 location, ref Vector3 hitLocation, ref Vector3 hitNormal)
{
if (item.IsOfType<MaterialBase>())
{
if (hit is StaticModelNode staticModelNode)
var material = FlaxEngine.Content.LoadAsync<MaterialBase>(item.ID);
if (material && !material.WaitForLoaded(100) && material.IsDecal)
{
var actor = new Decal
{
Material = material,
LocalOrientation = RootNode.RaycastNormalRotation(ref hitNormal),
Name = item.ShortName
};
DebugDraw.DrawWireArrow(PostProcessSpawnedActorLocation(actor, ref hitNormal), actor.LocalOrientation, 1.0f, Color.Red, 1000000);
Spawn(actor, ref hitLocation, ref hitNormal);
}
else if (hit is StaticModelNode staticModelNode)
{
var staticModel = (StaticModel)staticModelNode.Actor;
var ray = ConvertMouseToRay(ref location);
if (staticModel.IntersectsEntry(ref ray, out _, out _, out var entryIndex))
{
var material = FlaxEngine.Content.LoadAsync<MaterialBase>(item.ID);
using (new UndoBlock(Undo, staticModel, "Change material"))
staticModel.SetMaterial(entryIndex, material);
}
}
else if (hit is BoxBrushNode.SideLinkNode brushSurfaceNode)
{
var material = FlaxEngine.Content.LoadAsync<MaterialBase>(item.ID);
using (new UndoBlock(Undo, brushSurfaceNode.Brush, "Change material"))
{
var surface = brushSurfaceNode.Surface;
@@ -954,11 +970,11 @@ namespace FlaxEditor.Viewport
{
var actor = item.OnEditorDrop(this);
actor.Name = item.ShortName;
Spawn(actor, ref hitLocation);
Spawn(actor, ref hitLocation, ref hitNormal);
}
}
private void Spawn(ScriptType item, SceneGraphNode hit, ref Vector2 location, ref Vector3 hitLocation)
private void Spawn(ScriptType item, SceneGraphNode hit, ref Vector2 location, ref Vector3 hitLocation, ref Vector3 hitNormal)
{
var actor = item.CreateInstance() as Actor;
if (actor == null)
@@ -967,7 +983,7 @@ namespace FlaxEditor.Viewport
return;
}
actor.Name = item.Name;
Spawn(actor, ref hitLocation);
Spawn(actor, ref hitLocation, ref hitNormal);
}
/// <inheritdoc />
@@ -980,11 +996,11 @@ namespace FlaxEditor.Viewport
return result;
// Check if drag sth
Vector3 hitLocation = ViewPosition;
Vector3 hitLocation = ViewPosition, hitNormal = -ViewDirection;
SceneGraphNode hit = null;
if (DragHandlers.HasValidDrag)
{
GetHitLocation(ref location, out hit, out hitLocation);
GetHitLocation(ref location, out hit, out hitLocation, out hitNormal);
}
// Drag assets
@@ -996,7 +1012,7 @@ namespace FlaxEditor.Viewport
for (int i = 0; i < _dragAssets.Objects.Count; i++)
{
var item = _dragAssets.Objects[i];
Spawn(item, hit, ref location, ref hitLocation);
Spawn(item, hit, ref location, ref hitLocation, ref hitNormal);
}
}
// Drag actor type
@@ -1008,7 +1024,7 @@ namespace FlaxEditor.Viewport
for (int i = 0; i < _dragActorType.Objects.Count; i++)
{
var item = _dragActorType.Objects[i];
Spawn(item, hit, ref location, ref hitLocation);
Spawn(item, hit, ref location, ref hitLocation, ref hitNormal);
}
}