Merge remote-tracking branch 'origin/master'

# Conflicts:
#	Source/Editor/Viewport/MainEditorGizmoViewport.cs
This commit is contained in:
Wojtek Figat
2025-03-16 23:21:32 +01:00
5 changed files with 82 additions and 57 deletions

View File

@@ -35,7 +35,7 @@ namespace FlaxEditor.Gizmo
/// <inheritdoc />
public EditorPrimitives()
{
Order = -100;
Order = 100;
}
/// <inheritdoc />

View File

@@ -11,7 +11,7 @@ namespace FlaxEngine.Gizmo;
/// <summary>
/// Class for adding viewport rubber band selection.
/// </summary>
public class ViewportRubberBandSelector
public sealed class ViewportRubberBandSelector
{
private bool _isMosueCaptured;
private bool _isRubberBandSpanning;
@@ -232,30 +232,15 @@ public class ViewportRubberBandSelector
}
/// <summary>
/// Used to draw the rubber band. Begins render 2D.
/// Draws the ruber band during owner viewport UI drawing.
/// </summary>
/// <param name="context">The GPU Context.</param>
/// <param name="target">The GPU texture target.</param>
/// <param name="targetDepth">The GPU texture target depth.</param>
public void Draw(GPUContext context, GPUTexture target, GPUTexture targetDepth)
{
// Draw RubberBand for rect selection
if (!_isRubberBandSpanning)
return;
Render2D.Begin(context, target, targetDepth);
Draw2D();
Render2D.End();
}
/// <summary>
/// Used to draw the rubber band. Use if already rendering 2D context.
/// </summary>
public void Draw2D()
public void Draw()
{
if (!_isRubberBandSpanning)
return;
Render2D.FillRectangle(_rubberBandRect, Style.Current.Selection);
Render2D.DrawRectangle(_rubberBandRect, Style.Current.SelectionBorder);
var style = Style.Current;
Render2D.FillRectangle(_rubberBandRect, style.Selection);
Render2D.DrawRectangle(_rubberBandRect, style.SelectionBorder);
}
/// <summary>

View File

@@ -166,7 +166,6 @@ namespace FlaxEditor.SceneGraph.Actors
var actor = new BoxCollider
{
StaticFlags = staticModelNode.Actor.StaticFlags,
Transform = staticModelNode.Actor.Transform,
};
staticModelNode.Root.Spawn(actor, staticModelNode.Actor);
createdNodes.Add(window is PrefabWindow pWindow ? pWindow.Graph.Root.Find(actor) : Editor.Instance.Scene.GetActorNode(actor));
@@ -177,7 +176,6 @@ namespace FlaxEditor.SceneGraph.Actors
var actor = new SphereCollider
{
StaticFlags = staticModelNode.Actor.StaticFlags,
Transform = staticModelNode.Actor.Transform,
};
staticModelNode.Root.Spawn(actor, staticModelNode.Actor);
createdNodes.Add(window is PrefabWindow pWindow ? pWindow.Graph.Root.Find(actor) : Editor.Instance.Scene.GetActorNode(actor));
@@ -188,7 +186,6 @@ namespace FlaxEditor.SceneGraph.Actors
var actor = new BoxCollider
{
StaticFlags = staticModelNode.Actor.StaticFlags,
Transform = staticModelNode.Actor.Transform,
Size = new Float3(100.0f, 100.0f, 1.0f),
};
staticModelNode.Root.Spawn(actor, staticModelNode.Actor);
@@ -200,7 +197,6 @@ namespace FlaxEditor.SceneGraph.Actors
var actor = new CapsuleCollider
{
StaticFlags = staticModelNode.Actor.StaticFlags,
Transform = staticModelNode.Actor.Transform,
Radius = 25.0f,
Height = 50.0f,
};
@@ -217,7 +213,6 @@ namespace FlaxEditor.SceneGraph.Actors
var actor = new MeshCollider
{
StaticFlags = staticModelNode.Actor.StaticFlags,
Transform = staticModelNode.Actor.Transform,
CollisionData = collisionData,
};
staticModelNode.Root.Spawn(actor, staticModelNode.Actor);

View File

@@ -371,9 +371,6 @@ namespace FlaxEditor.Viewport
Gizmos[i].Draw(ref renderContext);
}
// Draw RubberBand for rect selection
_rubberBandSelector.Draw(context, target, targetDepth);
// Draw selected objects debug shapes and visuals
if (DrawDebugDraw && (renderContext.View.Flags & ViewFlags.DebugDraw) == ViewFlags.DebugDraw)
{
@@ -589,6 +586,15 @@ namespace FlaxEditor.Viewport
}
}
/// <inheritdoc />
public override void Draw()
{
base.Draw();
// Draw rubber band for rectangle selection
_rubberBandSelector.Draw();
}
/// <inheritdoc />
protected override void OrientViewport(ref Quaternion orientation)
{

View File

@@ -24,6 +24,7 @@
#include "Engine/Level/Scripts/ModelPrefab.h"
#include "Engine/Platform/FileSystem.h"
#include "Engine/Utilities/RectPack.h"
#include "Engine/Scripting/Scripting.h"
#include "Engine/Profiler/ProfilerCPU.h"
#include "AssetsImportingManager.h"
@@ -169,6 +170,33 @@ bool SortMeshGroups(IGrouping<StringView, MeshData*> const& i1, IGrouping<String
return i1.GetKey().Compare(i2.GetKey()) < 0;
}
void CloneObject(rapidjson_flax::StringBuffer& buffer, SceneObject* src, SceneObject* dst, bool stripName = false)
{
// Serialize source
buffer.Clear();
CompactJsonWriter writer(buffer);
writer.StartObject();
const void* defaultInstance = src->GetType().GetDefaultInstance();
src->Serialize(writer, defaultInstance);
writer.EndObject();
// Parse json
rapidjson_flax::Document document;
document.Parse(buffer.GetString(), buffer.GetSize());
// Strip unwanted data
document.RemoveMember("ID");
document.RemoveMember("ParentID");
document.RemoveMember("PrefabID");
document.RemoveMember("PrefabObjectID");
if (stripName)
document.RemoveMember("Name");
// Deserialize destination
auto modifier = Cache::ISerializeModifier.Get();
dst->Deserialize(document, &*modifier);
}
CreateAssetResult ImportModel::Import(CreateAssetContext& context)
{
// Get import options
@@ -677,6 +705,8 @@ CreateAssetResult ImportModel::CreatePrefab(CreateAssetContext& context, ModelDa
// Create prefab structure
Dictionary<int32, Actor*> nodeToActor;
Dictionary<Guid, SceneObject*> newPrefabObjects; // Maps prefab object id to the restored and linked object
rapidjson_flax::StringBuffer jsonBuffer;
Array<Actor*> nodeActors;
Actor* rootActor = nullptr;
for (int32 nodeIndex = 0; nodeIndex < data.Nodes.Count(); nodeIndex++)
@@ -767,7 +797,6 @@ CreateAssetResult ImportModel::CreatePrefab(CreateAssetContext& context, ModelDa
// Link with object from prefab (if reimporting)
if (prefab)
{
rapidjson_flax::StringBuffer buffer;
for (Actor* a : nodeActors)
{
for (const auto& i : prefab->ObjectsCache)
@@ -779,33 +808,12 @@ CreateAssetResult ImportModel::CreatePrefab(CreateAssetContext& context, ModelDa
continue;
// Preserve local changes made in the prefab
{
// Serialize
buffer.Clear();
CompactJsonWriter writer(buffer);
writer.StartObject();
const void* defaultInstance = o->GetType().GetDefaultInstance();
o->Serialize(writer, defaultInstance);
writer.EndObject();
// Parse json
rapidjson_flax::Document document;
document.Parse(buffer.GetString(), buffer.GetSize());
// Strip unwanted data
document.RemoveMember("ID");
document.RemoveMember("ParentID");
document.RemoveMember("PrefabID");
document.RemoveMember("PrefabObjectID");
document.RemoveMember("Name");
// Deserialize object
auto modifier = Cache::ISerializeModifier.Get();
a->Deserialize(document, &*modifier);
}
CloneObject(jsonBuffer, o, a, true);
// Mark as this object already exists in prefab so will be preserved when updating it
a->LinkPrefab(o->GetPrefabID(), o->GetPrefabObjectID());
const Guid prefabObjectId = o->GetPrefabObjectID();
a->LinkPrefab(o->GetPrefabID(), prefabObjectId);
newPrefabObjects.Add(prefabObjectId, a);
break;
}
}
@@ -826,12 +834,43 @@ CreateAssetResult ImportModel::CreatePrefab(CreateAssetContext& context, ModelDa
{
if (i.Value->GetTypeHandle() == modelPrefabScript->GetTypeHandle())
{
modelPrefabScript->LinkPrefab(i.Value->GetPrefabID(), i.Value->GetPrefabObjectID());
const Guid prefabObjectId = i.Value->GetPrefabObjectID();
modelPrefabScript->LinkPrefab(i.Value->GetPrefabID(), prefabObjectId);
newPrefabObjects.Add(prefabObjectId, modelPrefabScript);
break;
}
}
}
}
if (prefab)
{
// Preserve existing objects added by user (eg. colliders, sfx, vfx, scripts)
for (const auto& i : prefab->ObjectsCache)
{
// Skip already restored objects
const Guid prefabObjectId = i.Key;
if (newPrefabObjects.ContainsKey(prefabObjectId))
continue;
SceneObject* defaultObject = i.Value;
// TODO: ignore objects that were imported previously but not now (eg. mesh was removed from source asset)
// Find parent to link
SceneObject* parent;
if (!newPrefabObjects.TryGet(defaultObject->GetParent()->GetPrefabObjectID(), parent))
continue;
// Duplicate object
SceneObject* restoredObject = (SceneObject*)Scripting::NewObject(defaultObject->GetTypeHandle());
if (!restoredObject)
continue;
CloneObject(jsonBuffer, defaultObject, restoredObject);
restoredObject->SetParent((Actor*)parent);
// Link with existing prefab instance
restoredObject->LinkPrefab(i.Value->GetPrefabID(), prefabObjectId);
newPrefabObjects.Add(prefabObjectId, restoredObject);
}
}
// Create prefab instead of native asset
bool failed;