Example #1
0
        internal static BuildStatus Build(List <Brush> brushes,
                                          CSGBuildSettings buildSettings,
                                          CSGBuildContext.BuildContext buildContext,
                                          Transform rootTransform,
                                          MaterialMeshDictionary materialMeshDictionary,
                                          List <Mesh> collisionMeshDictionary,
                                          bool polygonsRemoved,
                                          bool forceRebuild,
                                          Action <float> onProgressChange,
                                          Action <GameObject, Mesh> onFinalizeVisualMesh,
                                          Action <GameObject, Mesh> onFinalizeCollisionMesh,
                                          bool multithreaded)
        {
            CSGFactory.brushes                 = brushes;
            CSGFactory.buildSettings           = buildSettings;
            CSGFactory.buildContext            = buildContext;
            CSGFactory.rootTransform           = rootTransform;
            CSGFactory.materialMeshDictionary  = materialMeshDictionary;
            CSGFactory.collisionMeshDictionary = collisionMeshDictionary;
            CSGFactory.polygonsRemoved         = polygonsRemoved;
            CSGFactory.forceRebuild            = forceRebuild;
            CSGFactory.onProgressChange        = onProgressChange;
            CSGFactory.onFinalizeVisualMesh    = onFinalizeVisualMesh;
            CSGFactory.onFinalizeCollisionMesh = onFinalizeCollisionMesh;

//			DebugExclude.hackyHolder = DebugExclude.GetMetaDataHolder();
//			BrushChunk.ResetNextID();

            if (buildInProgress)
            {
                Debug.LogWarning("Existing build has not completed");
            }

            if (multithreaded)
            {
                readyForFinalize = false;
                buildInProgress  = true;
                ThreadPool.QueueUserWorkItem(CoreBuild, true);
                // FinalizeBuild is called by Tick when CoreBuild is complete
                return(BuildStatus.Started);
            }
            else
            {
                readyForFinalize = false;
                CoreBuild(null);
                bool buildOccurred = FinalizeBuild();
                buildInProgress = false;

                return(buildOccurred ? BuildStatus.Complete : BuildStatus.Unnecessary);
            }
        }
        internal static void BuildVisual(Transform meshGroupHolder,
                                         PolygonEntry[] polygonIndex,
                                         CSGBuildSettings buildSettings,
                                         CSGBuildContext.BuildContext buildContext,
                                         MaterialMeshDictionary materialMeshDictionary)
        {
            materialMeshDictionary.Clear();

            // Reset statistics
            buildContext.buildMetrics.TotalMeshes    = 0;
            buildContext.buildMetrics.TotalVertices  = 0;
            buildContext.buildMetrics.TotalTriangles = 0;

            Dictionary <Material, List <PolygonEntry> > polygonMaterialTable = new Dictionary <Material, List <PolygonEntry> >();

            for (int i = 0; i < polygonIndex.Length; i++)
            {
                PolygonEntry entry = polygonIndex[i];

                if (PolygonEntry.IsValid(entry) &&
                    entry.Positions.Length > 0 &&
                    !entry.ExcludeFromBuild)    // Skip polygons that weren't built
                {
                    Material material = entry.Material;

                    if (material == null)
                    {
                        material = buildSettings.DefaultVisualMaterial;
                    }

                    if (polygonMaterialTable.ContainsKey(material))
                    {
                        polygonMaterialTable[material].Add(entry);
                    }
                    else
                    {
                        polygonMaterialTable.Add(material, new List <PolygonEntry>()
                        {
                            entry
                        });
                    }
                }
            }

            foreach (KeyValuePair <Material, List <PolygonEntry> > row in polygonMaterialTable)
            {
                Mesh mesh = new Mesh();

                List <Vector3> positionsList = new List <Vector3>();
                List <Vector3> normalsList   = new List <Vector3>();
                List <Vector2> uvList        = new List <Vector2>();
                List <Color>   colorsList    = new List <Color>();
                List <int>     trianglesList = new List <int>();

                for (int i = 0; i < row.Value.Count; i++)
                {
                    int positionOffset = positionsList.Count;
                    int triangleOffset = trianglesList.Count;

                    PolygonEntry polygonEntry = row.Value[i];
                    if (polygonEntry.Positions.Length + positionOffset > MESH_VERTEX_LIMIT)
                    {
                        FinalizeVisualMesh(meshGroupHolder, mesh, row.Key, buildSettings, buildContext, positionsList, normalsList, uvList, colorsList, trianglesList, materialMeshDictionary);
                        mesh = new Mesh();
                        positionsList.Clear();
                        normalsList.Clear();
                        uvList.Clear();
                        colorsList.Clear();
                        trianglesList.Clear();
                        positionOffset = 0;
                    }
                    positionsList.AddRange(polygonEntry.Positions);
                    normalsList.AddRange(polygonEntry.Normals);
                    uvList.AddRange(polygonEntry.UV);
                    colorsList.AddRange(polygonEntry.Colors);

                    for (int j = 0; j < polygonEntry.Triangles.Length; j++)
                    {
                        trianglesList.Add(polygonEntry.Triangles[j] + positionOffset);
                    }

                    row.Value[i].BuiltMesh           = mesh;
                    row.Value[i].BuiltVertexOffset   = positionOffset;
                    row.Value[i].BuiltTriangleOffset = triangleOffset;
                }

                FinalizeVisualMesh(meshGroupHolder, mesh, row.Key, buildSettings, buildContext, positionsList, normalsList, uvList, colorsList, trianglesList, materialMeshDictionary);
            }
        }
        internal static void FinalizeVisualMesh(Transform meshGroupHolder,
                                                Mesh mesh,
                                                Material material,
                                                CSGBuildSettings buildSettings,
                                                CSGBuildContext.BuildContext buildContext,
                                                List <Vector3> positionsList,
                                                List <Vector3> normalsList,
                                                List <Vector2> uvList,
                                                List <Color> colorsList,
                                                List <int> trianglesList,
                                                MaterialMeshDictionary materialMeshDictionary)
        {
            Vector3[] positionsArray = new Vector3[positionsList.Count];
            Vector3[] normalsArray   = new Vector3[normalsList.Count];
            Vector2[] uvArray        = new Vector2[uvList.Count];
            Color[]   colorsArray    = new Color[colorsList.Count];
            int[]     trianglesArray = new int[trianglesList.Count];

            positionsList.CopyTo(positionsArray);
            normalsList.CopyTo(normalsArray);
            uvList.CopyTo(uvArray);
            trianglesList.CopyTo(trianglesArray);
            colorsList.CopyTo(colorsArray);

            mesh.vertices = positionsArray;
            mesh.normals  = normalsArray;
            mesh.uv       = uvArray;
            mesh.colors   = colorsArray;

            if (meshGroupHolder.position != Vector3.zero ||
                meshGroupHolder.rotation != Quaternion.identity ||
                meshGroupHolder.lossyScale != Vector3.one)
            {
                mesh.LocalizeToTransform(meshGroupHolder);
            }

            mesh.triangles = trianglesArray;

            if (buildSettings.GenerateTangents)
            {
                // Generate tangents, necessary for some shaders
                mesh.GenerateTangents();
            }

            buildContext.buildMetrics.TotalMeshes++;
            buildContext.buildMetrics.TotalVertices  += positionsArray.Length;
            buildContext.buildMetrics.TotalTriangles += trianglesArray.Length / 3;

            GameObject newGameObject = new GameObject("MaterialMesh");

            // Allow any editor dependent code to fire, e.g. lightmap unwrapping, static flags
            if (OnFinalizeVisualMesh != null)
            {
                OnFinalizeVisualMesh(newGameObject, mesh);
            }

            newGameObject.AddComponent <MeshFilter>().sharedMesh = mesh;
            MeshRenderer meshRenderer = newGameObject.AddComponent <MeshRenderer>();

            meshRenderer.sharedMaterial       = material;
            meshRenderer.shadowCastingMode    = buildSettings.ShadowCastingMode;
            meshRenderer.reflectionProbeUsage = buildSettings.ReflectionProbeUsage;
            //newGameObject.transform.parent = meshGroupHolder;

            newGameObject.transform.SetParent(meshGroupHolder, false);

#if UNITY_EDITOR
            if (buildSettings.SaveMeshesAsAssets)
            {
                // Make sure the folder exists to save into
                string path = SceneManager.GetActiveScene().path;
                path = Path.Combine(Path.GetDirectoryName(path), Path.GetFileNameWithoutExtension(path));
                if (!Directory.Exists(path))
                {
                    UnityEditor.AssetDatabase.CreateFolder(Path.GetDirectoryName(path), Path.GetFileName(path));
                }
                // Save to a file rather than leaving it as a scene asset
                UnityEditor.AssetDatabase.CreateAsset(mesh, Path.Combine(path, "VisualMesh" + materialMeshDictionary.MeshCount + ".asset"));
            }
#endif

            materialMeshDictionary.Add(material, mesh, newGameObject);
        }
        internal static void FinalizeVisualMesh(Transform meshGroupHolder,
                                                Mesh mesh,
                                                Material material,
                                                CSGBuildSettings buildSettings,
                                                CSGBuildContext.BuildContext buildContext,
                                                List <Vector3> positionsList,
                                                List <Vector3> normalsList,
                                                List <Vector2> uvList,
                                                List <Color> colorsList,
                                                List <int> trianglesList,
                                                MaterialMeshDictionary materialMeshDictionary)
        {
            Vector3[] positionsArray = new Vector3[positionsList.Count];
            Vector3[] normalsArray   = new Vector3[normalsList.Count];
            Vector2[] uvArray        = new Vector2[uvList.Count];
            Color[]   colorsArray    = new Color[colorsList.Count];
            int[]     trianglesArray = new int[trianglesList.Count];

            positionsList.CopyTo(positionsArray);
            normalsList.CopyTo(normalsArray);
            uvList.CopyTo(uvArray);
            trianglesList.CopyTo(trianglesArray);
            colorsList.CopyTo(colorsArray);

            mesh.vertices = positionsArray;
            mesh.normals  = normalsArray;
            mesh.uv       = uvArray;
            mesh.colors   = colorsArray;


            if (meshGroupHolder.position != Vector3.zero ||
                meshGroupHolder.rotation != Quaternion.identity ||
                meshGroupHolder.lossyScale != Vector3.one)
            {
                mesh.LocalizeToTransform(meshGroupHolder);
            }

            mesh.triangles = trianglesArray;

            if (buildSettings.GenerateTangents)
            {
                // Generate tangents, necessary for some shaders
                mesh.GenerateTangents();
            }

            buildContext.buildMetrics.TotalMeshes++;
            buildContext.buildMetrics.TotalVertices  += positionsArray.Length;
            buildContext.buildMetrics.TotalTriangles += trianglesArray.Length / 3;

            GameObject newGameObject = new GameObject("MaterialMesh");

            // Allow any editor dependent code to fire, e.g. lightmap unwrapping, static flags
            if (OnFinalizeVisualMesh != null)
            {
                OnFinalizeVisualMesh(newGameObject, mesh);
            }


            newGameObject.AddComponent <MeshFilter>().sharedMesh       = mesh;
            newGameObject.AddComponent <MeshRenderer>().sharedMaterial = material;
//			newGameObject.transform.parent = meshGroupHolder;
            newGameObject.transform.SetParent(meshGroupHolder, false);

            materialMeshDictionary.Add(material, mesh, newGameObject);
        }