コード例 #1
0
    /**
     * Find the nearest triangle intersected by InWorldRay on this pb_Object.  InWorldRay is in world space.
     * @hit contains information about the hit point.  @distance limits how far from @InWorldRay.origin the hit
     * point may be.  @cullingMode determines what face orientations are tested (Culling.Front only tests front
     * faces, Culling.Back only tests back faces, and Culling.FrontBack tests both).
     */
    public static bool MeshRaycast(Ray InWorldRay, pb_Object pb, out pb_RaycastHit hit, float distance, Culling cullingMode)
    {
        /**
         * Transform ray into model space
         */

        InWorldRay.origin   -= pb.transform.position;                      // Why doesn't worldToLocalMatrix apply translation?
        InWorldRay.origin    = pb.transform.worldToLocalMatrix * InWorldRay.origin;
        InWorldRay.direction = pb.transform.worldToLocalMatrix * InWorldRay.direction;

        Vector3[] vertices = pb.vertices;

        float   dist  = 0f;
        Vector3 point = Vector3.zero;

        float   OutHitPoint = Mathf.Infinity;
        float   dot;       // vars used in loop
        Vector3 nrm;       // vars used in loop
        int     OutHitFace = -1;
        Vector3 OutNrm     = Vector3.zero;

        /**
         * Iterate faces, testing for nearest hit to ray origin.  Optionally ignores backfaces.
         */
        for (int CurFace = 0; CurFace < pb.faces.Length; ++CurFace)
        {
            int[] Indices = pb.faces[CurFace].indices;

            for (int CurTriangle = 0; CurTriangle < Indices.Length; CurTriangle += 3)
            {
                Vector3 a = vertices[Indices[CurTriangle + 0]];
                Vector3 b = vertices[Indices[CurTriangle + 1]];
                Vector3 c = vertices[Indices[CurTriangle + 2]];

                nrm = Vector3.Cross(b - a, c - a);
                dot = Vector3.Dot(InWorldRay.direction, nrm);

                bool ignore = false;

                switch (cullingMode)
                {
                case Culling.Front:
                    if (dot > 0f)
                    {
                        ignore = true;
                    }
                    break;

                case Culling.Back:
                    if (dot < 0f)
                    {
                        ignore = true;
                    }
                    break;
                }

                if (!ignore && pb_Math.RayIntersectsTriangle(InWorldRay, a, b, c, out dist, out point))
                {
                    if (dist > OutHitPoint || dist > distance)
                    {
                        continue;
                    }

                    OutNrm      = nrm;
                    OutHitFace  = CurFace;
                    OutHitPoint = dist;

                    continue;
                }
            }
        }

        hit = new pb_RaycastHit(OutHitPoint,
                                InWorldRay.GetPoint(OutHitPoint),
                                OutNrm,
                                OutHitFace);

        return(OutHitFace > -1);
    }
コード例 #2
0
 /**
  * Find a triangle intersected by InRay on InMesh.  InRay is in world space.
  */
 public static bool MeshRaycast(Ray InWorldRay, pb_Object pb, out pb_RaycastHit hit)
 {
     return(MeshRaycast(InWorldRay, pb, out hit, Mathf.Infinity, Culling.Front));
 }