Add material drag drop to animated models (with highlight)

This commit is contained in:
2026-08-08 06:43:13 +02:00
parent 59227bbc8b
commit 7a67864136
2 changed files with 57 additions and 14 deletions
@@ -41,7 +41,7 @@ namespace FlaxEditor.Viewport
private readonly DragActorType<DragDropEventArgs> _dragActorType;
private readonly DragScriptItems<DragDropEventArgs> _dragScriptItem;
private StaticModel _previewStaticModel;
private ModelInstanceActor _previewModel;
private int _previewModelEntryIndex;
private BrushSurface _previewBrushSurface;
@@ -56,15 +56,15 @@ namespace FlaxEditor.Viewport
internal void ClearDragEffects()
{
_previewStaticModel = null;
_previewModel = null;
_previewModelEntryIndex = -1;
_previewBrushSurface = new BrushSurface();
}
internal void CollectDrawCalls(ViewportDebugDrawData debugDrawData, ref RenderContext renderContext)
{
if (_previewStaticModel)
debugDrawData.HighlightModel(_previewStaticModel, _previewModelEntryIndex);
if (_previewModel)
debugDrawData.HighlightModel(_previewModel, _previewModelEntryIndex);
if (_previewBrushSurface.Brush)
debugDrawData.HighlightBrushSurface(_previewBrushSurface);
}
@@ -127,11 +127,18 @@ namespace FlaxEditor.Viewport
return;
}
// TODO: refactor this to be handled by ActorNode itself for generic actor highlights
if (hit is StaticModelNode staticModelNode)
{
_previewStaticModel = (StaticModel)staticModelNode.Actor;
_previewModel = (StaticModel)staticModelNode.Actor;
var ray = _viewport.ConvertMouseToRay(ref location);
_previewStaticModel.IntersectsEntry(ref ray, out _, out _, out _previewModelEntryIndex);
_previewModel.IntersectsEntry(ref ray, out _, out _, out _previewModelEntryIndex);
}
else if (hit is AnimatedModelNode animatedModelNode)
{
_previewModel = (AnimatedModel)animatedModelNode.Actor;
var ray = _viewport.ConvertMouseToRay(ref location);
_previewModel.IntersectsEntry(ref ray, out _, out _, out _previewModelEntryIndex);
}
else if (hit is BoxBrushNode.SideLinkNode brushSurfaceNode)
{
@@ -251,14 +258,25 @@ namespace FlaxEditor.Viewport
};
Spawn(actor, ref hitLocation, ref hitNormal);
}
// TODO: refactor this to be handled by ActorNode itself for generic actor highlights
else if (hit is StaticModelNode staticModelNode)
{
var staticModel = (StaticModel)staticModelNode.Actor;
var actor = (StaticModel)staticModelNode.Actor;
var ray = _viewport.ConvertMouseToRay(ref location);
if (staticModel.IntersectsEntry(ref ray, out _, out _, out var entryIndex))
if (actor.IntersectsEntry(ref ray, out _, out _, out var entryIndex))
{
using (new UndoBlock(_owner.Undo, staticModel, "Change material"))
staticModel.SetMaterial(entryIndex, material);
using (new UndoBlock(_owner.Undo, actor, "Change material"))
actor.SetMaterial(entryIndex, material);
}
}
else if (hit is AnimatedModelNode animatedModelNode)
{
var actor = (AnimatedModel)animatedModelNode.Actor;
var ray = _viewport.ConvertMouseToRay(ref location);
if (actor.IntersectsEntry(ref ray, out _, out _, out var entryIndex))
{
using (new UndoBlock(_owner.Undo, actor, "Change material"))
actor.SetMaterial(entryIndex, material);
}
}
else if (hit is BoxBrushNode.SideLinkNode brushSurfaceNode)
+29 -4
View File
@@ -50,11 +50,10 @@ namespace FlaxEditor
/// Highlights the model.
/// </summary>
/// <param name="model">The model.</param>
public void HighlightModel(StaticModel model)
public void HighlightModel(ModelInstanceActor model)
{
if (model.Model == null)
if (!model)
return;
var entries = model.Entries;
for (var i = 0; i < entries.Length; i++)
HighlightModel(model, i);
@@ -65,7 +64,7 @@ namespace FlaxEditor
/// </summary>
/// <param name="model">The model.</param>
/// <param name="entryIndex">Index of the entry to highlight.</param>
public void HighlightModel(StaticModel model, int entryIndex)
public void HighlightModel(ModelInstanceActor model, int entryIndex)
{
_highlights.Add(new HighlightData
{
@@ -144,6 +143,32 @@ namespace FlaxEditor
}
}
}
else if (highlight.Target is AnimatedModel animatedModel)
{
var model = animatedModel.SkinnedModel;
if (model == null)
continue;
animatedModel.Transform.GetWorld(out world);
var bounds = BoundingSphere.FromBox(animatedModel.Box);
var bones = animatedModel.SkinnedMeshBones;
// Pick a proper LOD
Float3 center = bounds.Center - renderContext.View.Origin;
int lodIndex = RenderTools.ComputeModelLOD(model, ref center, (float)bounds.Radius, ref renderContext);
var lods = model.LODs;
if (lods == null || lods.Length < lodIndex || lodIndex < 0)
continue;
var lod = lods[lodIndex];
// Draw meshes
for (int meshIndex = 0; meshIndex < lod.Meshes.Length; meshIndex++)
{
if (lod.Meshes[meshIndex].MaterialSlotIndex == highlight.EntryIndex)
{
lod.Meshes[meshIndex].Draw(ref renderContext, bones, _highlightMaterial, ref world);
}
}
}
}
if (_highlightTriangles.Count > 0)