Ejemplo n.º 1
0
 public void GetLocalVectorToOut(Vec2 worldVector, Vec2 result)
 {
     Rot.MulTrans(Xf.Q, worldVector, result);
 }
Ejemplo n.º 2
0
        public override bool Raycast(RayCastOutput output, RayCastInput input, Transform xf, int childIndex)
        {
            // Put the ray into the edge's frame of reference.
            Vec2 p1 = pool0.Set(input.P1).SubLocal(xf.P);

            Rot.MulTrans(xf.Q, p1, p1);
            Vec2 p2 = pool1.Set(input.P2).SubLocal(xf.P);

            Rot.MulTrans(xf.Q, p1, p1);
            Vec2 d = p2.SubLocal(p1); // we don't use p2 later

            Vec2 v1     = Vertex1;
            Vec2 v2     = Vertex2;
            Vec2 normal = pool2.Set(v2).SubLocal(v1);

            normal.Set(normal.Y, -normal.X);
            normal.Normalize();

            // q = p1 + t * d
            // dot(normal, q - v1) = 0
            // dot(normal, p1 - v1) + t * dot(normal, d) = 0
            pool3.Set(v1).SubLocal(p1);
            float numerator   = Vec2.Dot(normal, pool3);
            float denominator = Vec2.Dot(normal, d);

            if (denominator == 0.0f)
            {
                return(false);
            }

            float t = numerator / denominator;

            if (t < 0.0f || 1.0f < t)
            {
                return(false);
            }

            Vec2 q = pool3;
            Vec2 r = pool4;

            // Vec2 q = p1 + t * d;
            q.Set(d).MulLocal(t).AddLocal(p1);

            // q = v1 + s * r
            // s = dot(q - v1, r) / dot(r, r)
            // Vec2 r = v2 - v1;
            r.Set(v2).SubLocal(v1);
            float rr = Vec2.Dot(r, r);

            if (rr == 0.0f)
            {
                return(false);
            }

            pool5.Set(q).SubLocal(v1);
            float s = Vec2.Dot(pool5, r) / rr;

            if (s < 0.0f || 1.0f < s)
            {
                return(false);
            }

            output.Fraction = t;
            if (numerator > 0.0f)
            {
                // argOutput.normal = -normal;
                output.Normal.Set(normal).NegateLocal();
            }
            else
            {
                // output.normal = normal;
                output.Normal.Set(normal);
            }
            return(true);
        }
Ejemplo n.º 3
0
        public override bool Raycast(RayCastOutput output, RayCastInput input, Transform xf, int childIndex)
        {
            Vec2 p1   = pool1;
            Vec2 p2   = pool2;
            Vec2 d    = pool3;
            Vec2 temp = pool4;

            p1.Set(input.P1).SubLocal(xf.P);
            Rot.MulTrans(xf.Q, p1, p1);
            p2.Set(input.P2).SubLocal(xf.P);
            Rot.MulTrans(xf.Q, p2, p2);
            d.Set(p2).SubLocal(p1);

            // if (count == 2) {

            // } else {

            float lower = 0, upper = input.MaxFraction;

            int index = -1;

            for (int i = 0; i < VertexCount; ++i)
            {
                // p = p1 + a * d
                // dot(normal, p - v) = 0
                // dot(normal, p1 - v) + a * dot(normal, d) = 0
                temp.Set(Vertices[i]).SubLocal(p1);
                float numerator   = Vec2.Dot(Normals[i], temp);
                float denominator = Vec2.Dot(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;
                    }
                }

                if (upper < lower)
                {
                    return(false);
                }
            }

            Debug.Assert(0.0f <= lower && lower <= input.MaxFraction);

            if (index >= 0)
            {
                output.Fraction = lower;
                Rot.MulToOutUnsafe(xf.Q, Normals[index], output.Normal);
                // normal = Mul(xf.R, m_normals[index]);
                return(true);
            }
            return(false);
        }