void TraceToDispTree(DispCollTree dispTree, Vector3 start, Vector3 end, Vector3 mins, Vector3 maxs, float startf, float endf, trace_t trace, bool raycast) { if (raycast) { } else { Vector3 boxExtends = ((mins + maxs) * 0.5f) - mins; if(dispTree.AABBSweep(start, end, boxExtends, startf, endf, ref trace)) { } } }
bool OnLadder(trace_t trace) { if ((trace.contents & (int)brushflags.CONTENTS_LADDER) > 0) return true; return false; }
void IntersectAABoxSweptTriangle(Vector3 start, Vector3 end, Vector3 extends, Vector3 v1, Vector3 v2, Vector3 v3, Vector3 triNormal, float triDist, ushort triFlags, ushort triSurfProp, ref trace_t trace, bool startsOutside) { // // make sure the box and triangle are not initially intersecting!! // NOTE: if bStartOutside is set -- this is assumed // if( !startsOutside ) { // check for interection -- if not intersecting continue, otherwise // return and let the "in solid" functions handle it } // // initialize the axial-aligned box sweep triangle test // bool bStartOutSolid = false; bool bEndOutSolid = false; float fracStart = NEVER_UPDATED; float fracEnd = 1.0f; // calculate the box direction - the sweep direction Vector3 boxDir = end - start; // // OPTIMIZATION: make sure objects are traveling toward one another // float angle = Vector3.Dot(triNormal, boxDir);// triNormal.Dot(boxDir); if( angle/*triNormal.Dot( boxDir )*/ > ClipMap.EPSILON ) { return; } // test against the triangle face plane if (!FacePlane(triNormal, triDist, start, end, extends, ref fracStart, ref fracEnd, v1, v2, v3, bStartOutSolid, bEndOutSolid)) { return; } // test against axial planes (of the aabb) if (!AxialPlanesXYZ(v1, v2, v3, start, end, extends, boxDir, triNormal, ref fracStart, ref fracEnd, bStartOutSolid, bEndOutSolid)) { return; } // // There are 9 edge tests - edges 1, 2, 3 cross with the box edges (symmetry) 1, 2, 3. However, the box // is axial-aligned resulting in axially directional edges -- thus each test is edges 1, 2, and 3 vs. // axial planes x, y, and z // // There are potentially 9 more tests with edges, the edge's edges and the direction of motion! // NOTE: I don't think these tests are necessary for a manifold surface -- but they still remain if // it ever becomes a problem in the future! // Vector3 edge; // edge 1 - axial tests are 2d tests, swept direction is a 3d test edge = v2 - v1; if (!EdgeCrossAxialX(edge, v1, v3, extends, start, end, triNormal, triDist, ref fracStart, ref fracEnd, bStartOutSolid, bEndOutSolid, 4)) { return; } if (!EdgeCrossAxialY(edge, v1, v3, extends, start, end, triNormal, triDist, ref fracStart, ref fracEnd, bStartOutSolid, bEndOutSolid, 5)) { return; } if (!EdgeCrossAxialZ(edge, v1, v3, extends, start, end, triNormal, triDist, ref fracStart, ref fracEnd, bStartOutSolid, bEndOutSolid, 6)) { return; } // if( !EdgeCrossSweptDir( edge, v1, v3, boxDir, boxExtents, boxStart, boxEnd, fracStart, fracEnd ) ) { fraction = fracStart; return; } // edge 2 - axial tests are 2d tests, swept direction is a 3d test edge = v3 - v2; if (!EdgeCrossAxialX(edge, v2, v1, extends, start, end, triNormal, triDist, ref fracStart, ref fracEnd, bStartOutSolid, bEndOutSolid, 7)) { return; } if (!EdgeCrossAxialY(edge, v2, v1, extends, start, end, triNormal, triDist, ref fracStart, ref fracEnd, bStartOutSolid, bEndOutSolid, 8)) { return; } if (!EdgeCrossAxialZ(edge, v2, v1, extends, start, end, triNormal, triDist, ref fracStart, ref fracEnd, bStartOutSolid, bEndOutSolid, 9)) { return; } // if( !EdgeCrossSweptDir( edge, v2, v1, boxDir, boxExtents, boxStart, boxEnd, fracStart, fracEnd ) ) { fraction = fracStart; return; } // edge 3 - axial tests are 2d tests, swept direction is a 3d test edge = v1 - v3; if (!EdgeCrossAxialX(edge, v3, v2, extends, start, end, triNormal, triDist, ref fracStart, ref fracEnd, bStartOutSolid, bEndOutSolid, 10)) { return; } if (!EdgeCrossAxialY(edge, v3, v2, extends, start, end, triNormal, triDist, ref fracStart, ref fracEnd, bStartOutSolid, bEndOutSolid, 11)) { return; } if (!EdgeCrossAxialZ(edge, v3, v2, extends, start, end, triNormal, triDist, ref fracStart, ref fracEnd, bStartOutSolid, bEndOutSolid, 12)) { return; } // if( !EdgeCrossSweptDir( edge, v2, v1, boxDir, boxExtents, boxStart, boxEnd, fracStart, fracEnd ) ) { fraction = fracStart; return; } // // the direction of motion crossed with the axial planes is equivolent // to cross the box (axial planes) and the // // if( !DirectionOfMotionCrossAxialPlanes( boxStart, boxEnd, boxDir, boxExtents, fracStart, fracEnd, v1, v2, v3 ) ) { fraction = fracStart; return; } // // didn't have a separating axis -- update trace data -- should I handle a fraction left solid here!???? // if (fracStart < fracEnd) { if ((fracStart > NEVER_UPDATED) && (fracStart < trace.fraction)) { // clamp -- shouldn't really ever be here!??? if (fracStart < 0.0f) { fracStart = 0.0f; } trace.fraction = fracStart; trace.plane.normal = triNormal; trace.plane.dist = triDist; //trace.dispFlags = triFlags; m_iLatestSurfProp = triSurfProp; } } }
void SweptAABB_IntersectTriList(Vector3 start, Vector3 end, Vector3 extends, float startf, float endf, ref trace_t trace, TriList_t trilist) { Vector3 impactNormal = new Vector3(); float impactDist = 0f; Tri_t tri; // // intersect against all the flagged triangles in trilist // for (int iTri = 0; iTri < trilist.Count; iTri++) { // get the current displacement tri = trilist.ppTriList[iTri]; // intersection test IntersectAABoxSweptTriangle(start, end, extends, m_pVerts[tri.m_uiVerts[0]], m_pVerts[tri.m_uiVerts[2]], m_pVerts[tri.m_uiVerts[1]], tri.m_vecNormal, tri.m_flDist, tri.m_nFlags, tri.m_iSurfProp, /*fraction,*/ref trace, 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; }