ensure brute force ray intersection works (#1170)

* ensure brute force ray intersection works in the same space as kd-tree intersection

* add additional tests for ray casts against meshes using brute force approach

* update api and add some additional test cases

* comment tidy-up and other small updates/fixes for ray intersection code

* fix issue with values at the end of a ray
This commit is contained in:
Tom Hulton-Harrop
2021-06-08 19:44:33 +01:00
committed by GitHub
parent 80f62d0523
commit dd95d2b02e
7 changed files with 279 additions and 143 deletions
@@ -61,12 +61,13 @@ namespace AZ
//! Important: only to be used in the Editor, it may kick off a job to calculate spatial information.
//! [GFX TODO][ATOM-4343 Bake mesh spatial during AP processing]
//!
//! @param rayStart position where the ray starts
//! @param dir direction where the ray ends (does not have to be unit length)
//! @param distanceFactor if an intersection is detected, this will be set such that distanceFactor * dir.length == distance to intersection
//! @param normal if an intersection is detected, this will be set to the normal at the point of intersection
//! @return true if the ray intersects the mesh
bool LocalRayIntersection(const AZ::Vector3& rayStart, const AZ::Vector3& dir, float& distanceFactor, AZ::Vector3& normal) const;
//! @param rayStart The starting point of the ray.
//! @param rayDir The direction and length of the ray (magnitude is encoded in the direction).
//! @param[out] distanceNormalized If an intersection is found, will be set to the normalized distance of the intersection
//! (in the range 0.0-1.0) - to calculate the actual distance, multiply distanceNormalized by the magnitude of rayDir.
//! @param[out] normal If an intersection is found, will be set to the normal at the point of collision.
//! @return True if the ray intersects the mesh.
bool LocalRayIntersection(const AZ::Vector3& rayStart, const AZ::Vector3& rayDir, float& distanceNormalized, AZ::Vector3& normal) const;
//! Checks a ray for intersection against this model, where the ray is in a different coordinate space.
//! Important: only to be used in the Editor, it may kick off a job to calculate spatial information.
@@ -74,13 +75,19 @@ namespace AZ
//!
//! @param modelTransform a transform that puts the model into the ray's coordinate space
//! @param nonUniformScale Non-uniform scale applied in the model's local frame.
//! @param rayStart position where the ray starts
//! @param dir direction where the ray ends (does not have to be unit length)
//! @param distanceFactor if an intersection is detected, this will be set such that distanceFactor * dir.length == distance to intersection
//! @param normal if an intersection is detected, this will be set to the normal at the point of intersection
//! @return true if the ray intersects the mesh
bool RayIntersection(const AZ::Transform& modelTransform, const AZ::Vector3& nonUniformScale, const AZ::Vector3& rayStart,
const AZ::Vector3& dir, float& distanceFactor, AZ::Vector3& normal) const;
//! @param rayStart The starting point of the ray.
//! @param rayDir The direction and length of the ray (magnitude is encoded in the direction).
//! @param[out] distanceNormalized If an intersection is found, will be set to the normalized distance of the intersection
//! (in the range 0.0-1.0) - to calculate the actual distance, multiply distanceNormalized by the magnitude of rayDir.
//! @param[out] normal If an intersection is found, will be set to the normal at the point of collision.
//! @return True if the ray intersects the mesh.
bool RayIntersection(
const AZ::Transform& modelTransform,
const AZ::Vector3& nonUniformScale,
const AZ::Vector3& rayStart,
const AZ::Vector3& rayDir,
float& distanceNormalized,
AZ::Vector3& normal) const;
//! Get available UV names from the model and its lods.
const AZStd::unordered_set<AZ::Name>& GetUvNames() const;
@@ -63,12 +63,14 @@ namespace AZ
//! Important: only to be used in the Editor, it may kick off a job to calculate spatial information.
//! [GFX TODO][ATOM-4343 Bake mesh spatial information during AP processing]
//!
//! @param rayStart position where the ray starts
//! @param dir direction where the ray ends (does not have to be unit length)
//! @param distance if an intersection is detected, this will be set such that distanceFactor * dir.length == distance to intersection
//! @param normal if an intersection is detected, this will be set to the normal at the point of collision
//! @return true if the ray intersects the mesh
virtual bool LocalRayIntersectionAgainstModel(const AZ::Vector3& rayStart, const AZ::Vector3& dir, float& distance, AZ::Vector3& normal) const;
//! @param rayStart The starting point of the ray.
//! @param rayDir The direction and length of the ray (magnitude is encoded in the direction).
//! @param[out] distanceNormalized If an intersection is found, will be set to the normalized distance of the intersection
//! (in the range 0.0-1.0) - to calculate the actual distance, multiply distanceNormalized by the magnitude of rayDir.
//! @param[out] normal If an intersection is found, will be set to the normal at the point of collision.
//! @return True if the ray intersects the mesh.
virtual bool LocalRayIntersectionAgainstModel(
const AZ::Vector3& rayStart, const AZ::Vector3& rayDir, float& distanceNormalized, AZ::Vector3& normal) const;
private:
void SetReady();
@@ -79,9 +81,15 @@ namespace AZ
// mutable method
void BuildKdTree() const;
bool BruteForceRayIntersect(const AZ::Vector3& rayStart, const AZ::Vector3& dir, float& distance, AZ::Vector3& normal) const;
bool BruteForceRayIntersect(
const AZ::Vector3& rayStart, const AZ::Vector3& rayDir, float& distanceNormalized, AZ::Vector3& normal) const;
bool LocalRayIntersectionAgainstMesh(const ModelLodAsset::Mesh& mesh, const AZ::Vector3& rayStart, const AZ::Vector3& dir, float& distance, AZ::Vector3& normal) const;
bool LocalRayIntersectionAgainstMesh(
const ModelLodAsset::Mesh& mesh,
const AZ::Vector3& rayStart,
const AZ::Vector3& rayDir,
float& distanceNormalized,
AZ::Vector3& normal) const;
// Various model information used in raycasting
AZ::Name m_positionName{ "POSITION" };