/// Implement Shape. // Collision Detection in Interactive 3D Environments by Gino van den Bergen // From Section 3.1.2 // x = s + a * r // norm(x) = radius public override bool RayCast(out RayCastOutput output, RayCastInput input, Transform transform, int childIndex){ throw new NotImplementedException(); //Vec2 position = transform.p + Utilities.Mul(transform.q, m_p); //Vec2 s = input.p1 - position; //float b = Utilities.Dot(s, s) - m_radius * m_radius; //// Solve quadratic equation. //Vec2 r = input.p2 - input.p1; //float c = Utilities.Dot(s, r); //float rr = Utilities.Dot(r, r); //float sigma = c * c - rr * b; //// Check for negative discriminant and short segment. //if (sigma < 0.0f || rr < Single.Epsilon) //{ // return false; //} //// Find the point of intersection of the line with the circle. //float a = -(c + (float)Math.Sqrt(sigma)); //// Is the intersection point on the segment? //if (0.0f <= a && a <= input.maxFraction * rr) //{ // a /= rr; // output.fraction = a; // output.normal = s + a * r; // output.normal.Normalize(); // return true; //} //return false; }
/// Implement Shape. // p = p1 + t * d // v = v1 + s * e // p1 + t * d = v1 + s * e // s * e - t * d = p1 - v1 public override bool RayCast(out RayCastOutput output, RayCastInput input, Transform transform, int childIndex){ throw new NotImplementedException(); //// Put the ray into the edge's frame of reference. //Vec2 p1 = Utilities.MulT(xf.q, input.p1 - xf.p); //Vec2 p2 = Utilities.MulT(xf.q, input.p2 - xf.p); //Vec2 d = p2 - p1; //Vec2 v1 = m_vertex1; //Vec2 v2 = m_vertex2; //Vec2 e = v2 - v1; //Vec2 normal(e.Y, -e.X); //normal.Normalize(); //// q = p1 + t * d //// dot(normal, q - v1) = 0 //// dot(normal, p1 - v1) + t * dot(normal, d) = 0 //float numerator = Utilities.Dot(normal, v1 - p1); //float denominator = Utilities.Dot(normal, d); //if (denominator == 0.0f) //{ // return false; //} //float t = numerator / denominator; //if (t < 0.0f || input.maxFraction < t) //{ // return false; //} //Vec2 q = p1 + t * d; //// q = v1 + s * r //// s = dot(q - v1, r) / dot(r, r) //Vec2 r = v2 - v1; //float rr = Utilities.Dot(r, r); //if (rr == 0.0f) //{ // return false; //} //float s = Utilities.Dot(q - v1, r) / rr; //if (s < 0.0f || 1.0f < s) //{ // return false; //} //output.fraction = t; //if (numerator > 0.0f) //{ // output.normal = -normal; //} //else //{ // output.normal = normal; //} //return true; }
float RayCastCallback(RayCastInput input, int proxyId) { throw new NotImplementedException(); //void* userData = broadPhase.GetUserData(proxyId); //FixtureProxy* proxy = (FixtureProxy*)userData; //Fixture* fixture = proxy.fixture; //int index = proxy.childIndex; //RayCastOutput output; //bool hit = fixture.RayCast(out output, input, index); //if (hit) //{ // float fraction = output.fraction; // Vec2 point = (1.0f - fraction) * input.p1 + fraction * input.p2; // return callback.ReportFixture(fixture, point, output.normal, fraction); //} //return input.maxFraction; }
/// Implement Shape. public override bool RayCast(out RayCastOutput output, RayCastInput input, Transform transform, int childIndex) { throw new NotImplementedException(); //// Put the ray into the polygon's frame of reference. //Vec2 p1 = Utilities.MulT(xf.q, input.p1 - xf.p); //Vec2 p2 = Utilities.MulT(xf.q, input.p2 - xf.p); //Vec2 d = p2 - p1; //float lower = 0.0f, upper = input.maxFraction; //int index = -1; //for (int i = 0; i < m_count; ++i) //{ // // p = p1 + a * d // // dot(normal, p - v) = 0 // // dot(normal, p1 - v) + a * dot(normal, d) = 0 // float numerator = Utilities.Dot(m_normals[i], m_vertices[i] - p1); // float denominator = Utilities.Dot(m_normals[i], d); // if (denominator == 0.0f) // { // if (numerator < 0.0f) // { // return false; // } // } // else // { // // Note: we want this predicate without division: // // lower < numerator / denominator, where denominator < 0 // // Since denominator < 0, we have to flip the inequality: // // lower < numerator / denominator <==> denominator * lower > numerator. // if (denominator < 0.0f && numerator < lower * denominator) // { // // Increase lower. // // The segment enters this half-space. // lower = numerator / denominator; // index = i; // } // else if (denominator > 0.0f && numerator < upper * denominator) // { // // Decrease upper. // // The segment exits this half-space. // upper = numerator / denominator; // } // } // // The use of epsilon here causes the assert on lower to trip // // in some cases. Apparently the use of epsilon was to make edge // // shapes work, but now those are handled separately. // //if (upper < lower - Single.Epsilon) // if (upper < lower) // { // return false; // } //} //Utilities.Assert(0.0f <= lower && lower <= input.maxFraction); //if (index >= 0) //{ // output.fraction = lower; // output.normal = Utilities.Mul(xf.q, m_normals[index]); // return true; //} //return false; }
/// Implement Shape. public override bool RayCast(out RayCastOutput output, RayCastInput input, Transform transform, int childIndex){ throw new NotImplementedException(); //Utilities.Assert(childIndex < m_count); //EdgeShape edgeShape; //int i1 = childIndex; //int i2 = childIndex + 1; //if (i2 == m_count) //{ // i2 = 0; //} //edgeShape.m_vertex1 = m_vertices[i1]; //edgeShape.m_vertex2 = m_vertices[i2]; //return edgeShape.RayCast(output, input, xf, 0); }
public float RayCastCallback(RayCastInput input, int proxyId) { Actor actor = (Actor)m_tree.GetUserData(proxyId); RayCastOutput output; 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; }
/// Cast a ray against a child shape. /// @param output the ray-cast results. /// @param input the ray-cast input parameters. /// @param transform the transform to be applied to the shape. /// @param childIndex the child shape index public abstract bool RayCast(out RayCastOutput output, RayCastInput input, Transform transform, int childIndex);
public bool RayCast(out RayCastOutput output, RayCastInput input) { float tmin = -Single.MaxValue; float tmax = Single.MaxValue; Vec2 p = input.p1; Vec2 d = input.p2 - input.p1; Vec2 absD = Utilities.Abs(d); output = new RayCastOutput(); Vec2 normal = new Vec2(); for (int i = 0; i < 2; ++i) { if (Math.Abs(i) < Single.Epsilon) { // Parallel. if (p[i] < lowerBound[i] || upperBound[i] < p[i]) { return false; } } else { float inv_d = 1.0f / d[i]; float t1 = (lowerBound[i] - p[i]) * inv_d; float t2 = (upperBound[i] - p[i]) * 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[i] = s; tmin = t1; } // Pull the max down tmax = Math.Min(tmax, t2); if (tmin > tmax) { return false; } } } // Does the ray start inside the box? // Does the ray intersect beyond the max fraction? if (tmin < 0.0f || input.maxFraction < tmin) { return false; } // Intersection. output.fraction = tmin; output.normal = normal; return true; }
/// Cast a ray against this shape. /// @param output the ray-cast results. /// @param input the ray-cast input parameters. public bool RayCast(out RayCastOutput output, RayCastInput input, int childIndex){ return m_shape.RayCast(out output, input, m_body.GetTransform(), childIndex); }
internal void RayCast(RayCastCallbackInternal callback, ref RayCastInput input) { _tree.RayCast(callback, ref input); }