void SweptAABB_BuildTriList(Vector3 start, Vector3 end, Vector3 extends, int nodeid, AABB_t AABBox, TriList_t triList) { // get the current node Node_t node = m_pNodes[nodeid]; // // fill in AABBox plane distances // AABBox.Dists[0] = -(node.m_BBox[0].X - ClipMap.EPSILON); AABBox.Dists[1] = (node.m_BBox[1].X + ClipMap.EPSILON); AABBox.Dists[2] = -(node.m_BBox[0].Y - ClipMap.EPSILON); AABBox.Dists[3] = (node.m_BBox[1].Y + ClipMap.EPSILON); AABBox.Dists[4] = -(node.m_BBox[0].Z - ClipMap.EPSILON); AABBox.Dists[5] = (node.m_BBox[1].Z + ClipMap.EPSILON); // test the swept box against the given node if (SweptAABB_NodeTest(start, end, extends, AABBox)) { // // if leaf add tris to list // if ((node.m_fFlags & 0x01) > 0) { if (triList.Count < DISPCOLL_TRILIST_SIZE) { triList.ppTriList[triList.Count] = m_pTris[node.m_iTris[0]]; triList.ppTriList[triList.Count + 1] = m_pTris[node.m_iTris[1]]; triList.Count += 2; } return; } // continue testing with children nodes else { SweptAABB_BuildTriList(start, end, extends, Nodes_GetChild(nodeid, 0), AABBox, triList); SweptAABB_BuildTriList(start, end, extends, Nodes_GetChild(nodeid, 1), AABBox, triList); SweptAABB_BuildTriList(start, end, extends, Nodes_GetChild(nodeid, 2), AABBox, triList); SweptAABB_BuildTriList(start, end, extends, Nodes_GetChild(nodeid, 3), AABBox, triList); } } }
bool SweptAABB_NodeTest(Vector3 start, Vector3 end, Vector3 extends, AABB_t AABBox) { // // create and initialize the enter and exit fractions // float enterFraction = 0.0f; float exitFraction = 1.0f; // // test the ray against the AABB (reduced to 1d tests) // float distStart, distEnd, fraction; for (int ndxAxis = 0; ndxAxis < 3; ndxAxis++) { // // test negative axial direction // distStart = -start[ndxAxis] - (AABBox.Dists[(ndxAxis << 1)] + extends[ndxAxis] /*+ DIST_EPSILON*/ ); distEnd = -end[ndxAxis] - (AABBox.Dists[(ndxAxis << 1)] + extends[ndxAxis] /*+ DIST_EPSILON*/ ); if ((distStart > 0.0f) && (distEnd < 0.0f)) { fraction = (distStart - ClipMap.EPSILON) / (distStart - distEnd); // fraction = distStart * scalar[ndxAxis]; if (fraction > enterFraction) { enterFraction = fraction; } } else if ((distStart < 0.0f) && (distEnd > 0.0f)) { fraction = (distStart + ClipMap.EPSILON) / (distStart - distEnd); // fraction = distStart * scalar[ndxAxis]; if (fraction < exitFraction) { exitFraction = fraction; } } else if ((distStart > 0.0f) && (distEnd > 0.0f)) { return false; } // // test positive axial direction // distStart = start[ndxAxis] - (AABBox.Dists[(ndxAxis << 1) + 1] + extends[ndxAxis] /*+ DIST_EPSILON*/ ); distEnd = end[ndxAxis] - (AABBox.Dists[(ndxAxis << 1) + 1] + extends[ndxAxis] /*+ DIST_EPSILON*/ ); if ((distStart > 0.0f) && (distEnd < 0.0f)) { fraction = (distStart - ClipMap.EPSILON) / (distStart - distEnd); // fraction = distStart * scalar[ndxAxis]; if (fraction > enterFraction) { enterFraction = fraction; } } else if ((distStart < 0.0f) && (distEnd > 0.0f)) { fraction = (distStart + ClipMap.EPSILON) / (distStart - distEnd); // fraction = distStart * scalar[ndxAxis]; if (fraction < exitFraction) { exitFraction = fraction; } } else if ((distStart > 0.0f) && (distEnd > 0.0f)) { return false; } } // test results if (exitFraction < enterFraction) return false; return true; }
public bool AABBSweep(Vector3 start, Vector3 end, Vector3 extends, float startf, float endf, ref trace_t trace) { // // create and initialize the triangle list // TriList_t trilist = new TriList_t(); // // create and initialize the primary AABB // AABB_t AABBox = new AABB_t(); // // sweep box against the axial-aligned bboxed quad-tree and generate an initial // list of collision tris // SweptAABB_BuildTriList(start, end, extends, 0, AABBox, trilist); // save the starting fraction float preIntersectionFrac = trace.fraction; // // sweep axis-aligned bounding box against the triangles in the list // if (trilist.Count > 0) { SweptAABB_IntersectTriList(start, end, extends, startf, endf, ref trace, trilist); } // collision if (preIntersectionFrac > trace.fraction) return true; // no collision return false; }