/* * Author: Needles * https://steamcommunity.com/profiles/76561198026257137/ */ Collision <- {}; Collision.ResolveCollisions <- function(contactListOutput, resolutionTableOutput, pos, velocity, bboxMin, bboxMax, mask, ignore, maxIterations) { local trace = { start = pos, end = pos + velocity, hullmin = bboxMin, hullmax = bboxMax, mask = mask, ignore = ignore, }; local resolvedPos = pos + velocity; local count = 0; for(; count < maxIterations; count++) { trace.start = pos; trace.end = pos + velocity; if (TraceHull(trace) == false) { break; } if (trace.hit == false) { break; } // Now do some math to resolve the collision local a = trace.pos.Dot(trace.plane_normal); local b = (pos + velocity).Dot(trace.plane_normal); resolvedPos = pos + velocity + (trace.plane_normal * (a - b)); velocity = resolvedPos - trace.pos; pos = trace.pos; // Keep track of the collision output contactListOutput.append( { pos = trace.pos, normal = trace.plane_normal, name = trace.surface_name, flags = trace.surface_flags, props = trace.surface_props, } ); } // Output the final collision resolution if (count > 0) { resolutionTableOutput.pos <- resolvedPos; resolutionTableOutput.velocity <- velocity; return true; } return false; }; Collision.RaySphereIntersect <- function (intersectOutput, start, end, point, radius) { if (radius == 0.0) { return false; } local n = (end - start) n.Norm(); local l = point - start local ta = n.Dot(l); if (ta < 0) { return false; } local d = sqrt(l.Dot(l) - ta*ta); if (d > radius) { return false; } local tb = sqrt(radius*radius - d*d); intersectOutput.start <- ta - tb; intersectOutput.end <- ta + tb; return true; }; Collision.PointInBox <- function(point, min, max) { if ( point.x >= min.x && point.x <= max.x && point.y >= min.y && point.y <= max.y && point.z >= min.z && point.z <= max.z ) { return true; } return false; }