示例#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);
	}
示例#3
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 FaceRaycast(Ray InWorldRay, pb_Object mesh, out pb_RaycastHit hit, float distance, Culling cullingMode)
        {
            /**
             * Transform ray into model space
             */

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

            Vector3[] vertices = mesh.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 < mesh.faces.Length; ++CurFace)
            {
                int[] Indices = mesh.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);
        }
示例#4
0
		/**
		 * Find a triangle intersected by InRay on InMesh.  InRay is in world space.
		 * Returns the index in mesh.faces of the hit face, or -1.  Optionally can ignore
		 * backfaces.
		 */
		public static bool FaceRaycast(Ray InWorldRay, pb_Object mesh, out pb_RaycastHit hit)
		{
			return FaceRaycast(InWorldRay, mesh, out hit, Mathf.Infinity, Culling.Front);
		}
示例#5
0
 /**
  * Find a triangle intersected by InRay on InMesh.  InRay is in world space.
  * Returns the index in mesh.faces of the hit face, or -1.  Optionally can ignore
  * backfaces.
  */
 public static bool FaceRaycast(Ray InWorldRay, pb_Object mesh, out pb_RaycastHit hit)
 {
     return(FaceRaycast(InWorldRay, mesh, out hit, Mathf.Infinity, Culling.Front));
 }