コード例 #1
0
        public static void CombineMeshes(Queue<CombineInstance> items
            , byte area
            , InputGeometryCompiler compiler)
        {
            const int MaxTris = 65000;

            List<CombineInstance> combineInstancesPart = new List<CombineInstance>();
            byte[] areas = NMGen.CreateAreaBuffer(MaxTris, area);

            while (items.Count != 0)
            {
                int vertCount = 0;

                while (items.Count > 0
                    && (vertCount + items.Peek().mesh.vertexCount < MaxTris))
                {
                    vertCount += items.Peek().mesh.vertexCount;
                    combineInstancesPart.Add(items.Dequeue());
                }

                Mesh meshPart = new Mesh();

                meshPart.CombineMeshes(combineInstancesPart.ToArray(), true, true);

                compiler.AddTriangles(meshPart.vertices, meshPart.vertexCount
                    , meshPart.triangles, areas, meshPart.triangles.Length / 3);

                Object.DestroyImmediate(meshPart);

                combineInstancesPart.Clear();
            }
        }
コード例 #2
0
ファイル: MeshUtil.cs プロジェクト: niuniuzhu/RCFramework
        public static void CombineMeshes(Queue <CombineInstance> items
                                         , byte area
                                         , InputGeometryCompiler compiler)
        {
            const int MaxTris = 65000;

            List <CombineInstance> combineInstancesPart = new List <CombineInstance>();

            byte[] areas = NMGen.CreateAreaBuffer(MaxTris, area);

            while (items.Count != 0)
            {
                int vertCount = 0;

                while (items.Count > 0 &&
                       (vertCount + items.Peek().mesh.vertexCount < MaxTris))
                {
                    vertCount += items.Peek().mesh.vertexCount;
                    combineInstancesPart.Add(items.Dequeue());
                }

                Mesh meshPart = new Mesh();

                meshPart.CombineMeshes(combineInstancesPart.ToArray(), true, true);

                UnityEngine.Vector3[] vs  = meshPart.vertices;
                Vector3[]             vvs = VectorHelper.ToVector3Array(ref vs);
                compiler.AddTriangles(vvs, meshPart.vertexCount
                                      , meshPart.triangles, areas, meshPart.triangles.Length / 3);

                Object.DestroyImmediate(meshPart);

                combineInstancesPart.Clear();
            }
        }
コード例 #3
0
ファイル: TerrainCompiler.cs プロジェクト: zhu1987/critterai
    private void Compile(InputBuildContext context)
    {
        context.info.compilerCount++;

        InputGeometryCompiler compiler = context.geomCompiler;
        List <Component>      items    = context.components;
        List <byte>           areas    = context.areas;

        for (int i = 0; i < items.Count; i++)
        {
            Component item = items[i];

            if (item is Terrain)
            {
                Terrain terrain = (Terrain)item;

                if (terrain.terrainData != terrainData)
                {
                    continue;
                }

                TriangleMesh mesh   = TerrainUtil.TriangulateSurface(terrain, mResolution);
                byte[]       lareas = NMGen.CreateAreaBuffer(mesh.triCount, areas[i]);

                if (compiler.AddTriangles(mesh, lareas))
                {
                    string msg = string.Format("Compiled the {0} terrain surface. Triangles: {1}"
                                               , terrain.name, mesh.triCount);

                    context.Log(msg, this);
                }
                else
                {
                    string msg =
                        string.Format("Compiler rejected mesh for the {0} terrain.", terrain.name);

                    context.LogError(msg, this);

                    return;
                }

                if (includeTrees)
                {
                    int before = compiler.TriCount;

                    TerrainUtil.TriangluateTrees(terrain, areas[i], compiler);

                    string msg = string.Format("Compiled the {0} terrain trees. Triangles: {1}"
                                               , terrain.name, compiler.TriCount - before);

                    context.Log(msg, this);
                }

                break;
            }
        }
    }
コード例 #4
0
ファイル: MeshCompiler.cs プロジェクト: zwong91/Titan
    private void CombineMeshes(Queue <MeshFilter> filters
                               , byte area
                               , InputGeometryCompiler compiler
                               , ColliderHelper helper)
    {
        Queue <CombineInstance> combineInstances = new Queue <CombineInstance>();

        while (filters.Count != 0)
        {
            MeshFilter filter = filters.Dequeue();

            if (helper != null)
            {
                Collider collider = filter.GetComponent <Collider>();

                if (collider)
                {
                    CombineInstance ci;

                    if (helper.Get(collider, out ci))
                    {
                        combineInstances.Enqueue(ci);
                        continue;
                    }
                }
            }

            // Note: Null shared meshes were filtered out by the calling method.

            for (int subIndex = 0; subIndex < filter.sharedMesh.subMeshCount; ++subIndex)
            {
                CombineInstance combineInstance = new CombineInstance();
                combineInstance.mesh         = filter.sharedMesh;
                combineInstance.transform    = filter.transform.localToWorldMatrix;
                combineInstance.subMeshIndex = subIndex;

                combineInstances.Enqueue(combineInstance);
            }
        }

        MeshUtil.CombineMeshes(combineInstances, area, compiler);
    }
コード例 #5
0
        public static void TriangluateTrees(Terrain terrain
                                            , byte area
                                            , InputGeometryCompiler compiler)
        {
            if (terrain == null || terrain.terrainData == null || compiler == null)
            {
                return;
            }

            TerrainData data = terrain.terrainData;

            // Note: This array may be loaded with nulls.
            // This is required to keep indices in sync.
            Mesh[] protoMeshes = new Mesh[data.treePrototypes.Length];

            for (int i = 0; i < protoMeshes.Length; i++)
            {
                TreePrototype prototype = data.treePrototypes[i];
                MeshFilter    filter    = prototype.prefab.GetComponent <MeshFilter>();

                if (filter == null || filter.sharedMesh == null)
                {
                    Debug.LogWarning(string.Format(
                                         "{0} : There is no mesh attached the {1} tree prototype."
                                         + "Trees based on this prototype will be ignored."
                                         , terrain.name
                                         , prototype.prefab.name));
                    protoMeshes[i] = null;
                }
                else
                {
                    protoMeshes[i] = filter.sharedMesh;
                }
            }

            UnityEngine.Vector3 terrainPos  = terrain.transform.position;
            UnityEngine.Vector3 terrainSize = terrain.terrainData.size;

            Queue <CombineInstance> combineInstances =
                new Queue <CombineInstance>(data.treeInstances.Length);

            foreach (TreeInstance tree in data.treeInstances)
            {
                if (protoMeshes[tree.prototypeIndex] == null)
                {
                    // Prototype for this tree doesn't have a mesh.
                    continue;
                }

                UnityEngine.Vector3 pos = tree.position;
                pos.x *= terrainSize.x;
                pos.y *= terrainSize.y;
                pos.z *= terrainSize.z;
                pos   += terrainPos;

                UnityEngine.Vector3 scale =
                    new UnityEngine.Vector3(tree.widthScale, tree.heightScale, tree.widthScale);

                CombineInstance ci = new CombineInstance();
                ci.mesh      = protoMeshes[tree.prototypeIndex];
                ci.transform = Matrix4x4.TRS(pos, Quaternion.identity, scale);

                combineInstances.Enqueue(ci);
            }

            protoMeshes = null;

            if (combineInstances.Count == 0)
            {
                return;
            }

            MeshUtil.CombineMeshes(combineInstances, area, compiler);
        }
コード例 #6
0
ファイル: TerrainUtil.cs プロジェクト: BibleUs/critterai
        public static void TriangluateTrees(Terrain terrain
            , byte area
            , InputGeometryCompiler compiler)
        {
            if (terrain == null || terrain.terrainData == null || compiler == null)
                return;

            TerrainData data = terrain.terrainData;

            // Note: This array may be loaded with nulls.
            // This is required to keep indices in sync.
            Mesh[] protoMeshes = new Mesh[data.treePrototypes.Length];

            for (int i = 0; i < protoMeshes.Length; i++)
            {
                TreePrototype prototype = data.treePrototypes[i];
                MeshFilter filter = prototype.prefab.GetComponent<MeshFilter>();

                if (filter == null || filter.sharedMesh == null)
                {
                    Debug.LogWarning(string.Format(
                        "{0} : There is no mesh attached the {1} tree prototype."
                            + "Trees based on this prototype will be ignored."
                        , terrain.name
                        , prototype.prefab.name));
                    protoMeshes[i] = null;
                }
                else
                    protoMeshes[i] = filter.sharedMesh;
            }

            Vector3 terrainPos = terrain.transform.position;
            Vector3 terrainSize = terrain.terrainData.size;

            Queue<CombineInstance> combineInstances =
                new Queue<CombineInstance>(data.treeInstances.Length);

            foreach (TreeInstance tree in data.treeInstances)
            {
                if (protoMeshes[tree.prototypeIndex] == null)
                    // Prototype for this tree doesn't have a mesh.
                    continue;

                Vector3 pos = tree.position;
                pos.x *= terrainSize.x;
                pos.y *= terrainSize.y;
                pos.z *= terrainSize.z;
                pos += terrainPos;

                Vector3 scale =
                    new Vector3(tree.widthScale, tree.heightScale, tree.widthScale);

                CombineInstance ci = new CombineInstance();
                ci.mesh = protoMeshes[tree.prototypeIndex];
                ci.transform = Matrix4x4.TRS(pos, Quaternion.identity, scale);

                combineInstances.Enqueue(ci);
            }

            protoMeshes = null;

            if (combineInstances.Count == 0)
                return;

            MeshUtil.CombineMeshes(combineInstances, area, compiler);
        }
コード例 #7
0
ファイル: MeshCompiler.cs プロジェクト: zwong91/Titan
    private void Compile(InputBuildContext context)
    {
        context.info.compilerCount++;

        ColliderHelper colliderHelper = (colocationOption == MeshColocationOption.Collider)
            ? new ColliderHelper()
            : null;

        InputGeometryCompiler compiler = context.geomCompiler;

        List <Component> master = new List <Component>(context.components);
        List <byte>      areas  = new List <byte>(context.areas);

        Queue <MeshFilter> filters = new Queue <MeshFilter>();

        int count   = 0;
        int ignored = 0;

        while (master.Count > 0)
        {
            byte area = 0;

            for (int i = master.Count - 1; i >= 0; i--)
            {
                Component item = master[i];

                if (item is MeshFilter)
                {
                    MeshFilter filter = (MeshFilter)item;
                    if (filter.sharedMesh == null)
                    {
                        ignored++;
                        areas.RemoveAt(i);
                        master.RemoveAt(i);
                    }
                    else
                    {
                        if (filters.Count == 0)
                        {
                            area = areas[i];
                        }

                        if (areas[i] == area)
                        {
                            count++;
                            filters.Enqueue(filter);
                            areas.RemoveAt(i);
                            master.RemoveAt(i);
                        }
                    }
                }
                else
                {
                    areas.RemoveAt(i);
                    master.RemoveAt(i);
                }
            }

            if (filters.Count > 0)
            {
                CombineMeshes(filters, area, compiler, colliderHelper);
            }
        }

        if (colliderHelper != null)
        {
            colliderHelper.Dispose();
        }

        if (ignored > 0)
        {
            string msg = string.Format("{0}: Ignored {1} MeshFilters with a null mesh."
                                       , name, ignored);

            context.Log(msg, this);
        }

        context.Log(string.Format("{0}: Compiled {1} MeshFilters.", name, count), this);
    }