Add CollisionData.GetModelTriangle to retrieve source geometry triangle index from the raycast hit info
This commit is contained in:
@@ -366,6 +366,7 @@ bool CollisionCooking::CookCollision(const Argument& arg, CollisionData::Seriali
|
||||
outputOptions.ModelLodIndex = arg.ModelLodIndex;
|
||||
outputOptions.ConvexFlags = arg.ConvexFlags;
|
||||
outputOptions.ConvexVertexLimit = arg.ConvexVertexLimit;
|
||||
outputOptions.MaterialSlotsMask = arg.MaterialSlotsMask;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -133,6 +133,53 @@ bool CollisionData::CookCollision(CollisionDataType type, ModelData* modelData,
|
||||
|
||||
#endif
|
||||
|
||||
bool CollisionData::GetModelTriangle(uint32 faceIndex, MeshBase*& mesh, uint32& meshTriangleIndex) const
|
||||
{
|
||||
mesh = nullptr;
|
||||
meshTriangleIndex = MAX_uint32;
|
||||
if (!IsLoaded())
|
||||
return false;
|
||||
ScopeLock lock(Locker);
|
||||
if (_triangleMesh && faceIndex < _triangleMesh->getNbTriangles())
|
||||
{
|
||||
if (const PxU32* remap = _triangleMesh->getTrianglesRemap())
|
||||
{
|
||||
// Get source triangle index from the triangle mesh
|
||||
meshTriangleIndex = remap[faceIndex];
|
||||
|
||||
// Check if model was used when cooking
|
||||
AssetReference<ModelBase> model;
|
||||
model = _options.Model;
|
||||
if (!model)
|
||||
return true;
|
||||
|
||||
// Follow code-path similar to CollisionCooking.cpp to pick a mesh that contains this triangle (collision is cooked from merged all source meshes from the model)
|
||||
if (model->WaitForLoaded())
|
||||
return false;
|
||||
const int32 lodIndex = Math::Clamp(_options.ModelLodIndex, 0, model->GetLODsCount());
|
||||
Array<MeshBase*> meshes;
|
||||
model->GetMeshes(meshes, lodIndex);
|
||||
uint32 triangleCounter = 0;
|
||||
for (int32 meshIndex = 0; meshIndex < meshes.Count(); meshIndex++)
|
||||
{
|
||||
MeshBase* m = meshes[meshIndex];
|
||||
if ((_options.MaterialSlotsMask & (1 << m->GetMaterialSlotIndex())) == 0)
|
||||
continue;
|
||||
const uint32 count = m->GetTriangleCount();
|
||||
if (meshTriangleIndex - triangleCounter <= count)
|
||||
{
|
||||
mesh = m;
|
||||
meshTriangleIndex -= triangleCounter;
|
||||
return true;
|
||||
}
|
||||
triangleCounter += count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CollisionData::ExtractGeometry(Array<Vector3>& vertexBuffer, Array<int32>& indexBuffer) const
|
||||
{
|
||||
vertexBuffer.Clear();
|
||||
@@ -298,6 +345,7 @@ CollisionData::LoadResult CollisionData::load(const SerializedOptions* options,
|
||||
_options.ModelLodIndex = options->ModelLodIndex;
|
||||
_options.ConvexFlags = options->ConvexFlags;
|
||||
_options.ConvexVertexLimit = options->ConvexVertexLimit < 4 ? 255 : options->ConvexVertexLimit;
|
||||
_options.MaterialSlotsMask = options->MaterialSlotsMask == 0 ? MAX_uint32 : options->MaterialSlotsMask;
|
||||
|
||||
// Load data (rest of the chunk is a cooked collision data)
|
||||
if (_options.Type == CollisionDataType::None && dataSize > 0)
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
class Model;
|
||||
class ModelBase;
|
||||
class ModelData;
|
||||
class MeshBase;
|
||||
|
||||
namespace physx
|
||||
{
|
||||
@@ -104,42 +105,37 @@ DECLARE_SCRIPTING_TYPE_NO_SPAWN(CollisionDataOptions);
|
||||
/// <summary>
|
||||
/// The data type.
|
||||
/// </summary>
|
||||
API_FIELD() CollisionDataType Type;
|
||||
API_FIELD() CollisionDataType Type = CollisionDataType::None;
|
||||
|
||||
/// <summary>
|
||||
/// The source model asset id.
|
||||
/// </summary>
|
||||
API_FIELD() Guid Model;
|
||||
API_FIELD() Guid Model = Guid::Empty;
|
||||
|
||||
/// <summary>
|
||||
/// The source model LOD index.
|
||||
/// </summary>
|
||||
API_FIELD() int32 ModelLodIndex;
|
||||
API_FIELD() int32 ModelLodIndex = 0;
|
||||
|
||||
/// <summary>
|
||||
/// The cooked collision bounds.
|
||||
/// </summary>
|
||||
API_FIELD() BoundingBox Box;
|
||||
API_FIELD() BoundingBox Box = BoundingBox::Zero;
|
||||
|
||||
/// <summary>
|
||||
/// The convex generation flags.
|
||||
/// </summary>
|
||||
API_FIELD() ConvexMeshGenerationFlags ConvexFlags;
|
||||
API_FIELD() ConvexMeshGenerationFlags ConvexFlags = ConvexMeshGenerationFlags::None;
|
||||
|
||||
/// <summary>
|
||||
/// The convex vertices limit (maximum amount).
|
||||
/// </summary>
|
||||
API_FIELD() int32 ConvexVertexLimit;
|
||||
API_FIELD() int32 ConvexVertexLimit = 0;
|
||||
|
||||
CollisionDataOptions()
|
||||
{
|
||||
Type = CollisionDataType::None;
|
||||
Model = Guid::Empty;
|
||||
ModelLodIndex = 0;
|
||||
Box = BoundingBox::Zero;
|
||||
ConvexFlags = ConvexMeshGenerationFlags::None;
|
||||
ConvexVertexLimit = 0;
|
||||
}
|
||||
/// <summary>
|
||||
/// The source model material slots mask. One bit per-slot. Can be used to exclude particular material slots from collision cooking.
|
||||
/// </summary>
|
||||
API_FIELD() uint32 MaterialSlotsMask = MAX_uint32;
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
@@ -160,7 +156,8 @@ public:
|
||||
int32 ModelLodIndex;
|
||||
ConvexMeshGenerationFlags ConvexFlags;
|
||||
int32 ConvexVertexLimit;
|
||||
byte Padding[96];
|
||||
uint32 MaterialSlotsMask;
|
||||
byte Padding[92];
|
||||
};
|
||||
|
||||
static_assert(sizeof(SerializedOptions) == 128, "Invalid collision data options size. Change the padding.");
|
||||
@@ -259,6 +256,16 @@ public:
|
||||
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Extracts the triangle index of the original mesh data used for cooking this collision data. Can be used to get vertex attributes of the triangle mesh hit by the raycast.
|
||||
/// </summary>
|
||||
/// <remarks>Supported only for collision data built as triangle mesh and without <see cref="ConvexMeshGenerationFlags.SuppressFaceRemapTable"/> flag set.</remarks>
|
||||
/// <param name="faceIndex">The face index of the collision mesh.</param>
|
||||
/// <param name="mesh">The result source mesh used to build this collision data (can be null if collision data was cooked using custom geometry without source Model set).</param>
|
||||
/// <param name="meshTriangleIndex">The result triangle index of the source geometry used to build this collision data.</param>
|
||||
/// <returns>True if got a valid triangle index, otherwise false.</returns>
|
||||
API_FUNCTION() bool GetModelTriangle(uint32 faceIndex, API_PARAM(Out) MeshBase*& mesh, API_PARAM(Out) uint32& meshTriangleIndex) const;
|
||||
|
||||
/// <summary>
|
||||
/// Extracts the collision data geometry into list of triangles.
|
||||
/// </summary>
|
||||
|
||||
@@ -23,7 +23,7 @@ DECLARE_SCRIPTING_TYPE_NO_SPAWN(RayCastHit);
|
||||
/// <summary>
|
||||
/// The collider that was hit.
|
||||
/// </summary>
|
||||
API_FIELD() PhysicsColliderActor* Collider;
|
||||
API_FIELD() PhysicsColliderActor* Collider = nullptr;
|
||||
|
||||
/// <summary>
|
||||
/// The normal of the surface the ray hit.
|
||||
@@ -43,6 +43,7 @@ DECLARE_SCRIPTING_TYPE_NO_SPAWN(RayCastHit);
|
||||
/// <summary>
|
||||
/// The index of the face that was hit. Valid only for convex mesh (polygon index), triangle mesh (triangle index) and height field (triangle index).
|
||||
/// </summary>
|
||||
/// <seealso cref="CollisionData.GetModelTriangle" />
|
||||
API_FIELD() uint32 FaceIndex;
|
||||
|
||||
/// <summary>
|
||||
|
||||
Reference in New Issue
Block a user