fix: correct ray verification logic for shell analysis

- Ray now properly starts from global center through component center
- Only checks intersections beyond component center (outward extension)
- Removed incorrect center-point direction check
- Directly tests AABB intersection without pre-filtering

This fixes the issue where internal components were incorrectly marked as shell
due to skipping the portion between global center and component center.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
sladro 2025-09-20 09:09:37 +08:00
parent 9b2e60249c
commit 23a79cee42

View File

@ -3494,9 +3494,12 @@ bool CreoManager::IsComponentBlockedFromCenter(const Vector3D& globalCenter,
// Calculate ray direction (from global center through component center)
Vector3D rayDirection = (componentCenter - globalCenter).normalize();
// Start ray from component center (skip checking between global center and component)
// We want to check if ray is blocked AFTER passing through the component
Vector3D rayStart = componentCenter;
// Start ray from global center to check all components along the path
Vector3D rayStart = globalCenter;
// Calculate distance from global center to component center
// We only care about intersections beyond this distance (outward extension)
double distToComponentCenter = (componentCenter - globalCenter).length();
// Check intersection with all other components
for (const ComponentItem& otherComp : allComponents) {
@ -3505,24 +3508,8 @@ bool CreoManager::IsComponentBlockedFromCenter(const Vector3D& globalCenter,
continue;
}
// Calculate other component center
Vector3D otherCenter = Vector3D(
(otherComp.worldAABB.minPoint.x + otherComp.worldAABB.maxPoint.x) * 0.5,
(otherComp.worldAABB.minPoint.y + otherComp.worldAABB.maxPoint.y) * 0.5,
(otherComp.worldAABB.minPoint.z + otherComp.worldAABB.maxPoint.z) * 0.5
);
// Check if other component is in the outward direction
Vector3D toOther = otherCenter - rayStart;
double dotProduct = toOther.dot(rayDirection);
// If other component is not in the ray direction, skip
if (dotProduct <= 0) {
continue;
}
// Simple AABB ray intersection test
// Check if ray from component center outward intersects other component's AABB
// AABB ray intersection test
// We check if ray intersects other component's AABB beyond the component center
double tMin = 0.0;
double tMax = std::numeric_limits<double>::max();
@ -3562,9 +3549,15 @@ bool CreoManager::IsComponentBlockedFromCenter(const Vector3D& globalCenter,
}
}
// If ray intersects this component's AABB, the component is blocked
// Check if intersection exists and is beyond the component center (outward extension)
if (tMin <= tMax && tMin >= 0) {
return true; // Component is blocked
// Calculate the actual distance of the intersection point
double intersectionDistance = tMin;
// Only consider it blocked if intersection is beyond the component center
if (intersectionDistance > distToComponentCenter) {
return true; // Component is blocked by something in the outward direction
}
}
}