コード例 #1
0
ファイル: RecastMeshGatherer.cs プロジェクト: K07H/The-Forest
        private RasterizationMesh RasterizeCollider(Collider col, Matrix4x4 localToWorldMatrix)
        {
            RasterizationMesh result = null;

            if (col is BoxCollider)
            {
                result = this.RasterizeBoxCollider(col as BoxCollider, localToWorldMatrix);
            }
            else if (col is SphereCollider || col is CapsuleCollider)
            {
                SphereCollider  sphereCollider  = col as SphereCollider;
                CapsuleCollider capsuleCollider = col as CapsuleCollider;
                float           num             = (!(sphereCollider != null)) ? capsuleCollider.radius : sphereCollider.radius;
                float           height          = (!(sphereCollider != null)) ? (capsuleCollider.height * 0.5f / num - 1f) : 0f;
                Matrix4x4       matrix4x        = Matrix4x4.TRS((!(sphereCollider != null)) ? capsuleCollider.center : sphereCollider.center, Quaternion.identity, Vector3.one * num);
                matrix4x = localToWorldMatrix * matrix4x;
                result   = this.RasterizeCapsuleCollider(num, height, col.bounds, matrix4x);
            }
            else if (col is MeshCollider)
            {
                MeshCollider meshCollider = col as MeshCollider;
                if (meshCollider.sharedMesh != null && meshCollider.sharedMesh.isReadable)
                {
                    result = new RasterizationMesh(meshCollider.sharedMesh.vertices, meshCollider.sharedMesh.triangles, meshCollider.bounds, localToWorldMatrix);
                }
            }
            return(result);
        }
コード例 #2
0
        // Token: 0x060027D2 RID: 10194 RVA: 0x001B4B24 File Offset: 0x001B2D24
        private void CollectTreeMeshes(Terrain terrain, List <RasterizationMesh> result)
        {
            TerrainData terrainData = terrain.terrainData;

            for (int i = 0; i < terrainData.treeInstances.Length; i++)
            {
                TreeInstance  treeInstance  = terrainData.treeInstances[i];
                TreePrototype treePrototype = terrainData.treePrototypes[treeInstance.prototypeIndex];
                if (!(treePrototype.prefab == null))
                {
                    Collider component = treePrototype.prefab.GetComponent <Collider>();
                    Vector3  pos       = terrain.transform.position + Vector3.Scale(treeInstance.position, terrainData.size);
                    if (component == null)
                    {
                        Bounds            bounds = new Bounds(terrain.transform.position + Vector3.Scale(treeInstance.position, terrainData.size), new Vector3(treeInstance.widthScale, treeInstance.heightScale, treeInstance.widthScale));
                        Matrix4x4         matrix = Matrix4x4.TRS(pos, Quaternion.identity, new Vector3(treeInstance.widthScale, treeInstance.heightScale, treeInstance.widthScale) * 0.5f);
                        RasterizationMesh item   = new RasterizationMesh(RecastMeshGatherer.BoxColliderVerts, RecastMeshGatherer.BoxColliderTris, bounds, matrix);
                        result.Add(item);
                    }
                    else
                    {
                        Vector3           s = new Vector3(treeInstance.widthScale, treeInstance.heightScale, treeInstance.widthScale);
                        RasterizationMesh rasterizationMesh = this.RasterizeCollider(component, Matrix4x4.TRS(pos, Quaternion.identity, s));
                        if (rasterizationMesh != null)
                        {
                            rasterizationMesh.RecalculateBounds();
                            result.Add(rasterizationMesh);
                        }
                    }
                }
            }
        }
コード例 #3
0
        // Token: 0x0600262F RID: 9775 RVA: 0x001A8028 File Offset: 0x001A6228
        private List <RasterizationMesh>[] PutMeshesIntoTileBuckets(List <RasterizationMesh> meshes)
        {
            List <RasterizationMesh>[] array = new List <RasterizationMesh> [this.tiles.Length];
            Vector3 amount = new Vector3(1f, 0f, 1f) * this.TileBorderSizeInWorldUnits * 2f;

            for (int i = 0; i < array.Length; i++)
            {
                array[i] = ListPool <RasterizationMesh> .Claim();
            }
            for (int j = 0; j < meshes.Count; j++)
            {
                RasterizationMesh rasterizationMesh = meshes[j];
                Bounds            bounds            = rasterizationMesh.bounds;
                bounds.Expand(amount);
                IntRect touchingTiles = base.GetTouchingTiles(bounds);
                for (int k = touchingTiles.ymin; k <= touchingTiles.ymax; k++)
                {
                    for (int l = touchingTiles.xmin; l <= touchingTiles.xmax; l++)
                    {
                        array[l + k * this.tileXCount].Add(rasterizationMesh);
                    }
                }
            }
            return(array);
        }
コード例 #4
0
        // Token: 0x060027D5 RID: 10197 RVA: 0x001B4D9C File Offset: 0x001B2F9C
        private RasterizationMesh RasterizeCollider(Collider col, Matrix4x4 localToWorldMatrix)
        {
            RasterizationMesh result = null;

            if (col is BoxCollider)
            {
                result = this.RasterizeBoxCollider(col as BoxCollider, localToWorldMatrix);
            }
            else if (col is SphereCollider || col is CapsuleCollider)
            {
                SphereCollider  sphereCollider  = col as SphereCollider;
                CapsuleCollider capsuleCollider = col as CapsuleCollider;
                float           num             = (sphereCollider != null) ? sphereCollider.radius : capsuleCollider.radius;
                float           height          = (sphereCollider != null) ? 0f : (capsuleCollider.height * 0.5f / num - 1f);
                Quaternion      q = Quaternion.identity;
                if (capsuleCollider != null)
                {
                    q = Quaternion.Euler((float)((capsuleCollider.direction == 2) ? 90 : 0), 0f, (float)((capsuleCollider.direction == 0) ? 90 : 0));
                }
                Matrix4x4 matrix4x = Matrix4x4.TRS((sphereCollider != null) ? sphereCollider.center : capsuleCollider.center, q, Vector3.one * num);
                matrix4x = localToWorldMatrix * matrix4x;
                result   = this.RasterizeCapsuleCollider(num, height, col.bounds, matrix4x);
            }
            else if (col is MeshCollider)
            {
                MeshCollider meshCollider = col as MeshCollider;
                if (meshCollider.sharedMesh != null)
                {
                    result = new RasterizationMesh(meshCollider.sharedMesh.vertices, meshCollider.sharedMesh.triangles, meshCollider.bounds, localToWorldMatrix);
                }
            }
            return(result);
        }
コード例 #5
0
        /** Generates a terrain chunk mesh */
        RasterizationMesh GenerateHeightmapChunk(float[, ] heights, Vector3 sampleSize, Vector3 offset, int x0, int z0, int width, int depth, int stride)
        {
            // Downsample to a smaller mesh (full resolution will take a long time to rasterize)
            // Round up the width to the nearest multiple of terrainSampleSize and then add 1
            // (off by one because there are vertices at the edge of the mesh)
            int resultWidth = CeilDivision(width, terrainSampleSize) + 1;
            int resultDepth = CeilDivision(depth, terrainSampleSize) + 1;

            var heightmapWidth = heights.GetLength(0);
            var heightmapDepth = heights.GetLength(1);

            // Create a mesh from the heightmap
            var terrainVertices = new Vector3[resultWidth * resultDepth];

            // Create lots of vertices
            for (int z = 0; z < resultDepth; z++)
            {
                for (int x = 0; x < resultWidth; x++)
                {
                    int sampleX = Math.Min(x0 + x * stride, heightmapWidth - 1);
                    int sampleZ = Math.Min(z0 + z * stride, heightmapDepth - 1);

                    terrainVertices[z * resultWidth + x] = new Vector3(sampleZ * sampleSize.x, heights[sampleX, sampleZ] * sampleSize.y, sampleX * sampleSize.z) + offset;
                }
            }

            // Create the mesh by creating triangles in a grid like pattern
            var tris          = new int[(resultWidth - 1) * (resultDepth - 1) * 2 * 3];
            int triangleIndex = 0;

            for (int z = 0; z < resultDepth - 1; z++)
            {
                for (int x = 0; x < resultWidth - 1; x++)
                {
                    tris[triangleIndex]     = z * resultWidth + x;
                    tris[triangleIndex + 1] = z * resultWidth + x + 1;
                    tris[triangleIndex + 2] = (z + 1) * resultWidth + x + 1;
                    triangleIndex          += 3;
                    tris[triangleIndex]     = z * resultWidth + x;
                    tris[triangleIndex + 1] = (z + 1) * resultWidth + x + 1;
                    tris[triangleIndex + 2] = (z + 1) * resultWidth + x;
                    triangleIndex          += 3;
                }
            }

#if ASTARDEBUG
            var color = AstarMath.IntToColor(x0 + 7 * z0, 0.7f);
            for (int i = 0; i < tris.Length; i += 3)
            {
                Debug.DrawLine(terrainVertices[tris[i]], terrainVertices[tris[i + 1]], color, 40);
                Debug.DrawLine(terrainVertices[tris[i + 1]], terrainVertices[tris[i + 2]], color, 40);
                Debug.DrawLine(terrainVertices[tris[i + 2]], terrainVertices[tris[i]], color, 40);
            }
#endif

            var mesh = new RasterizationMesh(terrainVertices, tris, new Bounds());
            // Could probably calculate these bounds in a faster way
            mesh.RecalculateBounds();
            return(mesh);
        }
コード例 #6
0
        public void CollectColliderMeshes(List <RasterizationMesh> result)
        {
            var colls = MonoBehaviour.FindObjectsOfType <Collider>();

            if (tagMask.Count > 0 || mask != 0)
            {
                for (int i = 0; i < colls.Length; i++)
                {
                    Collider col = colls[i];

                    if ((((mask >> col.gameObject.layer) & 1) != 0 || tagMask.Contains(col.tag)) && col.enabled && !col.isTrigger && col.bounds.Intersects(bounds) && col.GetComponent <RecastMeshObj>() == null)
                    {
                        RasterizationMesh emesh = RasterizeCollider(col);
                        //Make sure a valid ExtraMesh was returned
                        if (emesh != null)
                        {
                            result.Add(emesh);
                        }
                    }
                }
            }

            // Clear cache to avoid memory leak
            capsuleCache.Clear();
        }
コード例 #7
0
        public void CollectColliderMeshes(List <RasterizationMesh> result)
        {
            /// <summary>TODO: Use Physics.OverlapBox on newer Unity versions</summary>
            // Find all colliders that could possibly be inside the bounds
            var colls = Physics.OverlapSphere(bounds.center, bounds.size.magnitude, -1, QueryTriggerInteraction.Ignore);

            if (tagMask.Count > 0 || mask != 0)
            {
                for (int i = 0; i < colls.Length; i++)
                {
                    Collider collider = colls[i];

                    if ((((mask >> collider.gameObject.layer) & 1) != 0 || tagMask.Contains(collider.tag)) && collider.enabled && !collider.isTrigger && collider.bounds.Intersects(bounds) && collider.GetComponent <RecastMeshObj>() == null)
                    {
                        RasterizationMesh emesh = RasterizeCollider(collider);
                        //Make sure a valid RasterizationMesh was returned
                        if (emesh != null)
                        {
                            result.Add(emesh);
                        }
                    }
                }
            }

            // Clear cache to avoid memory leak
            capsuleCache.Clear();
        }
コード例 #8
0
        private RasterizationMesh RasterizeCollider(Collider col, Matrix4x4 localToWorldMatrix)
        {
            RasterizationMesh mesh = null;

            if (col is BoxCollider)
            {
                return(this.RasterizeBoxCollider(col as BoxCollider, localToWorldMatrix));
            }
            if ((col is SphereCollider) || (col is CapsuleCollider))
            {
                SphereCollider  collider  = col as SphereCollider;
                CapsuleCollider collider2 = col as CapsuleCollider;
                float           radius    = (collider == null) ? collider2.radius : collider.radius;
                float           height    = (collider == null) ? (((collider2.height * 0.5f) / radius) - 1f) : 0f;
                Matrix4x4       matrixx   = Matrix4x4.TRS((collider == null) ? collider2.center : collider.center, Quaternion.identity, (Vector3)(Vector3.one * radius));
                matrixx = localToWorldMatrix * matrixx;
                return(this.RasterizeCapsuleCollider(radius, height, col.bounds, matrixx));
            }
            if (col is MeshCollider)
            {
                MeshCollider collider3 = col as MeshCollider;
                if (collider3.sharedMesh != null)
                {
                    mesh = new RasterizationMesh(collider3.sharedMesh.vertices, collider3.sharedMesh.triangles, collider3.bounds, localToWorldMatrix);
                }
            }
            return(mesh);
        }
コード例 #9
0
        private void GenerateTerrainChunks(Terrain terrain, Bounds bounds, float desiredChunkSize, List <RasterizationMesh> result)
        {
            TerrainData terrainData = terrain.terrainData;

            if (terrainData == null)
            {
                throw new ArgumentException("Terrain contains no terrain data");
            }
            Vector3 position = terrain.GetPosition();
            Vector3 center   = position + ((Vector3)(terrainData.size * 0.5f));
            Bounds  bounds2  = new Bounds(center, terrainData.size);

            if (bounds2.Intersects(bounds))
            {
                int heightmapWidth  = terrainData.heightmapWidth;
                int heightmapHeight = terrainData.heightmapHeight;
                float[,] heights = terrainData.GetHeights(0, 0, heightmapWidth, heightmapHeight);
                Vector3 heightmapScale = terrainData.heightmapScale;
                heightmapScale.y = terrainData.size.y;
                int a    = Mathf.CeilToInt(Mathf.Max((float)(desiredChunkSize / (heightmapScale.x * this.terrainSampleSize)), (float)12f)) * this.terrainSampleSize;
                int num5 = Mathf.CeilToInt(Mathf.Max((float)(desiredChunkSize / (heightmapScale.z * this.terrainSampleSize)), (float)12f)) * this.terrainSampleSize;
                for (int i = 0; i < heightmapHeight; i += num5)
                {
                    for (int j = 0; j < heightmapWidth; j += a)
                    {
                        int width = Mathf.Min(a, heightmapWidth - j);
                        int depth = Mathf.Min(num5, heightmapHeight - i);
                        RasterizationMesh item = this.GenerateHeightmapChunk(heights, heightmapScale, position, j, i, width, depth, this.terrainSampleSize);
                        result.Add(item);
                    }
                }
            }
        }
コード例 #10
0
ファイル: RecastMeshGatherer.cs プロジェクト: K07H/The-Forest
        public void CollectRecastMeshObjs(List <RasterizationMesh> buffer)
        {
            List <RecastMeshObj> list = ListPool <RecastMeshObj> .Claim();

            RecastMeshObj.GetAllInBounds(list, this.bounds);
            Dictionary <Mesh, Vector3[]> dictionary  = new Dictionary <Mesh, Vector3[]>();
            Dictionary <Mesh, int[]>     dictionary2 = new Dictionary <Mesh, int[]>();

            for (int i = 0; i < list.Count; i++)
            {
                MeshFilter meshFilter = list[i].GetMeshFilter();
                Renderer   renderer   = (!(meshFilter != null)) ? null : meshFilter.GetComponent <Renderer>();
                if (meshFilter != null && renderer != null)
                {
                    Mesh sharedMesh = meshFilter.sharedMesh;
                    RasterizationMesh rasterizationMesh = new RasterizationMesh();
                    rasterizationMesh.matrix   = renderer.localToWorldMatrix;
                    rasterizationMesh.original = meshFilter;
                    rasterizationMesh.area     = list[i].area;
                    if (dictionary.ContainsKey(sharedMesh))
                    {
                        rasterizationMesh.vertices  = dictionary[sharedMesh];
                        rasterizationMesh.triangles = dictionary2[sharedMesh];
                    }
                    else
                    {
                        rasterizationMesh.vertices  = sharedMesh.vertices;
                        rasterizationMesh.triangles = sharedMesh.triangles;
                        dictionary[sharedMesh]      = rasterizationMesh.vertices;
                        dictionary2[sharedMesh]     = rasterizationMesh.triangles;
                    }
                    rasterizationMesh.bounds = renderer.bounds;
                    buffer.Add(rasterizationMesh);
                }
                else
                {
                    Collider collider = list[i].GetCollider();
                    if (collider == null)
                    {
                        Debug.LogError("RecastMeshObject (" + list[i].gameObject.name + ") didn't have a collider or MeshFilter+Renderer attached", list[i].gameObject);
                    }
                    else
                    {
                        RasterizationMesh rasterizationMesh2 = this.RasterizeCollider(collider);
                        if (rasterizationMesh2 != null)
                        {
                            rasterizationMesh2.area = list[i].area;
                            buffer.Add(rasterizationMesh2);
                        }
                    }
                }
            }
            this.capsuleCache.Clear();
            ListPool <RecastMeshObj> .Release(list);
        }
コード例 #11
0
        void CollectTreeMeshes(Terrain terrain, List <RasterizationMesh> result)
        {
            TerrainData data = terrain.terrainData;

            for (int i = 0; i < data.treeInstances.Length; i++)
            {
                TreeInstance  instance = data.treeInstances[i];
                TreePrototype prot     = data.treePrototypes[instance.prototypeIndex];

                // Make sure that the tree prefab exists
                if (prot.prefab == null)
                {
                    continue;
                }

                var collider     = prot.prefab.GetComponent <Collider>();
                var treePosition = terrain.transform.position + Vector3.Scale(instance.position, data.size);
                var scale        = new Vector3(instance.widthScale, instance.heightScale, instance.widthScale);
                scale = Vector3.Scale(scale, prot.prefab.transform.localScale);

                if (collider == null)
                {
                    var instanceBounds = new Bounds(terrain.transform.position + Vector3.Scale(instance.position, data.size), new Vector3(instance.widthScale, instance.heightScale, instance.widthScale));

                    Matrix4x4 matrix = Matrix4x4.TRS(treePosition, Quaternion.identity, scale * 0.5f);

                    var mesh = new RasterizationMesh(BoxColliderVerts, BoxColliderTris, instanceBounds, matrix);

                    result.Add(mesh);
                }
                else
                {
                    // The prefab has a collider, use that instead

                    // Generate a mesh from the collider
                    RasterizationMesh mesh = RasterizeCollider(collider, Matrix4x4.TRS(treePosition, Quaternion.identity, scale));

                    // Make sure a valid mesh was generated
                    if (mesh != null)
                    {
                        // The bounds are incorrectly based on collider.bounds.
                        // It is incorrect because the collider is on the prefab, not on the tree instance
                        // so we need to recalculate the bounds based on the actual vertex positions
                        mesh.RecalculateBounds();
                        result.Add(mesh);
                    }
                }
            }
        }
コード例 #12
0
        /// <summary>
        /// Rasterizes a collider to a mesh assuming it's vertices should be multiplied with the matrix.
        /// Note that the bounds of the returned RasterizationMesh 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.
        /// </summary>
        RasterizationMesh RasterizeCollider(Collider col, Matrix4x4 localToWorldMatrix)
        {
            RasterizationMesh result = null;

            if (col is BoxCollider)
            {
                result = RasterizeBoxCollider(col as BoxCollider, localToWorldMatrix);
            }
            else if (col is SphereCollider || col is CapsuleCollider)
            {
                var scollider = col as SphereCollider;
                var ccollider = col as CapsuleCollider;

                float      radius = (scollider != null ? scollider.radius : ccollider.radius);
                float      height = scollider != null ? 0 : (ccollider.height * 0.5f / radius) - 1;
                Quaternion rot    = Quaternion.identity;
                // Capsule colliders can be aligned along the X, Y or Z axis
                if (ccollider != null)
                {
                    rot = Quaternion.Euler(ccollider.direction == 2 ? 90 : 0, 0, ccollider.direction == 0 ? 90 : 0);
                }
                Matrix4x4 matrix = Matrix4x4.TRS(scollider != null ? scollider.center : ccollider.center, rot, Vector3.one * radius);

                matrix = localToWorldMatrix * matrix;

                result = RasterizeCapsuleCollider(radius, height, col.bounds, matrix);
            }
            else if (col is MeshCollider)
            {
                var collider = col as MeshCollider;

                if (collider.sharedMesh != null)
                {
                    result = new RasterizationMesh(collider.sharedMesh.vertices, collider.sharedMesh.triangles, collider.bounds, localToWorldMatrix);
                }
            }

                        #if ASTARDEBUG
            for (int i = 0; i < result.triangles.Length; i += 3)
            {
                Debug.DrawLine(result.matrix.MultiplyPoint3x4(result.vertices[result.triangles[i]]), result.matrix.MultiplyPoint3x4(result.vertices[result.triangles[i + 1]]), Color.yellow);
                Debug.DrawLine(result.matrix.MultiplyPoint3x4(result.vertices[result.triangles[i + 2]]), result.matrix.MultiplyPoint3x4(result.vertices[result.triangles[i + 1]]), Color.yellow);
                Debug.DrawLine(result.matrix.MultiplyPoint3x4(result.vertices[result.triangles[i]]), result.matrix.MultiplyPoint3x4(result.vertices[result.triangles[i + 2]]), Color.yellow);
            }
                        #endif

            return(result);
        }
コード例 #13
0
        // Token: 0x060027D1 RID: 10193 RVA: 0x001B497C File Offset: 0x001B2B7C
        private RasterizationMesh GenerateHeightmapChunk(float[,] heights, Vector3 sampleSize, Vector3 offset, int x0, int z0, int width, int depth, int stride)
        {
            int num     = RecastMeshGatherer.CeilDivision(width, this.terrainSampleSize) + 1;
            int num2    = RecastMeshGatherer.CeilDivision(depth, this.terrainSampleSize) + 1;
            int length  = heights.GetLength(0);
            int length2 = heights.GetLength(1);
            int num3    = num * num2;

            Vector3[] array = ArrayPool <Vector3> .Claim(num3);

            for (int i = 0; i < num2; i++)
            {
                for (int j = 0; j < num; j++)
                {
                    int num4 = Math.Min(x0 + j * stride, length - 1);
                    int num5 = Math.Min(z0 + i * stride, length2 - 1);
                    array[i * num + j] = new Vector3((float)num5 * sampleSize.x, heights[num4, num5] * sampleSize.y, (float)num4 * sampleSize.z) + offset;
                }
            }
            int num6 = (num - 1) * (num2 - 1) * 2 * 3;

            int[] array2 = ArrayPool <int> .Claim(num6);

            int num7 = 0;

            for (int k = 0; k < num2 - 1; k++)
            {
                for (int l = 0; l < num - 1; l++)
                {
                    array2[num7]     = k * num + l;
                    array2[num7 + 1] = k * num + l + 1;
                    array2[num7 + 2] = (k + 1) * num + l + 1;
                    num7            += 3;
                    array2[num7]     = k * num + l;
                    array2[num7 + 1] = (k + 1) * num + l + 1;
                    array2[num7 + 2] = (k + 1) * num + l;
                    num7            += 3;
                }
            }
            RasterizationMesh rasterizationMesh = new RasterizationMesh(array, array2, default(Bounds));

            rasterizationMesh.numVertices  = num3;
            rasterizationMesh.numTriangles = num6;
            rasterizationMesh.pool         = true;
            rasterizationMesh.RecalculateBounds();
            return(rasterizationMesh);
        }
コード例 #14
0
ファイル: RecastMeshGatherer.cs プロジェクト: K07H/The-Forest
 public void CollectSceneMeshes(List <RasterizationMesh> meshes)
 {
     if (this.tagMask.Count > 0 || this.mask != 0)
     {
         MeshFilter[]                 meshFilters = UnityEngine.Object.FindObjectsOfType <MeshFilter>();
         List <MeshFilter>            list        = RecastMeshGatherer.FilterMeshes(meshFilters, this.tagMask, this.mask);
         Dictionary <Mesh, Vector3[]> dictionary  = new Dictionary <Mesh, Vector3[]>();
         Dictionary <Mesh, int[]>     dictionary2 = new Dictionary <Mesh, int[]>();
         bool flag = false;
         for (int i = 0; i < list.Count; i++)
         {
             MeshFilter meshFilter = list[i];
             Renderer   component  = meshFilter.GetComponent <Renderer>();
             if (component.isPartOfStaticBatch)
             {
                 flag = true;
             }
             else if (component.bounds.Intersects(this.bounds))
             {
                 Mesh sharedMesh = meshFilter.sharedMesh;
                 RasterizationMesh rasterizationMesh = new RasterizationMesh();
                 rasterizationMesh.matrix   = component.localToWorldMatrix;
                 rasterizationMesh.original = meshFilter;
                 if (dictionary.ContainsKey(sharedMesh))
                 {
                     rasterizationMesh.vertices  = dictionary[sharedMesh];
                     rasterizationMesh.triangles = dictionary2[sharedMesh];
                 }
                 else
                 {
                     rasterizationMesh.vertices  = sharedMesh.vertices;
                     rasterizationMesh.triangles = sharedMesh.triangles;
                     dictionary[sharedMesh]      = rasterizationMesh.vertices;
                     dictionary2[sharedMesh]     = rasterizationMesh.triangles;
                 }
                 rasterizationMesh.bounds = component.bounds;
                 meshes.Add(rasterizationMesh);
             }
             if (flag)
             {
                 Debug.LogWarning("Some meshes were statically batched. These meshes can not be used for navmesh calculation due to technical constraints.\nDuring runtime scripts cannot access the data of meshes which have been statically batched.\nOne way to solve this problem is to use cached startup (Save & Load tab in the inspector) to only calculate the graph when the game is not playing.");
             }
         }
     }
 }
コード例 #15
0
        // Token: 0x060027CF RID: 10191 RVA: 0x001B47A4 File Offset: 0x001B29A4
        private void GenerateTerrainChunks(Terrain terrain, Bounds bounds, float desiredChunkSize, List <RasterizationMesh> result)
        {
            TerrainData terrainData = terrain.terrainData;

            if (terrainData == null)
            {
                throw new ArgumentException("Terrain contains no terrain data");
            }
            Vector3 position = terrain.GetPosition();
            Vector3 center   = position + terrainData.size * 0.5f;
            Bounds  bounds2  = new Bounds(center, terrainData.size);

            if (!bounds2.Intersects(bounds))
            {
                return;
            }
            int heightmapResolution  = terrainData.heightmapResolution;
            int heightmapResolution2 = terrainData.heightmapResolution;

            float[,] heights = terrainData.GetHeights(0, 0, heightmapResolution, heightmapResolution2);
            Vector3 heightmapScale = terrainData.heightmapScale;

            heightmapScale.y = terrainData.size.y;
            int num  = Mathf.CeilToInt(Mathf.Max(desiredChunkSize / (heightmapScale.x * (float)this.terrainSampleSize), 12f)) * this.terrainSampleSize;
            int num2 = Mathf.CeilToInt(Mathf.Max(desiredChunkSize / (heightmapScale.z * (float)this.terrainSampleSize), 12f)) * this.terrainSampleSize;

            for (int i = 0; i < heightmapResolution2; i += num2)
            {
                for (int j = 0; j < heightmapResolution; j += num)
                {
                    int     num3    = Mathf.Min(num, heightmapResolution - j);
                    int     num4    = Mathf.Min(num2, heightmapResolution2 - i);
                    Vector3 min     = position + new Vector3((float)i * heightmapScale.x, 0f, (float)j * heightmapScale.z);
                    Vector3 max     = position + new Vector3((float)(i + num4) * heightmapScale.x, heightmapScale.y, (float)(j + num3) * heightmapScale.z);
                    Bounds  bounds3 = default(Bounds);
                    bounds3.SetMinMax(min, max);
                    if (bounds3.Intersects(bounds))
                    {
                        RasterizationMesh item = this.GenerateHeightmapChunk(heights, heightmapScale, position, j, i, num3, num4, this.terrainSampleSize);
                        result.Add(item);
                    }
                }
            }
        }
コード例 #16
0
ファイル: RecastMeshGatherer.cs プロジェクト: K07H/The-Forest
 public void CollectColliderMeshes(List <RasterizationMesh> result)
 {
     Collider[] array = UnityEngine.Object.FindObjectsOfType <Collider>();
     if (this.tagMask.Count > 0 || this.mask != 0)
     {
         foreach (Collider collider in array)
         {
             if (((this.mask >> collider.gameObject.layer & 1) != 0 || this.tagMask.Contains(collider.tag)) && collider.enabled && !collider.isTrigger && collider.bounds.Intersects(this.bounds) && collider.GetComponent <RecastMeshObj>() == null)
             {
                 RasterizationMesh rasterizationMesh = this.RasterizeCollider(collider);
                 if (rasterizationMesh != null)
                 {
                     result.Add(rasterizationMesh);
                 }
             }
         }
     }
     this.capsuleCache.Clear();
 }
コード例 #17
0
 // Token: 0x060027D3 RID: 10195 RVA: 0x001B4C8C File Offset: 0x001B2E8C
 public void CollectColliderMeshes(List <RasterizationMesh> result)
 {
     Collider[] array = Physics.OverlapSphere(this.bounds.center, this.bounds.size.magnitude, -1, QueryTriggerInteraction.Ignore);
     if (this.tagMask.Count > 0 || this.mask != 0)
     {
         foreach (Collider collider in array)
         {
             if (((this.mask >> collider.gameObject.layer & 1) != 0 || this.tagMask.Contains(collider.tag)) && collider.enabled && !collider.isTrigger && collider.bounds.Intersects(this.bounds) && collider.GetComponent <RecastMeshObj>() == null)
             {
                 RasterizationMesh rasterizationMesh = this.RasterizeCollider(collider);
                 if (rasterizationMesh != null)
                 {
                     result.Add(rasterizationMesh);
                 }
             }
         }
     }
     this.capsuleCache.Clear();
 }
コード例 #18
0
 public void CollectColliderMeshes(List <RasterizationMesh> result)
 {
     Collider[] colliderArray = UnityEngine.Object.FindObjectsOfType <Collider>();
     if ((this.tagMask.Count > 0) || (this.mask != 0))
     {
         for (int i = 0; i < colliderArray.Length; i++)
         {
             Collider col = colliderArray[i];
             if (((((this.mask >> (col.gameObject.layer & 0x1f)) & 1) != 0) || this.tagMask.Contains(col.tag)) && ((col.enabled && !col.isTrigger) && (col.bounds.Intersects(this.bounds) && (col.GetComponent <RecastMeshObj>() == null))))
             {
                 RasterizationMesh item = this.RasterizeCollider(col);
                 if (item != null)
                 {
                     result.Add(item);
                 }
             }
         }
     }
     this.capsuleCache.Clear();
 }
コード例 #19
0
        private RasterizationMesh GenerateHeightmapChunk(float[,] heights, Vector3 sampleSize, Vector3 offset, int x0, int z0, int width, int depth, int stride)
        {
            int num    = CeilDivision(width, this.terrainSampleSize) + 1;
            int num2   = CeilDivision(depth, this.terrainSampleSize) + 1;
            int length = heights.GetLength(0);
            int num4   = heights.GetLength(1);

            Vector3[] vertices = new Vector3[num * num2];
            for (int i = 0; i < num2; i++)
            {
                for (int k = 0; k < num; k++)
                {
                    int num7 = Math.Min((int)(x0 + (k * stride)), (int)(length - 1));
                    int num8 = Math.Min((int)(z0 + (i * stride)), (int)(num4 - 1));
                    vertices[(i * num) + k] = new Vector3(num8 * sampleSize.x, heights[num7, num8] * sampleSize.y, num7 * sampleSize.z) + offset;
                }
            }
            int[] triangles = new int[(((num - 1) * (num2 - 1)) * 2) * 3];
            int   index     = 0;

            for (int j = 0; j < (num2 - 1); j++)
            {
                for (int m = 0; m < (num - 1); m++)
                {
                    triangles[index]     = (j * num) + m;
                    triangles[index + 1] = ((j * num) + m) + 1;
                    triangles[index + 2] = (((j + 1) * num) + m) + 1;
                    index               += 3;
                    triangles[index]     = (j * num) + m;
                    triangles[index + 1] = (((j + 1) * num) + m) + 1;
                    triangles[index + 2] = ((j + 1) * num) + m;
                    index               += 3;
                }
            }
            RasterizationMesh mesh = new RasterizationMesh(vertices, triangles, new Bounds());

            mesh.RecalculateBounds();
            return(mesh);
        }
コード例 #20
0
ファイル: RecastMeshGatherer.cs プロジェクト: K07H/The-Forest
        private RasterizationMesh GenerateHeightmapChunk(float[,] heights, Vector3 sampleSize, Vector3 offset, int x0, int z0, int width, int depth, int stride)
        {
            int num     = RecastMeshGatherer.CeilDivision(width, this.terrainSampleSize) + 1;
            int num2    = RecastMeshGatherer.CeilDivision(depth, this.terrainSampleSize) + 1;
            int length  = heights.GetLength(0);
            int length2 = heights.GetLength(1);

            Vector3[] array = new Vector3[num * num2];
            for (int i = 0; i < num2; i++)
            {
                for (int j = 0; j < num; j++)
                {
                    int num3 = Math.Min(x0 + j * stride, length - 1);
                    int num4 = Math.Min(z0 + i * stride, length2 - 1);
                    array[i * num + j] = new Vector3((float)num4 * sampleSize.x, heights[num3, num4] * sampleSize.y, (float)num3 * sampleSize.z) + offset;
                }
            }
            int[] array2 = new int[(num - 1) * (num2 - 1) * 2 * 3];
            int   num5   = 0;

            for (int k = 0; k < num2 - 1; k++)
            {
                for (int l = 0; l < num - 1; l++)
                {
                    array2[num5]     = k * num + l;
                    array2[num5 + 1] = k * num + l + 1;
                    array2[num5 + 2] = (k + 1) * num + l + 1;
                    num5            += 3;
                    array2[num5]     = k * num + l;
                    array2[num5 + 1] = (k + 1) * num + l + 1;
                    array2[num5 + 2] = (k + 1) * num + l;
                    num5            += 3;
                }
            }
            RasterizationMesh rasterizationMesh = new RasterizationMesh(array, array2, default(Bounds));

            rasterizationMesh.RecalculateBounds();
            return(rasterizationMesh);
        }
コード例 #21
0
        public void CollectSceneMeshes(List <RasterizationMesh> meshes)
        {
            if (tagMask.Count > 0 || mask != 0)
            {
                // This is unfortunately the fastest way to find all mesh filters.. and it is not particularly fast.
                var meshFilters    = GameObject.FindObjectsOfType <MeshFilter>();
                var filteredMeshes = FilterMeshes(meshFilters, tagMask, mask);

                var cachedVertices = new Dictionary <Mesh, Vector3[]>();
                var cachedTris     = new Dictionary <Mesh, int[]>();

                bool containedStatic = false;

                for (int i = 0; i < filteredMeshes.Count; i++)
                {
                    MeshFilter filter = filteredMeshes[i];

                    // Note, guaranteed to have a renderer
                    Renderer rend = filter.GetComponent <Renderer>();

                    if (rend.isPartOfStaticBatch)
                    {
                        // Statically batched meshes cannot be used due to Unity limitations
                        // log a warning about this
                        containedStatic = true;
                    }
                    else
                    {
                        // Only include it if it intersects with the graph
                        if (rend.bounds.Intersects(bounds))
                        {
                            Mesh mesh = filter.sharedMesh;
                            RasterizationMesh smesh;

                            // Check the cache to avoid allocating
                            // a new array unless necessary
                            if (cachedVertices.ContainsKey(mesh))
                            {
                                smesh = new RasterizationMesh(cachedVertices[mesh], cachedTris[mesh], rend.bounds);
                            }
                            else
                            {
                                smesh = new RasterizationMesh(mesh.vertices, mesh.triangles, rend.bounds);
                                cachedVertices[mesh] = smesh.vertices;
                                cachedTris[mesh]     = smesh.triangles;
                            }

                            smesh.matrix   = rend.localToWorldMatrix;
                            smesh.original = filter;
                            meshes.Add(smesh);
                        }
                    }

                    if (containedStatic)
                    {
                        Debug.LogWarning("Some meshes were statically batched. These meshes can not be used for navmesh calculation" +
                                         " due to technical constraints.\nDuring runtime scripts cannot access the data of meshes which have been statically batched.\n" +
                                         "One way to solve this problem is to use cached startup (Save & Load tab in the inspector) to only calculate the graph when the game is not playing.");
                    }
                }

                                #if ASTARDEBUG
                int y = 0;
                foreach (RasterizationMesh smesh in meshes)
                {
                    y++;
                    Vector3[] vecs = smesh.vertices;
                    int[]     tris = smesh.triangles;

                    for (int i = 0; i < tris.Length; i += 3)
                    {
                        Vector3 p1 = smesh.matrix.MultiplyPoint3x4(vecs[tris[i + 0]]);
                        Vector3 p2 = smesh.matrix.MultiplyPoint3x4(vecs[tris[i + 1]]);
                        Vector3 p3 = smesh.matrix.MultiplyPoint3x4(vecs[tris[i + 2]]);

                        Debug.DrawLine(p1, p2, Color.red, 1);
                        Debug.DrawLine(p2, p3, Color.red, 1);
                        Debug.DrawLine(p3, p1, Color.red, 1);
                    }
                }
                                #endif
            }
        }
コード例 #22
0
        public MeshCollection Finalize()
        {
#if UNITY_2020_1_OR_NEWER
            Mesh.MeshDataArray data = Mesh.AcquireReadOnlyMeshData(meshData);
            var meshes           = new NativeArray <RasterizationMesh>(this.meshes.Count, Allocator.Persistent);
            int meshBufferOffset = vertexBuffers.Count;

            UnityEngine.Profiling.Profiler.BeginSample("Copying vertices");
            for (int i = 0; i < data.Length; i++)
            {
                var rawMeshData = data[i];
                var verts       = new NativeArray <Vector3>(rawMeshData.vertexCount, Allocator.Persistent, NativeArrayOptions.UninitializedMemory);
                rawMeshData.GetVertices(verts);
                int totalIndices = 0;
                for (int subMeshIndex = 0; subMeshIndex < rawMeshData.subMeshCount; subMeshIndex++)
                {
                    totalIndices += rawMeshData.GetSubMesh(subMeshIndex).indexCount;
                }
                var tris   = new NativeArray <int>(totalIndices, Allocator.Persistent, NativeArrayOptions.UninitializedMemory);
                int offset = 0;
                for (int subMeshIndex = 0; subMeshIndex < rawMeshData.subMeshCount; subMeshIndex++)
                {
                    var submesh = rawMeshData.GetSubMesh(subMeshIndex);
                    rawMeshData.GetIndices(tris.GetSubArray(offset, submesh.indexCount), subMeshIndex);
                    offset += submesh.indexCount;
                }

                vertexBuffers.Add(verts);
                triangleBuffers.Add(tris);
            }
            UnityEngine.Profiling.Profiler.EndSample();

            for (int i = 0; i < meshes.Length; i++)
            {
                var gatheredMesh = this.meshes[i];
                int bufferIndex;
                if (gatheredMesh.meshDataIndex >= 0)
                {
                    bufferIndex = meshBufferOffset + gatheredMesh.meshDataIndex;
                }
                else
                {
                    bufferIndex = -(gatheredMesh.meshDataIndex + 1);
                }

                var bounds = gatheredMesh.bounds;
                var slice  = vertexBuffers[bufferIndex].Reinterpret <float3>();
                if (bounds == new Bounds())
                {
                    UnityEngine.Profiling.Profiler.BeginSample("CalculateBounds");
                    // Recalculate bounding box
                    float4x4 m = gatheredMesh.matrix;
                    unsafe {
                        CalculateBoundsInvoke((float3 *)slice.GetUnsafeReadOnlyPtr(), slice.Length, ref m, out bounds);
                    }
                    UnityEngine.Profiling.Profiler.EndSample();
                }

                var triangles = triangleBuffers[bufferIndex];
                meshes[i] = new RasterizationMesh {
                    vertices  = new UnsafeSpan <float3>(slice),
                    triangles = new UnsafeSpan <int>(triangles.Slice(0, gatheredMesh.indicesCount != -1 ? gatheredMesh.indicesCount : triangles.Length)),
                    area      = gatheredMesh.area,
                    bounds    = bounds,
                    matrix    = gatheredMesh.matrix,
                    solid     = gatheredMesh.solid,
                };
            }

            cachedMeshes.Clear();
            ObjectPoolSimple <Dictionary <MeshCacheItem, int> > .Release(ref cachedMeshes);

            ListPool <GatheredMesh> .Release(ref this.meshes);

            data.Dispose();

            return(new MeshCollection(vertexBuffers, triangleBuffers, meshes));
#else
            throw new System.NotImplementedException("The burst version of recast is only supported in Unity 2020.1 or later");
#endif
        }
コード例 #23
0
        /// <summary>Find all relevant RecastMeshObj components and create ExtraMeshes for them</summary>
        public void CollectRecastMeshObjs(List <RasterizationMesh> buffer)
        {
            var buffer2 = Util.ListPool <RecastMeshObj> .Claim();

            // Get all recast mesh objects inside the bounds
            RecastMeshObj.GetAllInBounds(buffer2, bounds);

            var cachedVertices = new Dictionary <Mesh, Vector3[]>();
            var cachedTris     = new Dictionary <Mesh, int[]>();

            // Create an RasterizationMesh object
            // for each RecastMeshObj
            for (int i = 0; i < buffer2.Count; i++)
            {
                MeshFilter filter = buffer2[i].GetMeshFilter();
                Renderer   rend   = filter != null?filter.GetComponent <Renderer>() : null;

                if (filter != null && rend != null && filter.sharedMesh != null)
                {
                    Mesh mesh = filter.sharedMesh;
                    RasterizationMesh smesh;

                    // Don't read the vertices and triangles from the
                    // mesh if we have seen the same mesh previously
                    if (cachedVertices.ContainsKey(mesh))
                    {
                        smesh = new RasterizationMesh(cachedVertices[mesh], cachedTris[mesh], rend.bounds);
                    }
                    else
                    {
                        smesh = new RasterizationMesh(mesh.vertices, mesh.triangles, rend.bounds);
                        cachedVertices[mesh] = smesh.vertices;
                        cachedTris[mesh]     = smesh.triangles;
                    }

                    smesh.matrix   = rend.localToWorldMatrix;
                    smesh.original = filter;
                    smesh.area     = buffer2[i].area;
                    buffer.Add(smesh);
                }
                else
                {
                    Collider coll = buffer2[i].GetCollider();

                    if (coll == null)
                    {
                        Debug.LogError("RecastMeshObject (" + buffer2[i].gameObject.name + ") didn't have a collider or MeshFilter+Renderer attached", buffer2[i].gameObject);
                        continue;
                    }

                    RasterizationMesh smesh = RasterizeCollider(coll);

                    // Make sure a valid RasterizationMesh was returned
                    if (smesh != null)
                    {
                        smesh.area = buffer2[i].area;
                        buffer.Add(smesh);
                    }
                }
            }

            // Clear cache to avoid memory leak
            capsuleCache.Clear();

            Util.ListPool <RecastMeshObj> .Release(ref buffer2);
        }