Use mesh collision proxy if available.

This commit is contained in:
Chandler Cox
2025-01-27 18:28:06 -06:00
parent fc4c2c53fc
commit abe2482a01
4 changed files with 66 additions and 10 deletions

View File

@@ -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<Float3> extraPoints = new List<Float3>();
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()));

View File

@@ -633,5 +633,14 @@ namespace FlaxEngine
throw new Exception("Failed to download mesh data.");
return result;
}
/// <summary>
/// Gets the collision proxy points for the mesh.
/// </summary>
/// <returns>The triangle points in the collision proxy.</returns>
public Float3[] GetCollisionProxyPoints()
{
return Internal_GetCollisionProxyPoints(__unmanagedPtr, out _);
}
}
}

View File

@@ -847,4 +847,17 @@ MArray* Mesh::DownloadBuffer(bool forceGpu, MTypeObject* resultType, int32 typeI
return result;
}
Array<Float3> Mesh::GetCollisionProxyPoints() const
{
Array<Vector3> 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

View File

@@ -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<Float3> GetCollisionProxyPoints() const;
#endif
};