Fix issues in surface normal computation in raycast method of ConeShape and BoxShape

This commit is contained in:
Daniel Chappuis 2014-11-27 21:05:32 +01:00
parent 5d2cf593b5
commit 4ae7e7997a
2 changed files with 15 additions and 9 deletions

View File

@ -90,8 +90,10 @@ bool BoxShape::raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxyShape* pro
// Compute the intersection of the ray with the near and far plane of the slab // Compute the intersection of the ray with the near and far plane of the slab
decimal oneOverD = decimal(1.0) / rayDirection[i]; decimal oneOverD = decimal(1.0) / rayDirection[i];
decimal t1 = (-mExtent[i] - point1[i]) * oneOverD; decimal t1 = (-mExtent[i] - point1[i]) * oneOverD;
decimal t2 = (mExtent[i] - point1 [i]) * oneOverD; decimal t2 = (mExtent[i] - point1[i]) * oneOverD;
currentNormal = -mExtent; currentNormal[0] = (i == 0) ? -mExtent[i] : decimal(0.0);
currentNormal[1] = (i == 1) ? -mExtent[i] : decimal(0.0);
currentNormal[2] = (i == 2) ? -mExtent[i] : decimal(0.0);
// Swap t1 and t2 if need so that t1 is intersection with near plane and // Swap t1 and t2 if need so that t1 is intersection with near plane and
// t2 with far plane // t2 with far plane
@ -125,6 +127,7 @@ bool BoxShape::raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxyShape* pro
raycastInfo.proxyShape = proxyShape; raycastInfo.proxyShape = proxyShape;
raycastInfo.hitFraction = tMin; raycastInfo.hitFraction = tMin;
raycastInfo.worldPoint = localToWorldTransform * localHitPoint; raycastInfo.worldPoint = localToWorldTransform * localHitPoint;
normalDirection.normalize();
raycastInfo.worldNormal = localToWorldTransform.getOrientation() * normalDirection; raycastInfo.worldNormal = localToWorldTransform.getOrientation() * normalDirection;
return true; return true;

View File

@ -215,14 +215,17 @@ bool ConeShape::raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxyShape* pr
// Compute the normal direction for hit against side of the cone // Compute the normal direction for hit against side of the cone
if (hitIndex != 2) { if (hitIndex != 2) {
decimal m = std::sqrt(localHitPoint[hitIndex].x * localHitPoint[hitIndex].x +
localHitPoint[hitIndex].z * localHitPoint[hitIndex].z);
decimal h = decimal(2.0) * mHalfHeight; decimal h = decimal(2.0) * mHalfHeight;
decimal hOverR = h / mRadius; decimal value1 = (localHitPoint[hitIndex].x * localHitPoint[hitIndex].x +
decimal hOverROverM = hOverR / m; localHitPoint[hitIndex].z * localHitPoint[hitIndex].z);
localNormal[hitIndex].x = localHitPoint[hitIndex].x * hOverROverM; decimal rOverH = mRadius / h;
localNormal[hitIndex].y = mRadius / h; decimal value2 = decimal(1.0) + rOverH * rOverH;
localNormal[hitIndex].z = localHitPoint[hitIndex].z * hOverROverM; decimal factor = decimal(1.0) / std::sqrt(value1 * value2);
decimal x = localHitPoint[hitIndex].x * factor;
decimal z = localHitPoint[hitIndex].z * factor;
localNormal[hitIndex].x = x;
localNormal[hitIndex].y = std::sqrt(x * x + z * z) * rOverH;
localNormal[hitIndex].z = z;
} }
raycastInfo.body = proxyShape->getBody(); raycastInfo.body = proxyShape->getBody();