diff --git a/Source/Editor/Viewport/MainEditorGizmoViewport.cs b/Source/Editor/Viewport/MainEditorGizmoViewport.cs index a6d5f1c36..4c0891124 100644 --- a/Source/Editor/Viewport/MainEditorGizmoViewport.cs +++ b/Source/Editor/Viewport/MainEditorGizmoViewport.cs @@ -13,6 +13,7 @@ using FlaxEditor.Windows; using FlaxEngine; using FlaxEngine.GUI; using FlaxEngine.Tools; + using Object = FlaxEngine.Object; namespace FlaxEditor.Viewport @@ -684,21 +685,53 @@ namespace FlaxEditor.Viewport if (uiCanvas.Is2D) continue; } - - // Check if all corners are in box to select it. - var corners = actorBox.GetCorners(); - var containsAllCorners = true; - foreach (var c in corners) + + var containsAllPoints = true; + var fallBackToBox = false; + if (a is StaticModel sm) { - Viewport.ProjectPoint(c, out var loc); - if (!adjustedRect.Contains(loc)) + List extraPoints = new List(); + var m = sm.Model.LODs[0]; + foreach (var mesh in m.Meshes) { - containsAllCorners = false; - break; + var points = mesh.GetCollisionProxyPoints(); + if (points.Length == 0) + { + fallBackToBox = true; + break; + } + foreach (var point in points) + { + Viewport.ProjectPoint(a.Transform.LocalToWorld(point), out var loc); + if (!adjustedRect.Contains(loc)) + { + containsAllPoints = false; + break; + } + } } } + else + { + fallBackToBox = true; + } - if (containsAllCorners) + if (fallBackToBox) + { + // Check if all corners are in box to select it. + var corners = actorBox.GetCorners(); + foreach (var c in corners) + { + Viewport.ProjectPoint(c, out var loc); + if (!adjustedRect.Contains(loc)) + { + containsAllPoints = false; + break; + } + } + } + + if (containsAllPoints) { if (a.HasPrefabLink) hits.Add(SceneGraphRoot.Find(a.GetPrefabRoot())); diff --git a/Source/Engine/Graphics/Mesh.cs b/Source/Engine/Graphics/Mesh.cs index 42604c872..e44dbec7b 100644 --- a/Source/Engine/Graphics/Mesh.cs +++ b/Source/Engine/Graphics/Mesh.cs @@ -633,5 +633,14 @@ namespace FlaxEngine throw new Exception("Failed to download mesh data."); return result; } + + /// + /// Gets the collision proxy points for the mesh. + /// + /// The triangle points in the collision proxy. + public Float3[] GetCollisionProxyPoints() + { + return Internal_GetCollisionProxyPoints(__unmanagedPtr, out _); + } } } diff --git a/Source/Engine/Graphics/Models/Mesh.cpp b/Source/Engine/Graphics/Models/Mesh.cpp index 77c2089e1..365280a44 100644 --- a/Source/Engine/Graphics/Models/Mesh.cpp +++ b/Source/Engine/Graphics/Models/Mesh.cpp @@ -847,4 +847,17 @@ MArray* Mesh::DownloadBuffer(bool forceGpu, MTypeObject* resultType, int32 typeI return result; } +Array Mesh::GetCollisionProxyPoints() const +{ + Array result; + for (int i = 0; i < _collisionProxy.Triangles.Count(); ++i) + { + auto triangle = _collisionProxy.Triangles[i]; + result.Add(triangle.V0); + result.Add(triangle.V1); + result.Add(triangle.V2); + } + return result; +} + #endif diff --git a/Source/Engine/Graphics/Models/Mesh.h b/Source/Engine/Graphics/Models/Mesh.h index 813836b85..2c8f8beda 100644 --- a/Source/Engine/Graphics/Models/Mesh.h +++ b/Source/Engine/Graphics/Models/Mesh.h @@ -320,5 +320,6 @@ private: API_FUNCTION(NoProxy) bool UpdateTrianglesUInt(int32 triangleCount, const MArray* trianglesObj); API_FUNCTION(NoProxy) bool UpdateTrianglesUShort(int32 triangleCount, const MArray* trianglesObj); API_FUNCTION(NoProxy) MArray* DownloadBuffer(bool forceGpu, MTypeObject* resultType, int32 typeI); + API_FUNCTION(NoProxy) Array GetCollisionProxyPoints() const; #endif };