示例#1
0
        private void DrawCapsule(CapsuleCache c0, Pen p)
        {
            var n    = c0.normal;
            var r    = c0.capsule.radius;
            var twor = 2 * r;
            var x    = r * n;
            var p0   = c0.capsule.p0;
            var p1   = c0.capsule.p1;

            DrawLine(p, p0 + x, p1 + x);
            DrawLine(p, p0 - x, p1 - x);
            float angle = Mathf.RAD_TO_DEG * (float)Math.Atan2(n.y, n.x);

            _graphics.DrawArc(p, p0.x - r, p0.y - r, twor, twor, angle, 180);
            _graphics.DrawArc(p, p1.x - r, p1.y - r, twor, twor, angle + 180, 180);
        }
示例#2
0
        RasterizationMesh RasterizeCapsuleCollider(float radius, float height, Bounds bounds, Matrix4x4 localToWorldMatrix)
        {
            // Calculate the number of rows to use
            // grows as sqrt(x) to the radius of the sphere/capsule which I have found works quite well
            int rows = Mathf.Max(4, Mathf.RoundToInt(colliderRasterizeDetail * Mathf.Sqrt(localToWorldMatrix.MultiplyVector(Vector3.one).magnitude)));

            if (rows > 100)
            {
                Debug.LogWarning("Very large detail for some collider meshes. Consider decreasing Collider Rasterize Detail (RecastGraph)");
            }

            int cols = rows;

            Vector3[] verts;
            int[]     trisArr;

            // Check if we have already calculated a similar capsule
            CapsuleCache cached = null;

            for (int i = 0; i < capsuleCache.Count; i++)
            {
                CapsuleCache c = capsuleCache[i];
                if (c.rows == rows && Mathf.Approximately(c.height, height))
                {
                    cached = c;
                }
            }

            if (cached == null)
            {
                // Generate a sphere/capsule mesh

                verts = new Vector3[(rows) * cols + 2];

                var tris = new List <int>();
                verts[verts.Length - 1] = Vector3.up;

                for (int r = 0; r < rows; r++)
                {
                    for (int c = 0; c < cols; c++)
                    {
                        verts[c + r * cols] = new Vector3(Mathf.Cos(c * Mathf.PI * 2 / cols) * Mathf.Sin((r * Mathf.PI / (rows - 1))), Mathf.Cos((r * Mathf.PI / (rows - 1))) + (r < rows / 2 ? height : -height), Mathf.Sin(c * Mathf.PI * 2 / cols) * Mathf.Sin((r * Mathf.PI / (rows - 1))));
                    }
                }

                verts[verts.Length - 2] = Vector3.down;

                for (int i = 0, j = cols - 1; i < cols; j = i++)
                {
                    tris.Add(verts.Length - 1);
                    tris.Add(0 * cols + j);
                    tris.Add(0 * cols + i);
                }

                for (int r = 1; r < rows; r++)
                {
                    for (int i = 0, j = cols - 1; i < cols; j = i++)
                    {
                        tris.Add(r * cols + i);
                        tris.Add(r * cols + j);
                        tris.Add((r - 1) * cols + i);

                        tris.Add((r - 1) * cols + j);
                        tris.Add((r - 1) * cols + i);
                        tris.Add(r * cols + j);
                    }
                }

                for (int i = 0, j = cols - 1; i < cols; j = i++)
                {
                    tris.Add(verts.Length - 2);
                    tris.Add((rows - 1) * cols + j);
                    tris.Add((rows - 1) * cols + i);
                }

                // Add calculated mesh to the cache
                cached        = new CapsuleCache();
                cached.rows   = rows;
                cached.height = height;
                cached.verts  = verts;
                cached.tris   = tris.ToArray();
                capsuleCache.Add(cached);
            }

            // Read from cache
            verts   = cached.verts;
            trisArr = cached.tris;

            return(new RasterizationMesh(verts, trisArr, bounds, localToWorldMatrix));
        }
示例#3
0
		/** Rasterizes a collider to a mesh assuming it's vertices should be multiplied with the matrix.
		 * Note that the bounds of the returned ExtraMesh is based on collider.bounds. So you might want to
		 * call myExtraMesh.RecalculateBounds on the returned mesh to recalculate it if the collider.bounds would
		 * not give the correct value.
		  * */
		ExtraMesh RasterizeCollider (Collider col, Matrix4x4 localToWorldMatrix) {
			if (col is BoxCollider) {
				BoxCollider collider = col as BoxCollider;
				
				Matrix4x4 matrix = Matrix4x4.TRS (collider.center, Quaternion.identity, collider.size*0.5f);
				matrix = localToWorldMatrix * matrix;
				
				Bounds b = collider.bounds;
				
				ExtraMesh m = new ExtraMesh(BoxColliderVerts,BoxColliderTris, b, matrix);
				
#if ASTARDEBUG
				
				Vector3[] verts = BoxColliderVerts;
				int[] tris = BoxColliderTris;
				
				for (int i=0;i<tris.Length;i+=3) {
					Debug.DrawLine (matrix.MultiplyPoint3x4(verts[tris[i]]),matrix.MultiplyPoint3x4(verts[tris[i+1]]), Color.yellow);
					Debug.DrawLine (matrix.MultiplyPoint3x4(verts[tris[i+2]]),matrix.MultiplyPoint3x4(verts[tris[i+1]]), Color.yellow);
					Debug.DrawLine (matrix.MultiplyPoint3x4(verts[tris[i]]),matrix.MultiplyPoint3x4(verts[tris[i+2]]), Color.yellow);
					
					//Normal debug
					/*Vector3 va = matrix.MultiplyPoint3x4(verts[tris[i]]);
					Vector3 vb = matrix.MultiplyPoint3x4(verts[tris[i+1]]);
					Vector3 vc = matrix.MultiplyPoint3x4(verts[tris[i+2]]);
					
					Debug.DrawRay ((va+vb+vc)/3, Vector3.Cross(vb-va,vc-va).normalized,Color.blue);*/
				}
#endif
				return m;
			} else if (col is SphereCollider || col is CapsuleCollider) {
				
				SphereCollider scollider = col as SphereCollider;
				CapsuleCollider ccollider = col as CapsuleCollider;
				
				float radius = (scollider != null ? scollider.radius : ccollider.radius);
				float height = scollider != null ? 0 : (ccollider.height*0.5f/radius) - 1;
				
				Matrix4x4 matrix = Matrix4x4.TRS (scollider != null ? scollider.center : ccollider.center, Quaternion.identity, Vector3.one*radius);
				matrix = localToWorldMatrix * matrix;
				
				//Calculate the number of rows to use
				//grows as sqrt(x) to the radius of the sphere/capsule which I have found works quite good
				int rows = Mathf.Max (4,Mathf.RoundToInt(colliderRasterizeDetail*Mathf.Sqrt(matrix.MultiplyVector(Vector3.one).magnitude)));
				
				if (rows > 100) {
					Debug.LogWarning ("Very large detail for some collider meshes. Consider decreasing Collider Rasterize Detail (RecastGraph)");
				}
				
				int cols = rows;
				
				Vector3[] verts;
				int[] trisArr;
				
				
				//Check if we have already calculated a similar capsule
				CapsuleCache cached = null;
				for (int i=0;i<capsuleCache.Count;i++) {
					CapsuleCache c = capsuleCache[i];
					if (c.rows == rows && Mathf.Approximately (c.height, height)) {
						cached = c;
					}
				}
				
				if (cached == null) {
					//Generate a sphere/capsule mesh
					
					verts = new Vector3[(rows)*cols + 2];
					
					List<int> tris = new List<int>();
					verts[verts.Length-1] = Vector3.up;
					
					for (int r=0;r<rows;r++) {
						for (int c=0;c<cols;c++) {
							verts[c + r*cols] = new Vector3 (Mathf.Cos (c*Mathf.PI*2/cols)*Mathf.Sin ((r*Mathf.PI/(rows-1))), Mathf.Cos ((r*Mathf.PI/(rows-1))) + (r < rows/2 ? height : -height) , Mathf.Sin (c*Mathf.PI*2/cols)*Mathf.Sin ((r*Mathf.PI/(rows-1))));
						}
					}
					
					verts[verts.Length-2] = Vector3.down;
					
					for (int i=0, j = cols-1;i<cols; j = i++) {
						tris.Add (verts.Length-1);
						tris.Add (0*cols + j);
						tris.Add (0*cols + i);
					}
					
					for (int r=1;r<rows;r++) {
						for (int i=0, j = cols-1;i<cols; j = i++) {
							tris.Add (r*cols + i);
							tris.Add (r*cols + j);
							tris.Add ((r-1)*cols + i);
							
							tris.Add ((r-1)*cols + j);
							tris.Add ((r-1)*cols + i);
							tris.Add (r*cols + j);
						}
					}
					
					for (int i=0, j = cols-1;i<cols; j = i++) {
						tris.Add (verts.Length-2);
						tris.Add ((rows-1)*cols + j);
						tris.Add ((rows-1)*cols + i);
					}
					
					//Add calculated mesh to the cache
					cached = new CapsuleCache ();
					cached.rows = rows;
					cached.height = height;
					cached.verts = verts;
					cached.tris = tris.ToArray();
					capsuleCache.Add (cached);
				}
				
				//Read from cache
				verts = cached.verts;
				trisArr = cached.tris;
				
				Bounds b = col.bounds;
				
				ExtraMesh m = new ExtraMesh(verts,trisArr, b, matrix);
				
#if ASTARDEBUG
				for (int i=0;i<trisArr.Length;i+=3) {
					Debug.DrawLine (matrix.MultiplyPoint3x4(verts[trisArr[i]]),matrix.MultiplyPoint3x4(verts[trisArr[i+1]]), Color.yellow);
					Debug.DrawLine (matrix.MultiplyPoint3x4(verts[trisArr[i+2]]),matrix.MultiplyPoint3x4(verts[trisArr[i+1]]), Color.yellow);
					Debug.DrawLine (matrix.MultiplyPoint3x4(verts[trisArr[i]]),matrix.MultiplyPoint3x4(verts[trisArr[i+2]]), Color.yellow);
					
					//Normal debug
					/*Vector3 va = matrix.MultiplyPoint3x4(verts[trisArr[i]]);
					Vector3 vb = matrix.MultiplyPoint3x4(verts[trisArr[i+1]]);
					Vector3 vc = matrix.MultiplyPoint3x4(verts[trisArr[i+2]]);
					
					Debug.DrawRay ((va+vb+vc)/3, Vector3.Cross(vb-va,vc-va).normalized,Color.blue);*/
				}
#endif	
				return m;
			} else if (col is MeshCollider) {
				MeshCollider collider = col as MeshCollider;
				
				if ( collider.sharedMesh != null ) {
					ExtraMesh m = new ExtraMesh(collider.sharedMesh.vertices, collider.sharedMesh.triangles, collider.bounds, localToWorldMatrix);
					return m;
				}
			}
			
			return new ExtraMesh();
		}
        private RasterizationMesh RasterizeCapsuleCollider(float radius, float height, Bounds bounds, Matrix4x4 localToWorldMatrix)
        {
            Vector3[] verts;
            int       num = Mathf.Max(4, Mathf.RoundToInt(this.colliderRasterizeDetail * Mathf.Sqrt(localToWorldMatrix.MultiplyVector(Vector3.one).magnitude)));

            if (num > 100)
            {
                Debug.LogWarning("Very large detail for some collider meshes. Consider decreasing Collider Rasterize Detail (RecastGraph)");
            }
            int          num2 = num;
            CapsuleCache item = null;

            for (int i = 0; i < this.capsuleCache.Count; i++)
            {
                CapsuleCache cache2 = this.capsuleCache[i];
                if ((cache2.rows == num) && Mathf.Approximately(cache2.height, height))
                {
                    item = cache2;
                }
            }
            if (item == null)
            {
                verts = new Vector3[(num * num2) + 2];
                List <int> list = new List <int>();
                verts[verts.Length - 1] = Vector3.up;
                for (int j = 0; j < num; j++)
                {
                    for (int num5 = 0; num5 < num2; num5++)
                    {
                        verts[num5 + (j * num2)] = new Vector3(Mathf.Cos(((num5 * 3.141593f) * 2f) / ((float)num2)) * Mathf.Sin((j * 3.141593f) / ((float)(num - 1))), Mathf.Cos((j * 3.141593f) / ((float)(num - 1))) + ((j >= (num / 2)) ? -height : height), Mathf.Sin(((num5 * 3.141593f) * 2f) / ((float)num2)) * Mathf.Sin((j * 3.141593f) / ((float)(num - 1))));
                    }
                }
                verts[verts.Length - 2] = Vector3.down;
                int num6 = 0;
                for (int k = num2 - 1; num6 < num2; k = num6++)
                {
                    list.Add(verts.Length - 1);
                    list.Add((0 * num2) + k);
                    list.Add((0 * num2) + num6);
                }
                for (int m = 1; m < num; m++)
                {
                    int num9 = 0;
                    for (int num10 = num2 - 1; num9 < num2; num10 = num9++)
                    {
                        list.Add((m * num2) + num9);
                        list.Add((m * num2) + num10);
                        list.Add(((m - 1) * num2) + num9);
                        list.Add(((m - 1) * num2) + num10);
                        list.Add(((m - 1) * num2) + num9);
                        list.Add((m * num2) + num10);
                    }
                }
                int num11 = 0;
                for (int n = num2 - 1; num11 < num2; n = num11++)
                {
                    list.Add(verts.Length - 2);
                    list.Add(((num - 1) * num2) + n);
                    list.Add(((num - 1) * num2) + num11);
                }
                item        = new CapsuleCache();
                item.rows   = num;
                item.height = height;
                item.verts  = verts;
                item.tris   = list.ToArray();
                this.capsuleCache.Add(item);
            }
            verts = item.verts;
            return(new RasterizationMesh(verts, item.tris, bounds, localToWorldMatrix));
        }