ADD: BVH Selection system completed
This commit is contained in:
@@ -283,11 +283,17 @@ namespace
|
|||||||
const glm::vec3 &rayDir,
|
const glm::vec3 &rayDir,
|
||||||
const RenderObject &obj,
|
const RenderObject &obj,
|
||||||
glm::vec3 &outWorldHit,
|
glm::vec3 &outWorldHit,
|
||||||
BoundsHitDebug *debug)
|
BoundsHitDebug *debug,
|
||||||
|
MeshBVHPickHit *outMeshHit)
|
||||||
{
|
{
|
||||||
const Bounds &bounds = obj.bounds;
|
const Bounds &bounds = obj.bounds;
|
||||||
const glm::mat4 &worldTransform = obj.transform;
|
const glm::mat4 &worldTransform = obj.transform;
|
||||||
|
|
||||||
|
if (outMeshHit)
|
||||||
|
{
|
||||||
|
*outMeshHit = {};
|
||||||
|
}
|
||||||
|
|
||||||
// Non-pickable object.
|
// Non-pickable object.
|
||||||
if (bounds.type == BoundsType::None)
|
if (bounds.type == BoundsType::None)
|
||||||
{
|
{
|
||||||
@@ -324,29 +330,41 @@ namespace
|
|||||||
}
|
}
|
||||||
case BoundsType::Mesh:
|
case BoundsType::Mesh:
|
||||||
{
|
{
|
||||||
// Try high-precision mesh BVH first when available, then fall back to box.
|
// For mesh bounds we rely solely on the CPU mesh BVH.
|
||||||
if (obj.sourceMesh && obj.sourceMesh->bvh)
|
// If there is no BVH or the BVH misses, the object is
|
||||||
|
// treated as not hit by this ray (no coarse box fallback).
|
||||||
|
if (!obj.sourceMesh || !obj.sourceMesh->bvh)
|
||||||
{
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
{
|
{
|
||||||
debug->usedBVH = true;
|
debug->usedBVH = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
MeshBVHPickHit meshHit{};
|
MeshBVHPickHit meshHit{};
|
||||||
if (intersect_ray_mesh_bvh(*obj.sourceMesh->bvh, worldTransform, rayOrigin, rayDir, meshHit))
|
if (!intersect_ray_mesh_bvh(*obj.sourceMesh->bvh, worldTransform, rayOrigin, rayDir, meshHit))
|
||||||
{
|
{
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
// BVH was queried but produced no hit.
|
||||||
|
debug->fallbackBox = true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
{
|
{
|
||||||
debug->bvhHit = true;
|
debug->bvhHit = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
outWorldHit = meshHit.worldPos;
|
outWorldHit = meshHit.worldPos;
|
||||||
return true;
|
if (outMeshHit)
|
||||||
}
|
|
||||||
if (debug)
|
|
||||||
{
|
{
|
||||||
debug->fallbackBox = true;
|
*outMeshHit = meshHit;
|
||||||
}
|
}
|
||||||
}
|
return true;
|
||||||
// return intersect_ray_box(rayOrigin, rayDir, bounds, worldTransform, outWorldHit);
|
|
||||||
}
|
}
|
||||||
case BoundsType::Box:
|
case BoundsType::Box:
|
||||||
default:
|
default:
|
||||||
@@ -455,7 +473,8 @@ bool SceneManager::pick(const glm::vec2 &mousePosPixels, RenderObject &outObject
|
|||||||
{
|
{
|
||||||
glm::vec3 hitPos{};
|
glm::vec3 hitPos{};
|
||||||
BoundsHitDebug localDebug{};
|
BoundsHitDebug localDebug{};
|
||||||
if (!intersect_ray_bounds(rayOrigin, rayDir, obj, hitPos, &localDebug))
|
MeshBVHPickHit localMeshHit{};
|
||||||
|
if (!intersect_ray_bounds(rayOrigin, rayDir, obj, hitPos, &localDebug, &localMeshHit))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -466,6 +485,16 @@ bool SceneManager::pick(const glm::vec2 &mousePosPixels, RenderObject &outObject
|
|||||||
bestDist2 = d2;
|
bestDist2 = d2;
|
||||||
bestHitPos = hitPos;
|
bestHitPos = hitPos;
|
||||||
outObject = obj;
|
outObject = obj;
|
||||||
|
|
||||||
|
// If we have a precise mesh BVH hit, refine the picked
|
||||||
|
// primitive to the exact triangle instead of the whole surface.
|
||||||
|
if (localMeshHit.hit && outObject.sourceMesh && outObject.sourceMesh->bvh)
|
||||||
|
{
|
||||||
|
outObject.firstIndex = localMeshHit.firstIndex;
|
||||||
|
outObject.indexCount = 3;
|
||||||
|
outObject.surfaceIndex = localMeshHit.surfaceIndex;
|
||||||
|
}
|
||||||
|
|
||||||
anyHit = true;
|
anyHit = true;
|
||||||
|
|
||||||
// Capture debug info for the best hit so far.
|
// Capture debug info for the best hit so far.
|
||||||
|
|||||||
Reference in New Issue
Block a user