From 358e39caa7c749ba7dcca81263b4e912090838b1 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Sat, 19 Sep 2026 22:48:57 +0200 Subject: [PATCH] Add various improvements to CSG Brushes editing workflow --- .../Editor/SceneGraph/Actors/BoxBrushNode.cs | 5 +++ Source/Engine/CSG/CSGData.cpp | 2 ++ Source/Engine/Level/Actors/BoxBrush.cpp | 32 +++++++++++++------ Source/Engine/Level/Actors/BoxBrush.h | 8 +---- 4 files changed, 31 insertions(+), 16 deletions(-) diff --git a/Source/Editor/SceneGraph/Actors/BoxBrushNode.cs b/Source/Editor/SceneGraph/Actors/BoxBrushNode.cs index 2e3d56c27..030d16d1e 100644 --- a/Source/Editor/SceneGraph/Actors/BoxBrushNode.cs +++ b/Source/Editor/SceneGraph/Actors/BoxBrushNode.cs @@ -7,6 +7,7 @@ using Real = System.Single; #endif using System; +using System.ComponentModel; using FlaxEngine; namespace FlaxEditor.SceneGraph.Actors @@ -45,6 +46,7 @@ namespace FlaxEditor.SceneGraph.Actors } } + [DefaultValue(typeof(Float2), "1,1")] [EditorOrder(30), EditorDisplay("Brush", "UV Scale"), Limit(-1000, 1000, 0.01f)] [Tooltip("The surface texture coordinates scale.")] public Float2 TexCoordScale @@ -58,6 +60,7 @@ namespace FlaxEditor.SceneGraph.Actors } } + [DefaultValue(typeof(Float2), "0,0")] [EditorOrder(40), EditorDisplay("Brush", "UV Offset"), Limit(-1000, 1000, 0.01f)] [Tooltip("The surface texture coordinates offset.")] public Float2 TexCoordOffset @@ -71,6 +74,7 @@ namespace FlaxEditor.SceneGraph.Actors } } + [DefaultValue(0.0f)] [EditorOrder(50), EditorDisplay("Brush", "UV Rotation")] [Tooltip("The surface texture coordinates rotation angle (in degrees).")] public float TexCoordRotation @@ -84,6 +88,7 @@ namespace FlaxEditor.SceneGraph.Actors } } + [DefaultValue(1.0f)] [EditorOrder(20), EditorDisplay("Brush", "Scale In Lightmap"), Limit(0, 10000, 0.1f)] [Tooltip("The scale in lightmap (per surface).")] public float ScaleInLightmap diff --git a/Source/Engine/CSG/CSGData.cpp b/Source/Engine/CSG/CSGData.cpp index 53f94c175..04a78114e 100644 --- a/Source/Engine/CSG/CSGData.cpp +++ b/Source/Engine/CSG/CSGData.cpp @@ -72,6 +72,8 @@ void RawData::AddSurface(Brush* brush, int32 brushSurfaceIndex, const Guid& surf slot->AddSurface(scaleInLightmap, lightmapUVsBox, firstVertex, vertexCount); // Add surface to brush + if (!brush) + return; auto& brushData = Brushes[brush->GetBrushID()]; if (brushData.Surfaces.Count() != brush->GetSurfacesCount()) brushData.Surfaces.Resize(brush->GetSurfacesCount()); diff --git a/Source/Engine/Level/Actors/BoxBrush.cpp b/Source/Engine/Level/Actors/BoxBrush.cpp index 06bc047bc..1935a8b51 100644 --- a/Source/Engine/Level/Actors/BoxBrush.cpp +++ b/Source/Engine/Level/Actors/BoxBrush.cpp @@ -50,7 +50,18 @@ Array BoxBrush::GetSurfaces() const void BoxBrush::SetSurfaces(const Array& value) { CHECK(value.Count() == ARRAY_COUNT(Surfaces)); - Platform::MemoryCopy(Surfaces, value.Get(), sizeof(Surfaces)); + for (int32 i = 0; i < ARRAY_COUNT(Surfaces); i++) + { + auto& dst = Surfaces[i]; + const auto& src = value[i]; + dst.Brush = this; + dst.Index = i; + dst.Material = src.Material; + dst.TexCoordScale = src.TexCoordScale; + dst.TexCoordOffset = src.TexCoordOffset; + dst.TexCoordRotation = src.TexCoordRotation; + dst.ScaleInLightmap = src.ScaleInLightmap; + } OnBrushModified(); } @@ -67,10 +78,7 @@ void BoxBrush::SetCenter(const Vector3& value) { if (value == _center) return; - _center = value; - - // Fire events UpdateBounds(); OnBrushModified(); } @@ -79,10 +87,7 @@ void BoxBrush::SetSize(const Vector3& value) { if (value == _size) return; - _size = value; - - // Fire events UpdateBounds(); OnBrushModified(); } @@ -98,7 +103,7 @@ void BoxBrush::GetSurfaces(CSG::Surface surfaces[6]) surfaces[5].Normal = Vector3::Backward; // Calculate final transformation - const auto transform = _transform.LocalToWorld(Transform(_center, Quaternion::Identity, _size)); + const auto transform = _transform.LocalToWorld(Transform(_center, Quaternion::Identity, _size.GetAbsolute())); // Set size and scale surfaces[0].D = surfaces[1].D = transform.Scale.X / 2; @@ -163,6 +168,14 @@ void BoxBrush::GetVertices(int32 surfaceIndex, Array& outputData) const } } +void BoxBrush::UpdateBounds() +{ + OrientedBoundingBox::CreateCentered(_center, _size.GetAbsolute(), _bounds); + _bounds.Transform(_transform); + _bounds.GetBoundingBox(_box); + BoundingSphere::FromBox(_box, _sphere); +} + void BoxBrush::Serialize(SerializeStream& stream, const void* otherObj) { // Base @@ -230,7 +243,8 @@ bool BoxBrush::IntersectsItself(const Ray& ray, Real& distance, Vector3& normal) void BoxBrush::OnDebugDrawSelected() { - DEBUG_DRAW_WIRE_BOX(_bounds, Color::Yellow, 0, false); + DEBUG_DRAW_WIRE_BOX(_bounds, Color::Yellow.AlphaMultiplied(0.2f), 0, false); + DEBUG_DRAW_WIRE_BOX(_bounds, Color::Yellow, 0, true); // Base Actor::OnDebugDrawSelected(); diff --git a/Source/Engine/Level/Actors/BoxBrush.h b/Source/Engine/Level/Actors/BoxBrush.h index 519ca5ad8..17941b16b 100644 --- a/Source/Engine/Level/Actors/BoxBrush.h +++ b/Source/Engine/Level/Actors/BoxBrush.h @@ -188,13 +188,7 @@ public: API_FUNCTION() void GetVertices(int32 surfaceIndex, API_PARAM(Out) Array& outputData) const; private: - FORCE_INLINE void UpdateBounds() - { - OrientedBoundingBox::CreateCentered(_center, _size, _bounds); - _bounds.Transform(_transform); - _bounds.GetBoundingBox(_box); - BoundingSphere::FromBox(_box, _sphere); - } + void UpdateBounds(); public: // [Actor]