aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llvosurfacepatch.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/newview/llvosurfacepatch.cpp')
-rw-r--r--linden/indra/newview/llvosurfacepatch.cpp70
1 files changed, 40 insertions, 30 deletions
diff --git a/linden/indra/newview/llvosurfacepatch.cpp b/linden/indra/newview/llvosurfacepatch.cpp
index 7055b30..9bb801a 100644
--- a/linden/indra/newview/llvosurfacepatch.cpp
+++ b/linden/indra/newview/llvosurfacepatch.cpp
@@ -945,45 +945,55 @@ BOOL LLVOSurfacePatch::lineSegmentIntersect(const LLVector3& start, const LLVect
945 945
946 //step one meter at a time until intersection point found 946 //step one meter at a time until intersection point found
947 947
948 const LLVector3* ext = mDrawable->getSpatialExtents();
949 F32 rad = (delta*tdelta).magVecSquared();
950
948 F32 t = 0.f; 951 F32 t = 0.f;
949 while ( t <= 1.f) 952 while ( t <= 1.f)
950 { 953 {
951 LLVector3 sample = origin + delta*t; 954 LLVector3 sample = origin + delta*t;
952 955
953 F32 height = mRegionp->getLandHeightRegion(sample); 956 if (AABBSphereIntersectR2(ext[0], ext[1], sample+mRegionp->getOriginAgent(), rad))
954 if (height > sample.mV[2]) 957 {
955 { //ray went below ground, positive intersection 958 F32 height = mRegionp->getLandHeightRegion(sample);
956 //quick and dirty binary search to get impact point 959 if (height > sample.mV[2])
957 tdelta = -tdelta*0.5f; 960 { //ray went below ground, positive intersection
958 F32 err_dist = 0.001f; 961 //quick and dirty binary search to get impact point
959 F32 dist = fabsf(sample.mV[2] - height); 962 tdelta = -tdelta*0.5f;
960 963 F32 err_dist = 0.001f;
961 while (dist > err_dist && tdelta*tdelta > 0.0f) 964 F32 dist = fabsf(sample.mV[2] - height);
962 { 965
963 t += tdelta; 966 while (dist > err_dist && tdelta*tdelta > 0.0f)
964 sample = origin+delta*t; 967 {
965 height = mRegionp->getLandHeightRegion(sample); 968 t += tdelta;
966 if ((tdelta < 0 && height < sample.mV[2]) || 969 sample = origin+delta*t;
967 (height > sample.mV[2] && tdelta > 0)) 970 height = mRegionp->getLandHeightRegion(sample);
968 { //jumped over intersection point, go back 971 if ((tdelta < 0 && height < sample.mV[2]) ||
969 tdelta = -tdelta; 972 (height > sample.mV[2] && tdelta > 0))
973 { //jumped over intersection point, go back
974 tdelta = -tdelta;
975 }
976 tdelta *= 0.5f;
977 dist = fabsf(sample.mV[2] - height);
970 } 978 }
971 tdelta *= 0.5f;
972 dist = fabsf(sample.mV[2] - height);
973 }
974 979
975 if (intersection) 980 if (intersection)
976 { 981 {
977 sample.mV[2] = mRegionp->getLandHeightRegion(sample); 982 F32 height = mRegionp->getLandHeightRegion(sample);
978 *intersection = sample + mRegionp->getOriginAgent(); 983 if (fabsf(sample.mV[2]-height) < delta.length()*tdelta)
979 } 984 {
985 sample.mV[2] = mRegionp->getLandHeightRegion(sample);
986 }
987 *intersection = sample + mRegionp->getOriginAgent();
988 }
980 989
981 if (normal) 990 if (normal)
982 { 991 {
983 *normal = mRegionp->getLand().resolveNormalGlobal(mRegionp->getPosGlobalFromRegion(sample)); 992 *normal = mRegionp->getLand().resolveNormalGlobal(mRegionp->getPosGlobalFromRegion(sample));
984 } 993 }
985 994
986 return TRUE; 995 return TRUE;
996 }
987 } 997 }
988 998
989 t += tdelta; 999 t += tdelta;