public static void Build(DynamicMeshGenericMultiMaterialMesh _mesh, BuildrData _data)
    {
        switch (_data.generateCollider)
        {
        case BuildrData.ColliderGenerationModes.None:
            return;

//                break;

        case BuildrData.ColliderGenerationModes.Simple:
            BuildSimple(_mesh, _data);
            break;

        case BuildrData.ColliderGenerationModes.Complex:
            BuildrBuilding.Build(_mesh, _data);
            BuildrRoof.Build(_mesh, _data);
            int numberOfVolumes = _data.plan.numberOfVolumes;
            for (int v = 0; v < numberOfVolumes; v++)
            {
                BuildrInteriors.Build(_mesh, _data, v);
                BuildrStairs.Build(_mesh, _data, v, BuildrStairs.StairModes.Flat, false);
            }
            _mesh.CollapseSubmeshes();
            break;
        }
    }
Beispiel #2
0
    public static void Build(DynamicMeshGenericMultiMaterialMesh _mesh, BuildrData _data)
    {
        //        timestart = Time.realtimeSinceStartup;
        data     = _data;
        mesh     = _mesh;
        textures = data.textures.ToArray();
        BuildrPlan plan = data.plan;

//        int facadeIndex = 0;
        numberOfFacades = 0;
        int numberOfVolumes = data.plan.numberOfVolumes;

        //define rectangles that represent the facades
        packedTexturePositions.Clear();
        for (int v = 0; v < numberOfVolumes; v++)
        {
            BuildrVolume volume = plan.volumes[v];
            int          numberOfVolumePoints = volume.points.Count;

            for (int f = 0; f < numberOfVolumePoints; f++)
            {
                if (!volume.renderFacade[f])
                {
                    continue;
                }
                int      indexA = f;
                int      indexB = (f < numberOfVolumePoints - 1) ? f + 1 : 0;
                Vector2z p0     = plan.points[volume.points[indexA]];
                Vector2z p1     = plan.points[volume.points[indexB]];

                float facadeWidth = Vector2z.Distance(p0, p1) * PIXELS_PER_METER;
                int   floorBase   = plan.GetFacadeFloorHeight(v, volume.points[indexA], volume.points[indexB]);

                int numberOfFloors = volume.numberOfFloors - floorBase;
                if (numberOfFloors < 1)//no facade - adjacent facade is taller and covers this one
                {
                    continue;
                }

                float floorHeight  = data.floorHeight;
                float facadeHeight = (volume.numberOfFloors - floorBase) * floorHeight * PIXELS_PER_METER;
                if (facadeHeight < 0)
                {
                    facadeWidth  = 0;
                    facadeHeight = 0;
                }

                Rect newFacadeRect = new Rect(0, 0, facadeWidth, facadeHeight);
                packedTexturePositions.Add(newFacadeRect);

                numberOfFacades++;
            }
        }

        //Build ROOF
        DynamicMeshGenericMultiMaterialMesh dynMeshRoof = new DynamicMeshGenericMultiMaterialMesh();

        dynMeshRoof.name         = "Roof Mesh";
        dynMeshRoof.subMeshCount = textures.Length;
        BuildrRoof.Build(dynMeshRoof, data, true);
        dynMeshRoof.CheckMaxTextureUVs(data);

        roofTextures.Clear();
        roofTextureIndex.Clear();
        foreach (BuildrRoofDesign roofDesign in data.roofs)
        {
            foreach (int textureIndex in roofDesign.textureValues)
            {
                if (!roofTextureIndex.Contains(textureIndex))
                {
                    BuildrTexture bTexture = data.textures[textureIndex];
                    Vector2       largestSubmeshPlaneSize = new Vector2(1, 1);
                    Vector2       minWorldUvSize          = dynMeshRoof.MinWorldUvSize(textureIndex);
                    Vector2       maxWorldUvSize          = dynMeshRoof.MaxWorldUvSize(textureIndex);
                    largestSubmeshPlaneSize.x = maxWorldUvSize.x - minWorldUvSize.x;
                    largestSubmeshPlaneSize.y = maxWorldUvSize.y - minWorldUvSize.y;
                    int  roofTextureWidth    = Mathf.RoundToInt(largestSubmeshPlaneSize.x * PIXELS_PER_METER);
                    int  roofTextureHeight   = Mathf.RoundToInt(largestSubmeshPlaneSize.y * PIXELS_PER_METER);
                    Rect newRoofTexutureRect = new Rect(0, 0, roofTextureWidth, roofTextureHeight);
                    packedTexturePositions.Add(newRoofTexutureRect);
                    roofTextures.Add(bTexture);
                    roofTextureIndex.Add(textureIndex);
                }
            }
        }

        //run a custom packer to define their postions
        textureWidth = RectanglePack.Pack(packedTexturePositions, ATLAS_PADDING);

        //determine the resize scale and apply that to the rects
        packedScale = 1;
        int numberOfRects = packedTexturePositions.Count;

        if (textureWidth > MAXIMUM_TEXTURESIZE)
        {
            packedScale = MAXIMUM_TEXTURESIZE / (float)textureWidth;
            for (int i = 0; i < numberOfRects; i++)
            {
                Rect thisRect = packedTexturePositions[i];
                thisRect.x               *= packedScale;
                thisRect.y               *= packedScale;
                thisRect.width           *= packedScale;
                thisRect.height          *= packedScale;
                packedTexturePositions[i] = thisRect;
                //Debug.Log("Rects "+roofTextures[i-+packedTexturePositions[i]);
            }
            textureWidth = Mathf.RoundToInt(packedScale * textureWidth);
        }
        else
        {
            textureWidth = (int)Mathf.Pow(2, (Mathf.FloorToInt(Mathf.Log(textureWidth - 1, 2)) + 1));//find the next power of two
        }

        textureSize = textureWidth * textureWidth;
        colourArray = new Color32[textureSize];
        //TestRectColours();//this test paints all the facades with rainbow colours - real pretty
        BuildTextures();

        Texture2D packedTexture = new Texture2D(textureWidth, textureWidth, TextureFormat.ARGB32, true);

        packedTexture.filterMode = FilterMode.Bilinear;
        packedTexture.SetPixels32(colourArray);
        packedTexture.Apply(true, false);

        if (data.OneDrawCallTexture != null)
        {
            Object.DestroyImmediate(data.OneDrawCallTexture);
        }
        data.OneDrawCallTexture      = packedTexture;
        data.OneDrawCallTexture.name = "One Draw Call Texture";

        int         numberOfRoofTextures   = roofTextures.Count - 1;
        List <Rect> facadeTexturePositions = new List <Rect>(packedTexturePositions);

        Debug.Log(numberOfRoofTextures);
        facadeTexturePositions.RemoveRange(packedTexturePositions.Count - numberOfRoofTextures, numberOfRoofTextures);

        BuildrBuilding.Build(mesh, data, facadeTexturePositions.ToArray());

        data     = null;
        mesh     = null;
        textures = null;


        System.GC.Collect();
    }
Beispiel #3
0
    public void UpdateRender(renderModes _mode)
    {
        if (data.plan == null)
        {
            return;
        }
        if (data.floorHeight == 0)
        {
            return;
        }
        if (fullMesh == null)
        {
            fullMesh = new DynamicMeshGenericMultiMaterialMesh();
        }

        fullMesh.Clear();
        fullMesh.subMeshCount = data.textures.Count;

        foreach (DynamicMeshGenericMultiMaterialMesh intMesh in interiorMeshes)
        {
            intMesh.Clear();
        }

        switch (_mode)
        {
        case renderModes.full:
            BuildrBuilding.Build(fullMesh, data);
            BuildrRoof.Build(fullMesh, data);
            break;

        case renderModes.lowDetail:
            BuildrBuildingLowDetail2.Build(fullMesh, data);
            fullMesh.CollapseSubmeshes();
            break;

        case renderModes.box:
            BuildrBuildingBox.Build(fullMesh, data);
            break;
        }

        fullMesh.Build(false);

        while (meshHolders.Count > 0)
        {
            GameObject destroyOld = meshHolders[0];
            meshHolders.RemoveAt(0);
            DestroyImmediate(destroyOld);
        }

        int numberOfMeshes = fullMesh.meshCount;

        for (int i = 0; i < numberOfMeshes; i++)
        {
            GameObject newMeshHolder = new GameObject("model " + (i + 1));
            newMeshHolder.transform.parent        = transform;
            newMeshHolder.transform.localPosition = Vector3.zero;
            meshFilt      = newMeshHolder.AddComponent <MeshFilter>();
            meshRend      = newMeshHolder.AddComponent <MeshRenderer>();
            meshFilt.mesh = fullMesh[i].mesh;
            meshHolders.Add(newMeshHolder);
        }

        while (interiorMeshHolders.Count > 0)
        {
            GameObject destroyOld = interiorMeshHolders[0];
            interiorMeshHolders.RemoveAt(0);
            DestroyImmediate(destroyOld);
        }

        switch (_mode)
        {
        case renderModes.full:
            UpdateInteriors();
            UpdateTextures();
            break;

        case renderModes.lowDetail:
            meshRend.sharedMaterials = new Material[0];
            lowDetailMat.mainTexture = data.LODTextureAtlas;
            meshRend.sharedMaterial  = lowDetailMat;
            break;

        case renderModes.box:
            meshRend.sharedMaterials = new Material[0];
            lowDetailMat.mainTexture = data.textures[0].texture;
            meshRend.sharedMaterial  = lowDetailMat;
            break;
        }
    }
Beispiel #4
0
    private static void ExportModel(BuildrData data)
    {
        try
        {
            EditorUtility.DisplayCancelableProgressBar(PROGRESSBAR_TEXT, "", 0.0f);

            //check overwrites...
            string newDirectory = ROOT_FOLDER + data.exportFilename;
            if (!CreateFolder(newDirectory))
            {
                EditorUtility.ClearProgressBar();
                return;
            }

            EditorUtility.DisplayCancelableProgressBar(PROGRESSBAR_TEXT, "", 0.05f);
            if (data.fullmesh)
            {
                //export unpacked model
                DYN_MESH = new DynamicMeshGenericMultiMaterialMesh();
                DYN_MESH.subMeshCount = data.textures.Count;
                BuildrBuilding.Build(DYN_MESH, data);
                EditorUtility.DisplayCancelableProgressBar(PROGRESSBAR_TEXT, "", 0.30f);
                BuildrRoof.Build(DYN_MESH, data);
                EditorUtility.DisplayCancelableProgressBar(PROGRESSBAR_TEXT, "", 0.60f);
                DYN_MESH.Build(data.includeTangents);
                int meshCount = DYN_MESH.meshCount;


                List <int>            unusedTextures           = DYN_MESH.unusedSubmeshes;
                int                   numberOfUnpackedTextures = data.textures.Count;
                List <ExportMaterial> exportTextureList        = new List <ExportMaterial>();
                for (int t = 0; t < numberOfUnpackedTextures; t++)
                {
                    if (unusedTextures.Contains(t))
                    {
                        continue;//skip, unused
                    }
                    ExportMaterial newTexture = new ExportMaterial();
                    newTexture.name      = data.textures[t].name;
                    newTexture.material  = data.textures[t].material;
                    newTexture.generated = false;
                    newTexture.filepath  = data.textures[t].filePath;
                    exportTextureList.Add(newTexture);
                }
                for (int i = 0; i < meshCount; i++)
                {
                    EXPORT_MESH = DYN_MESH[i].mesh;
                    MeshUtility.Optimize(EXPORT_MESH);
                    Export(data, EXPORT_MESH, exportTextureList.ToArray());
                    string filenameSuffix = (meshCount > 1)? i.ToString() : "";
                    string filename       = data.exportFilename + filenameSuffix;
                    Export(filename, ROOT_FOLDER + data.exportFilename + "/", data, EXPORT_MESH, exportTextureList.ToArray());
                }
            }

            //Export Collider
            if (data.generateCollider != BuildrData.ColliderGenerationModes.None)
            {
                ExportCollider(data);
            }

            int[] numberOfInteriorMeshes = new int[data.plan.numberOfVolumes];
            if (data.renderInteriors && data.fullmesh)
            {
                numberOfInteriorMeshes = ExportInteriors(data);
            }

            int[] numberOfStairwells = new int[data.plan.numberOfVolumes];
            if (data.renderInteriors && data.fullmesh)
            {
                numberOfStairwells = ExportStairwells(data);
            }

            int numberOfDetailMeshes = 0;
            if (data.fullmesh)
            {
                numberOfDetailMeshes = ExportDetails(data);
            }

            EditorUtility.DisplayCancelableProgressBar(PROGRESSBAR_TEXT, "", 0.70f);

            //Place exported version into scene
            if (data.fullmesh)
            {
                AssetDatabase.Refresh();//ensure the database is up to date...
                GameObject baseObject = new GameObject(data.exportFilename);
                if ((data.createPrefabOnExport || data.placeIntoScene))
                {
                    baseObject.transform.position = CURRENT_TRANSFORM.position;
                    baseObject.transform.rotation = CURRENT_TRANSFORM.rotation;

                    string     modelFilePath = ROOT_FOLDER + data.exportFilename + "/" + data.exportFilename + FILE_EXTENTION;
                    GameObject newModel      = (GameObject)PrefabUtility.InstantiatePrefab(AssetDatabase.LoadMainAssetAtPath(modelFilePath));
                    newModel.name                    = "model";
                    newModel.transform.parent        = baseObject.transform;
                    newModel.transform.localPosition = Vector3.zero;
                    newModel.transform.localRotation = Quaternion.identity;
                    if (data.generateCollider != BuildrData.ColliderGenerationModes.None)
                    {
                        GameObject colliderObject   = new GameObject("collider");
                        string     colliderFilePath = ROOT_FOLDER + data.exportFilename + "/" + data.exportFilename + COLLIDER_SUFFIX + FILE_EXTENTION;
                        colliderObject.AddComponent <MeshCollider>().sharedMesh = (Mesh)AssetDatabase.LoadAssetAtPath(colliderFilePath, typeof(Mesh));
                        colliderObject.transform.parent        = baseObject.transform;
                        colliderObject.transform.localPosition = Vector3.zero;
                        colliderObject.transform.localRotation = Quaternion.identity;
                    }

                    for (int i = 0; i < numberOfDetailMeshes; i++)
                    {
                        string     detailSuffixIndex = ((numberOfDetailMeshes > 1) ? "_" + i : "");
                        string     detailFileName    = data.exportFilename + DETAIL_SUFFIX + detailSuffixIndex;
                        string     detailFolder      = ROOT_FOLDER + data.exportFilename + "/";
                        string     detailFilepath    = detailFolder + detailFileName + FILE_EXTENTION;
                        GameObject detailObject      = (GameObject)PrefabUtility.InstantiatePrefab(AssetDatabase.LoadMainAssetAtPath(detailFilepath));
                        detailObject.name                    = "details";
                        detailObject.transform.parent        = baseObject.transform;
                        detailObject.transform.localPosition = Vector3.zero;
                        detailObject.transform.localRotation = Quaternion.identity;
                    }

                    int        numberOfVolumes = data.plan.numberOfVolumes;
                    GameObject interiorHolder  = new GameObject("interiors");
                    interiorHolder.transform.parent        = baseObject.transform;
                    interiorHolder.transform.localPosition = Vector3.zero;
                    interiorHolder.transform.localRotation = Quaternion.identity;
                    for (int v = 0; v < numberOfInteriorMeshes.Length; v++)
                    {
                        int numMeshes = numberOfInteriorMeshes[v];
                        for (int i = 0; i < numMeshes; i++)
                        {
                            string     VolumeSuffix      = ((numberOfVolumes > 1) ? "_" + v : "");
                            string     DetailSuffixIndex = ((numMeshes > 1) ? "_" + i : "");
                            string     DetailFileName    = data.exportFilename + INTERIOR_SUFFIX + VolumeSuffix + DetailSuffixIndex;
                            string     DetailFolder      = ROOT_FOLDER + data.exportFilename + "/";
                            string     filePath          = DetailFolder + DetailFileName + FILE_EXTENTION;
                            GameObject interiorObject    = (GameObject)PrefabUtility.InstantiatePrefab(AssetDatabase.LoadMainAssetAtPath(filePath));
                            interiorObject.name                    = INTERIOR_SUFFIX + VolumeSuffix + DetailSuffixIndex;
                            interiorObject.transform.parent        = interiorHolder.transform;
                            interiorObject.transform.localPosition = Vector3.zero;
                            interiorObject.transform.localRotation = Quaternion.identity;
                        }
                    }

                    for (int v = 0; v < numberOfStairwells.Length; v++)
                    {
                        int numMeshes = numberOfStairwells[v];
                        for (int i = 0; i < numMeshes; i++)
                        {
                            string     VolumeSuffix      = ((numberOfVolumes > 1) ? "_" + v : "");
                            string     DetailSuffixIndex = ((numMeshes > 1) ? "_" + i : "");
                            string     DetailFileName    = data.exportFilename + STAIR_SUFFIX + VolumeSuffix + DetailSuffixIndex;
                            string     DetailFolder      = ROOT_FOLDER + data.exportFilename + "/";
                            string     filePath          = DetailFolder + DetailFileName + FILE_EXTENTION;
                            GameObject interiorObject    = (GameObject)PrefabUtility.InstantiatePrefab(AssetDatabase.LoadMainAssetAtPath(filePath));
                            interiorObject.name                    = STAIR_SUFFIX + VolumeSuffix + DetailSuffixIndex;
                            interiorObject.transform.parent        = interiorHolder.transform;
                            interiorObject.transform.localPosition = data.plan.volumes[v].stairBaseVector[i];
                            interiorObject.transform.localRotation = Quaternion.identity;
                        }
                    }
                }

                if (data.createPrefabOnExport)
                {
                    string prefabPath = ROOT_FOLDER + data.exportFilename + "/" + data.exportFilename + ".prefab";
                    Object prefab     = AssetDatabase.LoadAssetAtPath(prefabPath, typeof(GameObject));
                    if (prefab == null)
                    {
                        prefab = PrefabUtility.CreateEmptyPrefab(prefabPath);
                    }
                    PrefabUtility.ReplacePrefab(baseObject, prefab, ReplacePrefabOptions.ConnectToPrefab);
                }

                if (!data.placeIntoScene)
                {
                    Object.DestroyImmediate(baseObject);
                }
            }

            if (data.exportLowLOD)
            {
                ExportLowLOD(data);
            }

            DYN_MESH    = null;
            EXPORT_MESH = null;

            EditorUtility.ClearProgressBar();
            EditorUtility.UnloadUnusedAssets();

            AssetDatabase.Refresh();
        }catch (System.Exception e)
        {
            Debug.LogError("BuildR Export Error: " + e);
            EditorUtility.ClearProgressBar();
        }
    }