// GetBoxTriangleIntersectionPoints // Pushes intersection points onto the back of pts. Returns the // number of points found. // Points that are close together (compared to // combinationDistance) get combined private int GetBoxTriangleIntersectionPoints(List <MyCP> pts, MyBox box, MyColDetVoxelTriangle triangle, float combinationDistance) { // first intersect each edge of the box with the triangleVertexes MyBox.Edge[] edges; box.GetEdges(out edges); Vector3[] boxPts; box.GetCornerPoints(out boxPts); float tS; float tv1, tv2; int iEdge; for (iEdge = 0; iEdge < 12; ++iEdge) { MyBox.Edge edge = edges[iEdge]; MySegment seg = new MySegment(boxPts[(int)edge.Ind0], boxPts[(int)edge.Ind1] - boxPts[(int)edge.Ind0]); if (this.SegmentTriangleIntersection(out tS, out tv1, out tv2, seg, triangle)) { float depthA = Vector3.Dot(boxPts[(int)edge.Ind0] - seg.GetPoint(tS), triangle.Normal); float depthB = Vector3.Dot(boxPts[(int)edge.Ind1] - seg.GetPoint(tS), triangle.Normal); AddPoint(pts, seg.GetPoint(tS), triangle.Normal, depthA < depthB ? depthA : depthB, combinationDistance * combinationDistance); } } Vector3 pos, n; // now each edge of the triangleVertexes with the box for (iEdge = 0; iEdge < 3; ++iEdge) { Vector3 pt0 = triangle.GetPoint(iEdge); Vector3 pt1 = triangle.GetPoint((iEdge + 1) % 3); MySegment s1 = new MySegment(pt0, pt1 - pt0); MySegment s2 = new MySegment(pt1, pt0 - pt1); if (box.SegmentIntersect(out tS, out pos, out n, s1)) { float depthA = Vector3.Dot(pt0 - pos, triangle.Normal); float depthB = Vector3.Dot(pt1 - pos, triangle.Normal); AddPoint(pts, pos, triangle.Normal, depthA < depthB ? depthA : depthB, combinationDistance * combinationDistance); } if (box.SegmentIntersect(out tS, out pos, out n, s2)) { float depthA = Vector3.Dot(pt0 - pos, triangle.Normal); float depthB = Vector3.Dot(pt1 - pos, triangle.Normal); AddPoint(pts, pos, triangle.Normal, depthA < depthB ? depthA : depthB, combinationDistance * combinationDistance); } } return(pts.Count); }
public bool SegmentIntersect(out float fracOut, out Vector3 posOut, out Vector3 normalOut, MySegment seg) { fracOut = float.MaxValue; posOut = normalOut = Vector3.Zero; // algo taken from p674 of realting rendering // needs debugging float min = float.MinValue; float max = float.MaxValue; Vector3 p = GetCentre() - seg.Origin; Vector3 h; h.X = m_sideLengths.X * 0.5f; h.Y = m_sideLengths.Y * 0.5f; h.Z = m_sideLengths.Z * 0.5f; int dirMax = 0; int dirMin = 0; int dir = 0; //Vector3[] matrixVec = new Vector3[3]; MyVector3Array3 matrixVec = new MyVector3Array3(); matrixVec[0] = Transform.Orientation.Right; matrixVec[1] = Transform.Orientation.Up; matrixVec[2] = Transform.Orientation.Backward; //float[] vectorFloat = new float[3]; MyFloatArray3 vectorFloat = new MyFloatArray3(); vectorFloat[0] = h.X; vectorFloat[1] = h.Y; vectorFloat[2] = h.Z; for (dir = 0; dir < 3; dir++) { float e = Vector3.Dot(matrixVec[dir], p); float f = Vector3.Dot(matrixVec[dir], seg.Delta); if (System.Math.Abs(f) > MyPhysicsConfig.CollisionEpsilon) { float t1 = (e + vectorFloat[dir]) / f; float t2 = (e - vectorFloat[dir]) / f; if (t1 > t2) { float tmp = t1; t1 = t2; t2 = tmp; } if (t1 > min) { min = t1; dirMin = dir; } if (t2 < max) { max = t2; dirMax = dir; } if (min > max) return false; if (max < 0.0f) return false; } else if ((-e - vectorFloat[dir] > 0.0f) || (-e + vectorFloat[dir] < 0.0f)) { return false; } } if (min > 0.0f) { dir = dirMin; fracOut = min; } else { dir = dirMax; fracOut = max; } fracOut = MathHelper.Clamp(fracOut, 0.0f, 1.0f); posOut = seg.GetPoint(fracOut); if (Vector3.Dot(matrixVec[dir], seg.Delta) > 0.0f) normalOut = -matrixVec[dir]; else normalOut = matrixVec[dir]; return true; }
public bool SegmentIntersect(out float fracOut, out Vector3 posOut, out Vector3 normalOut, MySegment seg) { fracOut = float.MaxValue; posOut = normalOut = Vector3.Zero; // algo taken from p674 of realting rendering // needs debugging float min = float.MinValue; float max = float.MaxValue; Vector3 p = GetCentre() - seg.Origin; Vector3 h; h.X = m_sideLengths.X * 0.5f; h.Y = m_sideLengths.Y * 0.5f; h.Z = m_sideLengths.Z * 0.5f; int dirMax = 0; int dirMin = 0; int dir = 0; //Vector3[] matrixVec = new Vector3[3]; MyVector3Array3 matrixVec = new MyVector3Array3(); matrixVec[0] = Transform.Orientation.Right; matrixVec[1] = Transform.Orientation.Up; matrixVec[2] = Transform.Orientation.Backward; //float[] vectorFloat = new float[3]; MyFloatArray3 vectorFloat = new MyFloatArray3(); vectorFloat[0] = h.X; vectorFloat[1] = h.Y; vectorFloat[2] = h.Z; for (dir = 0; dir < 3; dir++) { float e = Vector3.Dot(matrixVec[dir], p); float f = Vector3.Dot(matrixVec[dir], seg.Delta); if (System.Math.Abs(f) > MyPhysicsConfig.CollisionEpsilon) { float t1 = (e + vectorFloat[dir]) / f; float t2 = (e - vectorFloat[dir]) / f; if (t1 > t2) { float tmp = t1; t1 = t2; t2 = tmp; } if (t1 > min) { min = t1; dirMin = dir; } if (t2 < max) { max = t2; dirMax = dir; } if (min > max) { return(false); } if (max < 0.0f) { return(false); } } else if ((-e - vectorFloat[dir] > 0.0f) || (-e + vectorFloat[dir] < 0.0f)) { return(false); } } if (min > 0.0f) { dir = dirMin; fracOut = min; } else { dir = dirMax; fracOut = max; } fracOut = MathHelper.Clamp(fracOut, 0.0f, 1.0f); posOut = seg.GetPoint(fracOut); if (Vector3.Dot(matrixVec[dir], seg.Delta) > 0.0f) { normalOut = -matrixVec[dir]; } else { normalOut = matrixVec[dir]; } return(true); }
// GetBoxTriangleIntersectionPoints // Pushes intersection points onto the back of pts. Returns the // number of points found. // Points that are close together (compared to // combinationDistance) get combined private int GetBoxTriangleIntersectionPoints(List<MyCP> pts, MyBox box, MyColDetVoxelTriangle triangle, float combinationDistance) { // first intersect each edge of the box with the triangleVertexes MyBox.Edge[] edges; box.GetEdges(out edges); Vector3[] boxPts; box.GetCornerPoints(out boxPts); float tS; float tv1, tv2; int iEdge; for (iEdge = 0; iEdge < 12; ++iEdge) { MyBox.Edge edge = edges[iEdge]; MySegment seg = new MySegment(boxPts[(int)edge.Ind0], boxPts[(int)edge.Ind1] - boxPts[(int)edge.Ind0]); if (this.SegmentTriangleIntersection(out tS, out tv1, out tv2, seg, triangle)) { float depthA = Vector3.Dot(boxPts[(int)edge.Ind0] - seg.GetPoint(tS), triangle.Normal); float depthB = Vector3.Dot(boxPts[(int)edge.Ind1] - seg.GetPoint(tS), triangle.Normal); AddPoint(pts, seg.GetPoint(tS),triangle.Normal, depthA < depthB ? depthA : depthB , combinationDistance * combinationDistance); } } Vector3 pos, n; // now each edge of the triangleVertexes with the box for (iEdge = 0; iEdge < 3; ++iEdge) { Vector3 pt0 = triangle.GetPoint(iEdge); Vector3 pt1 = triangle.GetPoint((iEdge + 1) % 3); MySegment s1 = new MySegment(pt0, pt1 - pt0); MySegment s2 = new MySegment(pt1, pt0 - pt1); if (box.SegmentIntersect(out tS, out pos, out n, s1)) { float depthA = Vector3.Dot(pt0 - pos, triangle.Normal); float depthB = Vector3.Dot(pt1 - pos, triangle.Normal); AddPoint(pts, pos, triangle.Normal, depthA < depthB ? depthA : depthB, combinationDistance * combinationDistance); } if (box.SegmentIntersect(out tS, out pos, out n, s2)) { float depthA = Vector3.Dot(pt0 - pos, triangle.Normal); float depthB = Vector3.Dot(pt1 - pos, triangle.Normal); AddPoint(pts, pos, triangle.Normal, depthA < depthB ? depthA : depthB, combinationDistance * combinationDistance); } } return pts.Count; }