diff options
Diffstat (limited to 'linden/indra/newview/llvosurfacepatch.cpp')
-rw-r--r-- | linden/indra/newview/llvosurfacepatch.cpp | 93 |
1 files changed, 92 insertions, 1 deletions
diff --git a/linden/indra/newview/llvosurfacepatch.cpp b/linden/indra/newview/llvosurfacepatch.cpp index 310a745..66c8dac 100644 --- a/linden/indra/newview/llvosurfacepatch.cpp +++ b/linden/indra/newview/llvosurfacepatch.cpp | |||
@@ -4,7 +4,7 @@ | |||
4 | * | 4 | * |
5 | * $LicenseInfo:firstyear=2001&license=viewergpl$ | 5 | * $LicenseInfo:firstyear=2001&license=viewergpl$ |
6 | * | 6 | * |
7 | * Copyright (c) 2001-2008, Linden Research, Inc. | 7 | * Copyright (c) 2001-2009, Linden Research, Inc. |
8 | * | 8 | * |
9 | * Second Life Viewer Source Code | 9 | * Second Life Viewer Source Code |
10 | * The source code in this file ("Source Code") is provided by Linden Lab | 10 | * The source code in this file ("Source Code") is provided by Linden Lab |
@@ -916,6 +916,97 @@ void LLVOSurfacePatch::getGeomSizesEast(const S32 stride, const S32 east_stride, | |||
916 | } | 916 | } |
917 | } | 917 | } |
918 | 918 | ||
919 | BOOL LLVOSurfacePatch::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, S32 face, BOOL pick_transparent, S32 *face_hitp, | ||
920 | LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal) | ||
921 | |||
922 | { | ||
923 | |||
924 | if (!lineSegmentBoundingBox(start, end)) | ||
925 | { | ||
926 | return FALSE; | ||
927 | } | ||
928 | |||
929 | LLVector3 delta = end-start; | ||
930 | |||
931 | LLVector3 pdelta = delta; | ||
932 | pdelta.mV[2] = 0; | ||
933 | |||
934 | F32 plength = pdelta.length(); | ||
935 | |||
936 | F32 tdelta = 1.f/plength; | ||
937 | |||
938 | LLVector3 origin = start - mRegionp->getOriginAgent(); | ||
939 | |||
940 | if (mRegionp->getLandHeightRegion(origin) > origin.mV[2]) | ||
941 | { | ||
942 | //origin is under ground, treat as no intersection | ||
943 | return FALSE; | ||
944 | } | ||
945 | |||
946 | //step one meter at a time until intersection point found | ||
947 | |||
948 | const LLVector3* ext = mDrawable->getSpatialExtents(); | ||
949 | F32 rad = (delta*tdelta).magVecSquared(); | ||
950 | |||
951 | F32 t = 0.f; | ||
952 | while ( t <= 1.f) | ||
953 | { | ||
954 | LLVector3 sample = origin + delta*t; | ||
955 | |||
956 | if (AABBSphereIntersectR2(ext[0], ext[1], sample+mRegionp->getOriginAgent(), rad)) | ||
957 | { | ||
958 | F32 height = mRegionp->getLandHeightRegion(sample); | ||
959 | if (height > sample.mV[2]) | ||
960 | { //ray went below ground, positive intersection | ||
961 | //quick and dirty binary search to get impact point | ||
962 | tdelta = -tdelta*0.5f; | ||
963 | F32 err_dist = 0.001f; | ||
964 | F32 dist = fabsf(sample.mV[2] - height); | ||
965 | |||
966 | while (dist > err_dist && tdelta*tdelta > 0.0f) | ||
967 | { | ||
968 | t += tdelta; | ||
969 | sample = origin+delta*t; | ||
970 | height = mRegionp->getLandHeightRegion(sample); | ||
971 | if ((tdelta < 0 && height < sample.mV[2]) || | ||
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); | ||
978 | } | ||
979 | |||
980 | if (intersection) | ||
981 | { | ||
982 | F32 height = mRegionp->getLandHeightRegion(sample); | ||
983 | if (fabsf(sample.mV[2]-height) < delta.length()*tdelta) | ||
984 | { | ||
985 | sample.mV[2] = mRegionp->getLandHeightRegion(sample); | ||
986 | } | ||
987 | *intersection = sample + mRegionp->getOriginAgent(); | ||
988 | } | ||
989 | |||
990 | if (normal) | ||
991 | { | ||
992 | *normal = mRegionp->getLand().resolveNormalGlobal(mRegionp->getPosGlobalFromRegion(sample)); | ||
993 | } | ||
994 | |||
995 | return TRUE; | ||
996 | } | ||
997 | } | ||
998 | |||
999 | t += tdelta; | ||
1000 | if (t > 1 && t < 1.f+tdelta*0.99f) | ||
1001 | { //make sure end point is checked (saves vertical lines coming up negative) | ||
1002 | t = 1.f; | ||
1003 | } | ||
1004 | } | ||
1005 | |||
1006 | |||
1007 | return FALSE; | ||
1008 | } | ||
1009 | |||
919 | void LLVOSurfacePatch::updateSpatialExtents(LLVector3& newMin, LLVector3 &newMax) | 1010 | void LLVOSurfacePatch::updateSpatialExtents(LLVector3& newMin, LLVector3 &newMax) |
920 | { | 1011 | { |
921 | LLVector3 posAgent = getPositionAgent(); | 1012 | LLVector3 posAgent = getPositionAgent(); |