public bool RayCast(out b2RayCastOutput output, b2RayCastInput input) { float tmin = -float.MaxValue; float tmax = float.MaxValue; b2Vec2 p = input.p1; b2Vec2 d = input.p2 - input.p1; b2Vec2 absD = b2Math.b2Abs(d); b2Vec2 normal = new b2Vec2(0,0); for (int i = 0; i < 2; ++i) { float p_i, lb, ub, d_i, absd_i; p_i = (i == 0 ? p.x : p.y); lb = (i == 0 ? m_lowerBound.x : m_lowerBound.y); ub = (i == 0 ? m_upperBound.x : m_upperBound.y); absd_i = (i == 0 ? absD.x : absD.y); d_i = (i == 0 ? d.x : d.y); if (absd_i < b2Settings.b2_epsilon) { // Parallel. if (p_i < lb || ub < p_i) { output.fraction = 0f; output.normal = new b2Vec2(0, 0); return false; } } else { float inv_d = 1.0f / d_i; float t1 = (lb - p_i) * inv_d; float t2 = (ub - p_i) * inv_d; // Sign of the normal vector. float s = -1.0f; if (t1 > t2) { b2Math.b2Swap(t1, t2); s = 1.0f; } // Push the min up if (t1 > tmin) { normal.SetZero(); if (i == 0) { normal.x = s; } else { normal.y = s; } tmin = t1; } // Pull the max down tmax = Math.Min(tmax, t2); if (tmin > tmax) { output.fraction = 0f; output.normal = new b2Vec2(0, 0); return false; } } } // Does the ray start inside the box? // Does the ray intersect beyond the max fraction? if (tmin < 0.0f || input.maxFraction < tmin) { output.fraction = 0f; output.normal = new b2Vec2(0, 0); return false; } // Intersection. output.fraction = tmin; output.normal = normal; return true; }
public virtual bool RayCast(out b2RayCastOutput output, b2RayCastInput input, int childIndex) { return m_shape.RayCast(out output, input, m_body.Transform, childIndex); }
public bool RayCast(out b2RayCastOutput output, b2RayCastInput input) { float tmin = -float.MaxValue; float tmax = float.MaxValue; b2Vec2 p = input.p1; b2Vec2 d = input.p2 - input.p1; b2Vec2 absD = b2Math.b2Abs(d); b2Vec2 normal = new b2Vec2(0, 0); for (int i = 0; i < 2; ++i) { float p_i, lb, ub, d_i, absd_i; p_i = (i == 0 ? p.x : p.y); lb = (i == 0 ? m_lowerBound.x : m_lowerBound.y); ub = (i == 0 ? m_upperBound.x : m_upperBound.y); absd_i = (i == 0 ? absD.x : absD.y); d_i = (i == 0 ? d.x : d.y); if (absd_i < b2Settings.b2_epsilon) { // Parallel. if (p_i < lb || ub < p_i) { output.fraction = 0f; output.normal = new b2Vec2(0, 0); return(false); } } else { float inv_d = 1.0f / d_i; float t1 = (lb - p_i) * inv_d; float t2 = (ub - p_i) * inv_d; // Sign of the normal vector. float s = -1.0f; if (t1 > t2) { b2Math.b2Swap(t1, t2); s = 1.0f; } // Push the min up if (t1 > tmin) { normal.SetZero(); if (i == 0) { normal.x = s; } else { normal.y = s; } tmin = t1; } // Pull the max down tmax = Math.Min(tmax, t2); if (tmin > tmax) { output.fraction = 0f; output.normal = new b2Vec2(0, 0); return(false); } } } // Does the ray start inside the box? // Does the ray intersect beyond the max fraction? if (tmin < 0.0f || input.maxFraction < tmin) { output.fraction = 0f; output.normal = new b2Vec2(0, 0); return(false); } // Intersection. output.fraction = tmin; output.normal = normal; return(true); }
private void RayCast() { m_rayActor = null; b2RayCastInput input = m_rayCastInput; // Ray cast against the dynamic tree. m_tree.RayCast(this, input); // Brute force ray cast. Actor bruteActor = null; b2RayCastOutput bruteOutput = new b2RayCastOutput(); for (int i = 0; i < e_actorCount; ++i) { if (m_actors[i].proxyId == b2_nullNode) { continue; } b2RayCastOutput output; bool hit = m_actors[i].aabb.RayCast(out output, input); if (hit) { bruteActor = m_actors[i]; bruteOutput = output; input.maxFraction = output.fraction; } } if (bruteActor != null) { Debug.Assert(bruteOutput.fraction == m_rayCastOutput.fraction); } }
public float RayCastCallback(ref b2RayCastInput input, int proxyId) { Actor actor = (Actor) m_tree.GetUserData(proxyId); b2RayCastOutput output = new b2RayCastOutput(); bool hit = actor.aabb.RayCast(out output, input); if (hit) { m_rayCastOutput = output; m_rayActor = actor; m_rayActor.fraction = output.fraction; return output.fraction; } return input.maxFraction; }
// From Real-time Collision Detection, p179. /** * Perform a precise raycast against the AABB. */ public bool RayCast(b2RayCastOutput output, b2RayCastInput input) { float tmin = -float.MaxValue; //float tmax = float.MaxValue; float pX = input.p1.x; float pY = input.p1.y; float dX = input.p2.x - input.p1.x; float dY = input.p2.y - input.p1.y; float absDX = Mathf.Abs(dX); float absDY = Mathf.Abs(dY); b2Vec2 normal = output.normal; float inv_d; float t1; float t2; float t3; float s; //x if (absDX < float.MinValue) { // Parallel. if (pX < lowerBound.x || upperBound.x < pX) { return(false); } } else { inv_d = 1.0f / dX; t1 = (lowerBound.x - pX) * inv_d; t2 = (upperBound.x - pX) * inv_d; // Sign of the normal vector s = -1.0f; if (t1 > t2) { t3 = t1; t1 = t2; t2 = t3; s = 1.0f; } // Push the min up if (t1 > tmin) { normal.x = s; normal.y = 0.0f; tmin = t1; } // Pull the max down float tmax = Mathf.Min(float.MaxValue, t2); if (tmin > tmax) { return(false); } } //y if (absDY < float.MinValue) { // Parallel. if (pY < lowerBound.y || upperBound.y < pY) { return(false); } } else { inv_d = 1.0f / dY; t1 = (lowerBound.y - pY) * inv_d; t2 = (upperBound.y - pY) * inv_d; // Sign of the normal vector s = -1.0f; if (t1 > t2) { t3 = t1; t1 = t2; t2 = t3; s = 1.0f; } // Push the min up if (t1 > tmin) { normal.y = s; normal.x = 0.0f; tmin = t1; } // Pull the max down float tmax = Mathf.Min(float.MaxValue, t2); if (tmin > tmax) { return(false); } } output.fraction = tmin; return(true); }