/// <summary> /// Indicates if a segment overlaps an AABox /// </summary> /// <param name="seg"></param> /// <param name="AABox"></param> /// <returns></returns> public static bool SegmentAABoxOverlap(Segment seg, AABox AABox) { Vector3 p0 = seg.Origin; Vector3 p1 = seg.GetEnd(); float[] faceOffsets = new float[2]; // The AABox faces are aligned with the world directions. Loop // over the 3 directions and do the two tests. for (int iDir = 0; iDir < 3; iDir++) { int jDir = (iDir + 1) % 3; int kDir = (iDir + 2) % 3; // one plane goes through the origin, one is offset faceOffsets[0] = JiggleUnsafe.Get(AABox.MinPos, iDir); faceOffsets[1] = JiggleUnsafe.Get(AABox.MaxPos, iDir); for (int iFace = 0; iFace < 2; iFace++) { // distance of each point from to the face plane float dist0 = JiggleUnsafe.Get(ref p0, iDir) - faceOffsets[iFace]; float dist1 = JiggleUnsafe.Get(ref p1, iDir) - faceOffsets[iFace]; float frac = -1.0f; if (dist0 * dist1 < -JiggleMath.Epsilon) frac = -dist0 / (dist1 - dist0); else if (System.Math.Abs(dist0) < JiggleMath.Epsilon) frac = 0.0f; else if (System.Math.Abs(dist1) < JiggleMath.Epsilon) frac = 1.0f; if (frac >= 0.0f) { //Assert(frac <= 1.0f); Vector3 pt = seg.GetPoint(frac); // check the point is within the face rectangle if ((JiggleUnsafe.Get(ref pt, jDir) > JiggleUnsafe.Get(AABox.MinPos, jDir) - JiggleMath.Epsilon) && (JiggleUnsafe.Get(ref pt, jDir) < JiggleUnsafe.Get(AABox.MaxPos, jDir) + JiggleMath.Epsilon) && (JiggleUnsafe.Get(ref pt, kDir) > JiggleUnsafe.Get(AABox.MinPos, kDir) - JiggleMath.Epsilon) && (JiggleUnsafe.Get(ref pt, kDir) < JiggleUnsafe.Get(AABox.MaxPos, kDir) + JiggleMath.Epsilon)) { return true; } } } } return false; }
/// <summary> /// Every skin must support a ray/segment intersection test - /// operates on the new value of the primitives /// </summary> /// <param name="frac"></param> /// <param name="pos"></param> /// <param name="normal"></param> /// <param name="seg"></param> /// <returns></returns> public bool SegmentIntersect(out float frac, out Vector3 pos, out Vector3 normal, Segment seg) { Vector3 segEnd = seg.GetEnd(); frac = float.MaxValue; float thisSegLenRelToOrig = 1.0f; Segment segCopy = seg; pos = normal = Vector3.Zero; for (int prim = primitivesNewWorld.Count; prim-- != 0; ) { float thisFrac; Vector3 newPosition = pos; if (primitivesNewWorld[prim].SegmentIntersect(out thisFrac, out newPosition, out normal, segCopy)) { pos = newPosition; frac = thisFrac * thisSegLenRelToOrig; segCopy.Delta *= thisFrac; thisSegLenRelToOrig *= frac; } } //System.Diagnostics.Debug.WriteLineIf(frac <= 1.0f, pos); return (frac <= 1.0f); }