/** * 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); }
/// <summary> /// From Real-time Collision Detection, p179. /// </summary> /// <param name="output"></param> /// <param name="input"></param> public bool raycast(RayCastOutput output, RayCastInput input, IWorldPool argPool) { //UPGRADE_TODO: The equivalent in .NET for field 'java.lang.Float.MIN_VALUE' may return a different value. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1043'" float tmin = Single.Epsilon; float tmax = Single.MaxValue; Vec2 p = argPool.popVec2(); Vec2 d = argPool.popVec2(); Vec2 absD = argPool.popVec2(); Vec2 normal = argPool.popVec2(); p.set_Renamed(input.p1); d.set_Renamed(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 { float inv_d = 1.0f / d.x; float t1 = (lowerBound.x - p.x) * inv_d; float t2 = (upperBound.x - p.x) * inv_d; // Sign of the normal vector. float s = -1.0f; if (t1 > t2) { float temp = t1; t1 = t2; t2 = temp; s = 1.0f; } // 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 { float inv_d = 1.0f / d.y; float t1 = (lowerBound.y - p.y) * inv_d; float t2 = (upperBound.y - p.y) * inv_d; // Sign of the normal vector. float s = -1.0f; if (t1 > t2) { float temp = t1; t1 = t2; t2 = temp; s = 1.0f; } // 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.0f || 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; }
/** * From Real-time Collision Detection, p179. * * @param output * @param input */ public bool raycast(RayCastOutput output, RayCastInput input, IWorldPool argPool) { float tmin = float.MinValue; float tmax = float.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); d.subLocal(input.p1); Vec2.absToOut(d, ref 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 { float inv_d = 1.0f/d.x; float t1 = (lowerBound.x - p.x)*inv_d; float t2 = (upperBound.x - p.x)*inv_d; // Sign of the normal vector. float s = -1.0f; if (t1 > t2) { float temp = t1; t1 = t2; t2 = temp; s = 1.0f; } // 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 { float inv_d = 1.0f/d.y; float t1 = (lowerBound.y - p.y)*inv_d; float t2 = (upperBound.y - p.y)*inv_d; // Sign of the normal vector. float s = -1.0f; if (t1 > t2) { float temp = t1; t1 = t2; t2 = temp; s = 1.0f; } // 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.0f || 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; }