More work for large worlds

This commit is contained in:
Wojtek Figat
2022-06-30 22:06:35 +02:00
parent 4007c5e29c
commit b40a890d31
10 changed files with 103 additions and 27 deletions

View File

@@ -127,6 +127,20 @@ bool SkinnedMesh::Intersects(const Ray& ray, const Matrix& world, Real& distance
return transformedBox.Intersects(ray, distance, normal);
}
bool SkinnedMesh::Intersects(const Ray& ray, const Transform& transform, Real& distance, Vector3& normal) const
{
// Transform points
Vector3 min, max;
transform.LocalToWorld(_box.Minimum, min);
transform.LocalToWorld(_box.Maximum, max);
// Get transformed box
BoundingBox transformedBox(min, max);
// Test ray on a box
return transformedBox.Intersects(ray, distance, normal);
}
void SkinnedMesh::Render(GPUContext* context) const
{
ASSERT(IsInitialized());

View File

@@ -150,6 +150,16 @@ public:
/// <returns>True whether the two objects intersected</returns>
bool Intersects(const Ray& ray, const Matrix& world, Real& distance, Vector3& normal) const;
/// <summary>
/// Determines if there is an intersection between the mesh and a ray in given world
/// </summary>
/// <param name="ray">The ray to test</param>
/// <param name="transform">Instance transformation</param>
/// <param name="distance">When the method completes and returns true, contains the distance of the intersection (if any valid).</param>
/// <param name="normal">When the method completes, contains the intersection surface normal vector (if any valid).</param>
/// <returns>True whether the two objects intersected</returns>
bool Intersects(const Ray& ray, const Transform& transform, Real& distance, Vector3& normal) const;
/// <summary>
/// Retrieves the eight corners of the bounding box.
/// </summary>

View File

@@ -100,6 +100,31 @@ bool SkinnedModelLOD::Intersects(const Ray& ray, const Matrix& world, Real& dist
return result;
}
bool SkinnedModelLOD::Intersects(const Ray& ray, const Transform& transform, Real& distance, Vector3& normal, SkinnedMesh** mesh)
{
// Check all meshes
bool result = false;
Real closest = MAX_float;
Vector3 closestNormal = Vector3::Up;
for (int32 i = 0; i < Meshes.Count(); i++)
{
// Test intersection with mesh and check if is closer than previous
Real dst;
Vector3 nrm;
if (Meshes[i].Intersects(ray, transform, dst, nrm) && dst < closest)
{
result = true;
*mesh = &Meshes[i];
closest = dst;
closestNormal = nrm;
}
}
distance = closest;
normal = closestNormal;
return result;
}
BoundingBox SkinnedModelLOD::GetBox(const Matrix& world) const
{
// Find minimum and maximum points of all the meshes

View File

@@ -63,6 +63,17 @@ public:
/// <returns>True whether the two objects intersected</returns>
bool Intersects(const Ray& ray, const Matrix& world, Real& distance, Vector3& normal, SkinnedMesh** mesh);
/// <summary>
/// Determines if there is an intersection between the Model and a Ray in given world using given instance
/// </summary>
/// <param name="ray">The ray to test</param>
/// <param name="transform">Instance transformation</param>
/// <param name="distance">When the method completes, contains the distance of the intersection (if any valid).</param>
/// <param name="normal">When the method completes, contains the intersection surface normal vector (if any valid).</param>
/// <param name="mesh">Mesh, or null</param>
/// <returns>True whether the two objects intersected</returns>
bool Intersects(const Ray& ray, const Transform& transform, Real& distance, Vector3& normal, SkinnedMesh** mesh);
/// <summary>
/// Get model bounding box in transformed world for given instance buffer
/// </summary>