summaryrefslogtreecommitdiff
path: root/indra/newview/llvosurfacepatch.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llvosurfacepatch.cpp')
-rw-r--r--indra/newview/llvosurfacepatch.cpp81
1 files changed, 81 insertions, 0 deletions
diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp
index 968cc69d3a..e912a19f81 100644
--- a/indra/newview/llvosurfacepatch.cpp
+++ b/indra/newview/llvosurfacepatch.cpp
@@ -916,6 +916,87 @@ void LLVOSurfacePatch::getGeomSizesEast(const S32 stride, const S32 east_stride,
}
}
+BOOL LLVOSurfacePatch::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, S32 face, BOOL pick_transparent, S32 *face_hitp,
+ LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal)
+
+{
+
+ if (!lineSegmentBoundingBox(start, end))
+ {
+ return FALSE;
+ }
+
+ LLVector3 delta = end-start;
+
+ LLVector3 pdelta = delta;
+ pdelta.mV[2] = 0;
+
+ F32 plength = pdelta.length();
+
+ F32 tdelta = 1.f/plength;
+
+ LLVector3 origin = start - mRegionp->getOriginAgent();
+
+ if (mRegionp->getLandHeightRegion(origin) > origin.mV[2])
+ {
+ //origin is under ground, treat as no intersection
+ return FALSE;
+ }
+
+ //step one meter at a time until intersection point found
+
+ F32 t = 0.f;
+ while ( t <= 1.f)
+ {
+ LLVector3 sample = origin + delta*t;
+
+ F32 height = mRegionp->getLandHeightRegion(sample);
+ if (height > sample.mV[2])
+ { //ray went below ground, positive intersection
+ //quick and dirty binary search to get impact point
+ tdelta = -tdelta*0.5f;
+ F32 err_dist = 0.001f;
+ F32 dist = fabsf(sample.mV[2] - height);
+
+ while (dist > err_dist && tdelta*tdelta > 0.0f)
+ {
+ t += tdelta;
+ sample = origin+delta*t;
+ height = mRegionp->getLandHeightRegion(sample);
+ if ((tdelta < 0 && height < sample.mV[2]) ||
+ (height > sample.mV[2] && tdelta > 0))
+ { //jumped over intersection point, go back
+ tdelta = -tdelta;
+ }
+ tdelta *= 0.5f;
+ dist = fabsf(sample.mV[2] - height);
+ }
+
+ if (intersection)
+ {
+ sample.mV[2] = mRegionp->getLandHeightRegion(sample);
+ *intersection = sample + mRegionp->getOriginAgent();
+ }
+
+ if (normal)
+ {
+ *normal = mRegionp->getLand().resolveNormalGlobal(mRegionp->getPosGlobalFromRegion(sample));
+ }
+
+ return TRUE;
+ }
+
+ t += tdelta;
+ if (t > 1 && t < 1.f+tdelta*0.99f)
+ { //make sure end point is checked (saves vertical lines coming up negative)
+ t = 1.f;
+ }
+ }
+
+
+ return FALSE;
+}
+
void LLVOSurfacePatch::updateSpatialExtents(LLVector3& newMin, LLVector3 &newMax)
{
LLVector3 posAgent = getPositionAgent();