/** * @deprecated please use {@link #raycast(RayCastOutput, RayCastInput, IWorldPool)} for better * performance * @param output * @param input * @return */ public bool raycast(RayCastOutput output, RayCastInput input) { return(raycast(output, input, new DefaultWorldPool(4, 4))); }
/** * From Real-time Collision Detection, p179. * * @param output * @param input */ public bool raycast(RayCastOutput output, RayCastInput input, IWorldPool argPool) { double tmin = -double.MaxValue; double tmax = double.MaxValue; Vec2 p = argPool.popVec2(); Vec2 d = argPool.popVec2(); Vec2 absD = argPool.popVec2(); Vec2 normal = argPool.popVec2(); p.set(input.p1); d.set(input.p2).subLocal(input.p1); Vec2.absToOut(d, absD); // x then y if (absD.x < Settings.EPSILON) { // Parallel. if (p.x < lowerBound.x || upperBound.x < p.x) { argPool.pushVec2(4); return(false); } } else { double inv_d = 1.0d / d.x; double t1 = (lowerBound.x - p.x) * inv_d; double t2 = (upperBound.x - p.x) * inv_d; // Sign of the normal vector. double s = -1.0d; if (t1 > t2) { double temp = t1; t1 = t2; t2 = temp; s = 1.0d; } // Push the min up if (t1 > tmin) { normal.setZero(); normal.x = s; tmin = t1; } // Pull the max down tmax = MathUtils.min(tmax, t2); if (tmin > tmax) { argPool.pushVec2(4); return(false); } } if (absD.y < Settings.EPSILON) { // Parallel. if (p.y < lowerBound.y || upperBound.y < p.y) { argPool.pushVec2(4); return(false); } } else { double inv_d = 1.0d / d.y; double t1 = (lowerBound.y - p.y) * inv_d; double t2 = (upperBound.y - p.y) * inv_d; // Sign of the normal vector. double s = -1.0d; if (t1 > t2) { double temp = t1; t1 = t2; t2 = temp; s = 1.0d; } // Push the min up if (t1 > tmin) { normal.setZero(); normal.y = s; tmin = t1; } // Pull the max down tmax = MathUtils.min(tmax, t2); if (tmin > tmax) { argPool.pushVec2(4); return(false); } } // Does the ray start inside the box? // Does the ray intersect beyond the max fraction? if (tmin < 0.0d || input.maxFraction < tmin) { argPool.pushVec2(4); return(false); } // Intersection. output.fraction = tmin; output.normal.x = normal.x; output.normal.y = normal.y; argPool.pushVec2(4); return(true); }
public void set(RayCastOutput rco) { normal.set(rco.normal); fraction = rco.fraction; }