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.ModelLodIndex = arg.ModelLodIndex;
|
||||||
outputOptions.ConvexFlags = arg.ConvexFlags;
|
outputOptions.ConvexFlags = arg.ConvexFlags;
|
||||||
outputOptions.ConvexVertexLimit = arg.ConvexVertexLimit;
|
outputOptions.ConvexVertexLimit = arg.ConvexVertexLimit;
|
||||||
|
outputOptions.MaterialSlotsMask = arg.MaterialSlotsMask;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -133,6 +133,53 @@ bool CollisionData::CookCollision(CollisionDataType type, ModelData* modelData,
|
|||||||
|
|
||||||
#endif
|
#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
|
void CollisionData::ExtractGeometry(Array<Vector3>& vertexBuffer, Array<int32>& indexBuffer) const
|
||||||
{
|
{
|
||||||
vertexBuffer.Clear();
|
vertexBuffer.Clear();
|
||||||
@@ -298,6 +345,7 @@ CollisionData::LoadResult CollisionData::load(const SerializedOptions* options,
|
|||||||
_options.ModelLodIndex = options->ModelLodIndex;
|
_options.ModelLodIndex = options->ModelLodIndex;
|
||||||
_options.ConvexFlags = options->ConvexFlags;
|
_options.ConvexFlags = options->ConvexFlags;
|
||||||
_options.ConvexVertexLimit = options->ConvexVertexLimit < 4 ? 255 : options->ConvexVertexLimit;
|
_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)
|
// Load data (rest of the chunk is a cooked collision data)
|
||||||
if (_options.Type == CollisionDataType::None && dataSize > 0)
|
if (_options.Type == CollisionDataType::None && dataSize > 0)
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
class Model;
|
class Model;
|
||||||
class ModelBase;
|
class ModelBase;
|
||||||
class ModelData;
|
class ModelData;
|
||||||
|
class MeshBase;
|
||||||
|
|
||||||
namespace physx
|
namespace physx
|
||||||
{
|
{
|
||||||
@@ -104,42 +105,37 @@ DECLARE_SCRIPTING_TYPE_NO_SPAWN(CollisionDataOptions);
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The data type.
|
/// The data type.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
API_FIELD() CollisionDataType Type;
|
API_FIELD() CollisionDataType Type = CollisionDataType::None;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The source model asset id.
|
/// The source model asset id.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
API_FIELD() Guid Model;
|
API_FIELD() Guid Model = Guid::Empty;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The source model LOD index.
|
/// The source model LOD index.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
API_FIELD() int32 ModelLodIndex;
|
API_FIELD() int32 ModelLodIndex = 0;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The cooked collision bounds.
|
/// The cooked collision bounds.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
API_FIELD() BoundingBox Box;
|
API_FIELD() BoundingBox Box = BoundingBox::Zero;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The convex generation flags.
|
/// The convex generation flags.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
API_FIELD() ConvexMeshGenerationFlags ConvexFlags;
|
API_FIELD() ConvexMeshGenerationFlags ConvexFlags = ConvexMeshGenerationFlags::None;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The convex vertices limit (maximum amount).
|
/// The convex vertices limit (maximum amount).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
API_FIELD() int32 ConvexVertexLimit;
|
API_FIELD() int32 ConvexVertexLimit = 0;
|
||||||
|
|
||||||
CollisionDataOptions()
|
/// <summary>
|
||||||
{
|
/// The source model material slots mask. One bit per-slot. Can be used to exclude particular material slots from collision cooking.
|
||||||
Type = CollisionDataType::None;
|
/// </summary>
|
||||||
Model = Guid::Empty;
|
API_FIELD() uint32 MaterialSlotsMask = MAX_uint32;
|
||||||
ModelLodIndex = 0;
|
|
||||||
Box = BoundingBox::Zero;
|
|
||||||
ConvexFlags = ConvexMeshGenerationFlags::None;
|
|
||||||
ConvexVertexLimit = 0;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -160,7 +156,8 @@ public:
|
|||||||
int32 ModelLodIndex;
|
int32 ModelLodIndex;
|
||||||
ConvexMeshGenerationFlags ConvexFlags;
|
ConvexMeshGenerationFlags ConvexFlags;
|
||||||
int32 ConvexVertexLimit;
|
int32 ConvexVertexLimit;
|
||||||
byte Padding[96];
|
uint32 MaterialSlotsMask;
|
||||||
|
byte Padding[92];
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert(sizeof(SerializedOptions) == 128, "Invalid collision data options size. Change the padding.");
|
static_assert(sizeof(SerializedOptions) == 128, "Invalid collision data options size. Change the padding.");
|
||||||
@@ -259,6 +256,16 @@ public:
|
|||||||
|
|
||||||
#endif
|
#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>
|
/// <summary>
|
||||||
/// Extracts the collision data geometry into list of triangles.
|
/// Extracts the collision data geometry into list of triangles.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ DECLARE_SCRIPTING_TYPE_NO_SPAWN(RayCastHit);
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The collider that was hit.
|
/// The collider that was hit.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
API_FIELD() PhysicsColliderActor* Collider;
|
API_FIELD() PhysicsColliderActor* Collider = nullptr;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The normal of the surface the ray hit.
|
/// The normal of the surface the ray hit.
|
||||||
@@ -43,6 +43,7 @@ DECLARE_SCRIPTING_TYPE_NO_SPAWN(RayCastHit);
|
|||||||
/// <summary>
|
/// <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).
|
/// 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>
|
/// </summary>
|
||||||
|
/// <seealso cref="CollisionData.GetModelTriangle" />
|
||||||
API_FIELD() uint32 FaceIndex;
|
API_FIELD() uint32 FaceIndex;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
Reference in New Issue
Block a user