Beispiel #1
0
        // ray intersect face and return intersection distance, point and normal
        public override bool PointIntersect(
            Vector3 rayOrigin,
            Vector3 rayDirection,
            Vector3[] vertices,
            out float intersectDistance,
            out Vector3 intersectPosition,
            out Vector3 intersectNormal)
        {
            intersectDistance = 0.0f;
            intersectPosition = rayOrigin;
            intersectNormal   = Vector3.Zero;

            Vector3 v1 = vertices[indices[0]];
            Vector3 v2 = vertices[indices[1]];
            Vector3 v3 = vertices[indices[2]];

            Vector3 uvt;

            if (CollisionFace.RayTriangleIntersect(rayOrigin, rayDirection,
                                                   v1, v2, v3, out uvt.Z, out uvt.X, out uvt.Y))
            {
                intersectDistance = uvt.Z;
                intersectPosition = (1.0f - uvt.X - uvt.Y) * v1 +
                                    uvt.X * v2 + uvt.Y * v3;
                intersectNormal = Vector3.Normalize(Vector3.Cross(v3 - v1, v2 - v1));
                return(true);
            }
            return(false);
        }
Beispiel #2
0
        // box intersect face and return intersection distance, point and normal
        public override bool BoxIntersect(
            CollisionBox rayBox,
            Vector3 rayOrigin,
            Vector3 rayDirection,
            Vector3[] vertices,
            out float intersectDistance,
            out Vector3 intersectPosition,
            out Vector3 intersectNormal)
        {
            intersectDistance = float.MaxValue;
            intersectPosition = rayOrigin;
            intersectNormal   = Vector3.Zero;

            bool    intersected = false;
            Vector3 p1, p2, p3, p4;
            uint    i, j;

            CollisionBox worldBox = new CollisionBox(rayBox.min + rayOrigin,
                                                     rayBox.max + rayOrigin);

            Vector3[] boxVerts = worldBox.GetVertices();
            Vector3[] boxEdges = worldBox.GetEdges();

            float   distance;
            Vector3 position;

            // intersect box edges to face edges
            for (i = 0; i < 12; i++)
            {
                // cull edges with normal more than 135 degree from moving direction
                float dot = Vector3.Dot(CollisionBox.edgeNormals[i], rayDirection);
                if (dot < -0.70710678)
                {
                    continue;
                }

                p1 = boxEdges[i * 2];
                p2 = boxEdges[i * 2 + 1];
                p4 = vertices[indices[0]];
                for (j = 0; j < indices.Length; j++)
                {
                    p3 = p4;
                    p4 = vertices[indices[(j + 1) % indices.Length]];

                    if (CollisionFace.EdgeIntersect(p1, p2, rayDirection,
                                                    p3, p4, out distance, out position))
                    {
                        if (distance < intersectDistance)
                        {
                            intersectDistance = distance;
                            intersectPosition = position;
                            intersectNormal   = Vector3.Cross(p2 - p1, p3 - p4);
                            intersectNormal   = Vector3.Normalize(intersectNormal);
                            if (Vector3.Dot(rayDirection, intersectNormal) > 0)
                            {
                                intersectNormal = Vector3.Negate(intersectNormal);
                            }
                            intersected = true;
                        }
                    }
                }
            }

            // intersect from face vertices to box
            for (i = 0; i < 3; i++)
            {
                float tnear, tfar;
                p1 = vertices[indices[i]];
                int box_face_id = worldBox.RayIntersect(p1, -rayDirection,
                                                        out tnear, out tfar);
                if (box_face_id > -1)
                {
                    if (tnear < intersectDistance)
                    {
                        intersectDistance = tnear;
                        intersectPosition = p1;
                        intersectNormal   = -CollisionBox.faceNormals[box_face_id];
                        intersected       = true;
                    }
                }
            }

            // intersect from box vertices to face polygon
            Vector3 v1 = vertices[indices[0]];
            Vector3 v2 = vertices[indices[1]];
            Vector3 v3 = vertices[indices[2]];
            Vector3 uvt;

            for (i = 0; i < 8; i++)
            {
                // cull vertices with normal more than 135 degree from moving direction
                float dot = Vector3.Dot(CollisionBox.vertexNormals[i], rayDirection);
                if (dot < -0.70710678)
                {
                    continue;
                }

                if (CollisionFace.RayTriangleIntersect(boxVerts[i], rayDirection,
                                                       v1, v2, v3, out uvt.Z, out uvt.X, out uvt.Y))
                {
                    if (uvt.Z < intersectDistance)
                    {
                        intersectDistance = uvt.Z;
                        intersectPosition = (1.0f - uvt.X - uvt.Y) *
                                            v1 + uvt.X * v2 + uvt.Y * v3;
                        intersectNormal = Vector3.Cross(v3 - v1, v2 - v1);
                        intersectNormal = Vector3.Normalize(intersectNormal);
                        intersected     = true;
                    }
                }
            }

            return(intersected);
        }