diff options
Diffstat (limited to 'linden/indra/newview/llvosurfacepatch.cpp')
-rw-r--r-- | linden/indra/newview/llvosurfacepatch.cpp | 70 |
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; |