Ejemplo n.º 1
0
    private static void ExportCollider(BuildrData data)
    {
        DynamicMeshGenericMultiMaterialMesh COL_MESH = new DynamicMeshGenericMultiMaterialMesh();

        COL_MESH.subMeshCount = data.textures.Count;
        BuildrBuildingCollider.Build(COL_MESH, data);
//        COL_MESH.CollapseSubmeshes();
        COL_MESH.Build(false);

        ExportMaterial[] exportTextures = new ExportMaterial[1];
        ExportMaterial   newTexture     = new ExportMaterial();

        newTexture.name      = "blank";
        newTexture.filepath  = "";
        newTexture.generated = true;
        exportTextures[0]    = newTexture;

        int numberOfColliderMeshes = COL_MESH.meshCount;

        for (int i = 0; i < numberOfColliderMeshes; i++)
        {
            MeshUtility.Optimize(COL_MESH[i].mesh);
            string ColliderSuffixIndex = ((numberOfColliderMeshes > 1) ? "_" + i : "");
            string ColliderFileName    = data.exportFilename + COLLIDER_SUFFIX + ColliderSuffixIndex;
            string ColliderFolder      = ROOT_FOLDER + data.exportFilename + "/";
            Export(ColliderFileName, ColliderFolder, data, COL_MESH[i].mesh, exportTextures);
        }
    }
Ejemplo n.º 2
0
    public void UpdateCollider()
    {
        if (data.generateCollider != BuildrData.ColliderGenerationModes.None)
        {
            if (data.floorHeight == 0)
            {
                return;
            }
            if (colliderMesh == null)
            {
                colliderMesh = new DynamicMeshGenericMultiMaterialMesh();
            }

            colliderMesh.Clear();
            colliderMesh.subMeshCount = 1;
            BuildrBuildingCollider.Build(colliderMesh, data);
            colliderMesh.Build(false);

            int numberOfStairMeshes = colliderMesh.meshCount;
            for (int i = 0; i < numberOfStairMeshes; i++)
            {
                string meshName = "collider";
                if (numberOfStairMeshes > 1)
                {
                    meshName += " mesh " + (i + 1);
                }
                GameObject newMeshHolder = new GameObject(meshName);
                newMeshHolder.transform.parent = transform;
                meshFilt      = newMeshHolder.AddComponent <MeshFilter>();
                meshRend      = newMeshHolder.AddComponent <MeshRenderer>();
                meshFilt.mesh = colliderMesh[i].mesh;
                colliderHolders.Add(newMeshHolder);
            }
        }
    }
Ejemplo n.º 3
0
    private static int[] ExportStairwells(BuildrData data)
    {
        int numberOfVolumes = data.plan.numberOfVolumes;

        int[] returnNumberOfMeshes = new int[numberOfVolumes];

        for (int v = 0; v < numberOfVolumes; v++)
        {
            BuildrVolume volume = data.plan.volumes[v];

            int numberOfUnpackedTextures         = data.textures.Count;
            List <ExportMaterial> exportTextures = new List <ExportMaterial>();

            if (!volume.generateStairs)
            {
                continue;
            }
            DynamicMeshGenericMultiMaterialMesh INT_STAIRWELL = new DynamicMeshGenericMultiMaterialMesh();
            INT_STAIRWELL.subMeshCount = data.textures.Count;
            BuildrStairs.Build(INT_STAIRWELL, data, v, BuildrStairs.StairModes.Stepped, true);
            INT_STAIRWELL.Build(data.includeTangents);

            List <int> unusedStairTextures = INT_STAIRWELL.unusedSubmeshes;
            numberOfUnpackedTextures = data.textures.Count;
            for (int t = 0; t < numberOfUnpackedTextures; t++)
            {
                if (unusedStairTextures.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;
                exportTextures.Add(newTexture);
            }

            int numberOfStairMeshes = INT_STAIRWELL.meshCount;
            for (int i = 0; i < numberOfStairMeshes; i++)
            {
                MeshUtility.Optimize(INT_STAIRWELL[i].mesh);
                string VolumeSuffix      = ((numberOfVolumes > 1) ? "_" + v : "");
                string DetailSuffixIndex = ((numberOfStairMeshes > 1) ? "_" + i : "");
                string DetailFileName    = data.exportFilename + STAIR_SUFFIX + VolumeSuffix + DetailSuffixIndex;
                string DetailFolder      = ROOT_FOLDER + data.exportFilename + "/";
                Export(DetailFileName, DetailFolder, data, INT_STAIRWELL[i].mesh, exportTextures.ToArray());
            }

            returnNumberOfMeshes[v] = numberOfStairMeshes;
        }

        return(returnNumberOfMeshes);
    }
Ejemplo n.º 4
0
    public void UpdateInteriors()
    {
        while (interiorMeshHolders.Count > 0)
        {
            GameObject destroyOld = interiorMeshHolders[0];
            interiorMeshHolders.RemoveAt(0);
            DestroyImmediate(destroyOld);
        }

        interiorMeshes.Clear();

        if (data.renderInteriors)
        {
            int numberOfVolumes = data.plan.numberOfVolumes;
            for (int v = 0; v < numberOfVolumes; v++)
            {
                DynamicMeshGenericMultiMaterialMesh interiorMesh = new DynamicMeshGenericMultiMaterialMesh();
                interiorMesh.subMeshCount = data.textures.Count;
                BuildrInteriors.Build(interiorMesh, data, v);
                interiorMesh.Build(false);

                int numberOfInteriorMeshes = interiorMesh.meshCount;
                for (int i = 0; i < numberOfInteriorMeshes; i++)
                {
                    string meshName = "model interior";
                    if (numberOfVolumes > 0)
                    {
                        meshName += " volume " + (v + 1);
                    }
                    if (numberOfInteriorMeshes > 1)
                    {
                        meshName += " mesh " + (i + 1);
                    }
                    GameObject newMeshHolder = new GameObject(meshName);
                    newMeshHolder.transform.parent        = transform;
                    newMeshHolder.transform.localPosition = Vector3.zero;
                    meshFilt      = newMeshHolder.AddComponent <MeshFilter>();
                    meshRend      = newMeshHolder.AddComponent <MeshRenderer>();
                    meshFilt.mesh = interiorMesh[i].mesh;
                    interiorMeshHolders.Add(newMeshHolder);
                }
            }
        }
    }
Ejemplo n.º 5
0
    private static void ExportLowLOD(BuildrData data)
    {
        DynamicMeshGenericMultiMaterialMesh dynLODMesh = new DynamicMeshGenericMultiMaterialMesh();

        dynLODMesh.subMeshCount = data.textures.Count;
        BuildrBuildingLowDetail2.Build(dynLODMesh, data);
        dynLODMesh.CollapseSubmeshes();
        EditorUtility.DisplayCancelableProgressBar(PROGRESSBAR_TEXT, "", 0.80f);
        dynLODMesh.Build(data.includeTangents);
        Mesh LODMesh = dynLODMesh[0].mesh;//TODO: support many meshes

        MeshUtility.Optimize(LODMesh);
        EditorUtility.DisplayCancelableProgressBar(PROGRESSBAR_TEXT, "", 0.90f);

        string textureName     = data.exportFilename + ATLASED_SUFFIX + LOD_SUFFIX;
        string textureFileName = textureName + ".png";
        string newDirectory    = ROOT_FOLDER + data.exportFilename;

        File.WriteAllBytes(newDirectory + "/" + textureFileName, data.LODTextureAtlas.EncodeToPNG());
        ExportMaterial[] exportTextures = new ExportMaterial[1];
        ExportMaterial   newTexture     = new ExportMaterial();

        newTexture.name      = textureName;
        newTexture.filepath  = textureFileName;
        newTexture.generated = true;
        exportTextures[0]    = newTexture;
        string LODFileName = data.exportFilename + LOD_SUFFIX;
        string LODFolder   = ROOT_FOLDER + data.exportFilename + "/";

        Export(LODFileName, LODFolder, data, LODMesh, exportTextures);


        if (data.placeIntoScene)
        {
            AssetDatabase.Refresh();//ensure the database is up to date...
            string     filePath = LODFolder + LODFileName + FILE_EXTENTION;
            GameObject newModel = (GameObject)PrefabUtility.InstantiatePrefab(AssetDatabase.LoadMainAssetAtPath(filePath));
            newModel.transform.position = CURRENT_TRANSFORM.position;
            newModel.transform.rotation = CURRENT_TRANSFORM.rotation;
        }

        Texture2D.DestroyImmediate(data.textureAtlas);
        Texture2D.DestroyImmediate(data.LODTextureAtlas);
    }
Ejemplo n.º 6
0
    private static void ExportCollider(TrackBuildR data)
    {
        DynamicMeshGenericMultiMaterialMesh COL_MESH = new DynamicMeshGenericMultiMaterialMesh();

//        COL_MESH.subMeshCount = data.textures.Count;
//        BuildrBuildingCollider.Build(COL_MESH, data);
//        COL_MESH.CollapseSubmeshes();
        COL_MESH.Build(false);

        ExportMaterial[] exportTextures = new ExportMaterial[1];
        ExportMaterial   newTexture     = new ExportMaterial();

        newTexture.name      = "blank";
        newTexture.filepath  = "";
        newTexture.generated = true;
        exportTextures[0]    = newTexture;

        int numberOfColliderMeshes = COL_MESH.meshCount;

        for (int i = 0; i < numberOfColliderMeshes; i++)
        {
            MeshUtility.Optimize(COL_MESH[i].mesh);
            string ColliderSuffixIndex = ((numberOfColliderMeshes > 1) ? "_" + i : "");
            string ColliderFileName    = data.exportFilename + COLLIDER_SUFFIX + ColliderSuffixIndex;
            string ColliderFolder      = ROOT_FOLDER + data.exportFilename + "/";
            Export(ColliderFileName, ColliderFolder, data, COL_MESH[i].mesh, exportTextures);
        }

        //string newDirectory = rootFolder+track.exportFilename;
        //if(!CreateFolder(newDirectory))
        //	return;
//        ExportMaterial[] exportTextures = new ExportMaterial[1];
//        ExportMaterial newTexture = new ExportMaterial();
//        newTexture.customName = "";
//        newTexture.filepath = "";
//        newTexture.generated = true;
//        exportTextures[0] = newTexture;
//        Export(track.exportFilename + COLLIDER_SUFFIX, ROOT_FOLDER + track.exportFilename + "/", track, EXPORT_MESH, exportTextures);
//
//        COL_MESH = null;
//        EXPORT_MESH = null;
    }
    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();
        }
    }
    private static void ExportLowLOD(BuildrData data)
    {
        DynamicMeshGenericMultiMaterialMesh dynLODMesh = new DynamicMeshGenericMultiMaterialMesh();
        dynLODMesh.subMeshCount = data.textures.Count;
        BuildrBuildingLowDetail2.Build(dynLODMesh, data);
        dynLODMesh.CollapseSubmeshes();
        EditorUtility.DisplayCancelableProgressBar(PROGRESSBAR_TEXT, "", 0.80f);
        dynLODMesh.Build(data.includeTangents);
        Mesh LODMesh = dynLODMesh[0].mesh;//TODO: support many meshes
        MeshUtility.Optimize(LODMesh);
        EditorUtility.DisplayCancelableProgressBar(PROGRESSBAR_TEXT, "", 0.90f);

        string textureName = data.exportFilename + ATLASED_SUFFIX + LOD_SUFFIX;
        string textureFileName = textureName + ".png";
        string newDirectory = ROOT_FOLDER + data.exportFilename;

        File.WriteAllBytes(newDirectory + "/" + textureFileName, data.LODTextureAtlas.EncodeToPNG());
        ExportMaterial[] exportTextures = new ExportMaterial[1];
        ExportMaterial newTexture = new ExportMaterial();
        newTexture.name = textureName;
        newTexture.filepath = textureFileName;
        newTexture.generated = true;
        exportTextures[0] = newTexture;
        string LODFileName = data.exportFilename + LOD_SUFFIX;
        string LODFolder = ROOT_FOLDER + data.exportFilename + "/";
        Export(LODFileName, LODFolder, data, LODMesh, exportTextures);

        if (data.placeIntoScene)
        {
            AssetDatabase.Refresh();//ensure the database is up to date...
            string filePath = LODFolder + LODFileName + FILE_EXTENTION;
            GameObject newModel = (GameObject)PrefabUtility.InstantiatePrefab(AssetDatabase.LoadMainAssetAtPath(filePath));
            newModel.transform.position = CURRENT_TRANSFORM.position;
            newModel.transform.rotation = CURRENT_TRANSFORM.rotation;
        }

        Texture2D.DestroyImmediate(data.textureAtlas);
        Texture2D.DestroyImmediate(data.LODTextureAtlas);
    }
    private static void ExportCollider(BuildrData data)
    {
        DynamicMeshGenericMultiMaterialMesh COL_MESH = new DynamicMeshGenericMultiMaterialMesh();
        COL_MESH.subMeshCount = data.textures.Count;
        BuildrBuildingCollider.Build(COL_MESH, data);
        //        COL_MESH.CollapseSubmeshes();
        COL_MESH.Build(false);

        ExportMaterial[] exportTextures = new ExportMaterial[1];
        ExportMaterial newTexture = new ExportMaterial();
        newTexture.name = "blank";
        newTexture.filepath = "";
        newTexture.generated = true;
        exportTextures[0] = newTexture;

        int numberOfColliderMeshes = COL_MESH.meshCount;
        for (int i = 0; i < numberOfColliderMeshes; i++)
        {
            MeshUtility.Optimize(COL_MESH[i].mesh);
            string ColliderSuffixIndex = ((numberOfColliderMeshes > 1) ? "_" + i : "");
            string ColliderFileName = data.exportFilename + COLLIDER_SUFFIX + ColliderSuffixIndex;
            string ColliderFolder = ROOT_FOLDER + data.exportFilename + "/";
            Export(ColliderFileName, ColliderFolder, data, COL_MESH[i].mesh, exportTextures);
        }
    }
Ejemplo n.º 10
0
    public void UpdateInteriors()
    {
        while (interiorMeshHolders.Count > 0)
        {
            GameObject destroyOld = interiorMeshHolders[0];
            interiorMeshHolders.RemoveAt(0);
            DestroyImmediate(destroyOld);
        }

        interiorMeshes.Clear();

        if (data.renderInteriors)
        {
            int numberOfVolumes = data.plan.numberOfVolumes;
            for (int v = 0; v < numberOfVolumes; v++)
            {
                DynamicMeshGenericMultiMaterialMesh interiorMesh = new DynamicMeshGenericMultiMaterialMesh();
                interiorMesh.subMeshCount = data.textures.Count;
                BuildrInteriors.Build(interiorMesh, data, v);
                interiorMesh.Build(false);

                int numberOfInteriorMeshes = interiorMesh.meshCount;
                for (int i = 0; i < numberOfInteriorMeshes; i++)
                {
                    string meshName = "model interior";
                    if (numberOfVolumes > 0) meshName += " volume " + (v + 1);
                    if (numberOfInteriorMeshes > 1) meshName += " mesh " + (i + 1);
                    GameObject newMeshHolder = new GameObject(meshName);
                    newMeshHolder.transform.parent = transform;
                    newMeshHolder.transform.localPosition = Vector3.zero;
                    meshFilt = newMeshHolder.AddComponent<MeshFilter>();
                    meshRend = newMeshHolder.AddComponent<MeshRenderer>();
                    meshFilt.mesh = interiorMesh[i].mesh;
                    interiorMeshHolders.Add(newMeshHolder);
                }
            }
        }
    }
Ejemplo n.º 11
0
    public void UpdateRender()
    {
        if (track.numberOfCurves == 0)
        {
            return;
        }

        track.RecalculateCurves();
        float trackMeshRes = track.meshResolution;

        float bumperDistanceA = 0;
        float bumperDistanceB = 0;


        int   numberOfCurves = track.numberOfCurves;
        bool  renderTrack    = track.render;
        float UVOffset       = 0;
        int   polyCount      = 0;

        for (int i = 0; i < numberOfCurves; i++)
        {
            TrackBuildRPoint curve = track[i];

            DynamicMeshGenericMultiMaterialMesh dynamicTrackMesh    = curve.dynamicTrackMesh;
            DynamicMeshGenericMultiMaterialMesh dynamicBoundaryMesh = curve.dynamicBoundaryMesh;
            DynamicMeshGenericMultiMaterialMesh dynamicOffroadMesh  = curve.dynamicOffroadMesh;
            DynamicMeshGenericMultiMaterialMesh dynamicBumperMesh   = curve.dynamicBumperMesh;
            DynamicMeshGenericMultiMaterialMesh dynamicColliderMesh = curve.dynamicColliderMesh;
            DynamicMeshGenericMultiMaterialMesh dynamicBottomMesh   = curve.dynamicBottomMesh;

            if (!curve.render || !renderTrack)
            {
                dynamicTrackMesh.Clear();
                dynamicBoundaryMesh.Clear();
                dynamicColliderMesh.Clear();
                dynamicOffroadMesh.Clear();
                dynamicBumperMesh.Clear();
                dynamicBottomMesh.Clear();
            }

            if (curve.shouldReRender && curve.render && renderTrack)
            {
                dynamicTrackMesh.Clear();
                dynamicTrackMesh.subMeshCount = 1;
                dynamicBoundaryMesh.Clear();
                dynamicBoundaryMesh.subMeshCount = 1;
                dynamicColliderMesh.Clear();
                dynamicColliderMesh.subMeshCount = 1;
                dynamicOffroadMesh.Clear();
                dynamicOffroadMesh.subMeshCount = 1;
                dynamicBumperMesh.Clear();
                dynamicBumperMesh.subMeshCount = 1;
                dynamicBottomMesh.Clear();
                dynamicBottomMesh.subMeshCount = 1;

                dynamicTrackMesh.name    = "curve " + i + " track mesh";
                dynamicBoundaryMesh.name = "curve " + i + " boundary mesh";
                dynamicColliderMesh.name = "curve " + i + " trackCollider mesh";
                dynamicOffroadMesh.name  = "curve " + i + " offroad mesh";
                dynamicBumperMesh.name   = "curve " + i + " bumper mesh";
                dynamicBottomMesh.name   = "curve " + i + " bottom mesh";

                bool trackTextureFlip    = (track.numberOfTextures > 0) ? track.Texture(curve.trackTextureStyleIndex).flipped : false;
                bool boundaryTextureFlip = (track.numberOfTextures > 0) ? track.Texture(curve.boundaryTextureStyleIndex).flipped : false;
                bool bumperTextureFlip   = (track.numberOfTextures > 0) ? track.Texture(curve.bumperTextureStyleIndex).flipped : false;
                bool bottomTextureFlip   = (track.numberOfTextures > 0) ? track.Texture(curve.bottomTextureStyleIndex).flipped : false;

                int   storedPointSize = curve.storedPointSize;
                float curveLength     = curve.arcLength;
                //Store these points so we can use previous values when Bezier clips itself
                Vector3 leftPointA  = curve.sampledLeftBoundaryPoints[0];
                Vector3 rightPointA = curve.sampledRightBoundaryPoints[0];
                Vector3 leftPointB  = curve.sampledLeftBoundaryPoints[0];
                Vector3 rightPointB = curve.sampledRightBoundaryPoints[0];
                for (int p = 0; p < storedPointSize - 1; p++)
                {
                    float   tA           = curve.normalisedT[p];
                    float   tB           = curve.normalisedT[p + 1];
                    int     sampleIndexA = p;
                    int     sampleIndexB = sampleIndexA + 1;
                    Vector3 pointA       = curve.sampledPoints[sampleIndexA];
                    Vector3 pointB       = curve.sampledPoints[sampleIndexB];
                    float   trackWidthA  = curve.sampledWidths[sampleIndexA] * 0.5f;
                    float   trackWidthB  = curve.sampledWidths[sampleIndexB] * 0.5f;
                    float   trackCrownA  = curve.sampledCrowns[sampleIndexA];
                    float   trackCrownB  = curve.sampledCrowns[sampleIndexB];
                    Vector3 trackUpA     = curve.sampledTrackUps[sampleIndexA];
                    Vector3 trackUpB     = curve.sampledTrackUps[sampleIndexB];
                    Vector3 trackCrossA  = curve.sampledTrackCrosses[sampleIndexA];
                    Vector3 trackCrossB  = curve.sampledTrackCrosses[sampleIndexB];
                    float   trackAngle   = curve.sampledAngles[sampleIndexA];

                    if (trackUpA == Vector3.zero || trackUpB == Vector3.zero)
                    {
                        return;
                    }

                    //TrackBuildRTexture texture = track.Texture(curve.trackTextureStyleIndex) ;// track.trackTexture;
                    int       pointANumber     = Mathf.Max(Mathf.CeilToInt(trackWidthA / trackMeshRes / 2) * 2, 2); //number of verts along line A
                    int       pointBNumber     = Mathf.Max(Mathf.CeilToInt(trackWidthB / trackMeshRes / 2) * 2, 2); //number of verts along line B
                    int       numberOfNewVerts = pointANumber + pointBNumber;
                    Vector3[] uncrownedVerts   = new Vector3[numberOfNewVerts];
                    if (curve.clipArrayLeft[sampleIndexA])
                    {
                        leftPointA = (pointA + (trackCrossA * -trackWidthA));
                    }
                    if (curve.clipArrayRight[sampleIndexA])
                    {
                        rightPointA = (pointA + (trackCrossA * trackWidthA));
                    }
                    float curveLengthA = (curveLength * tA) / trackWidthA + UVOffset;
                    float curveLengthB = (curveLength * tB) / trackWidthB + UVOffset;
                    float lerpASize    = 1.0f / (pointANumber - 1);

                    //track vertex/uv data for point nextNormIndex
                    Vector3[] newAPoints     = new Vector3[pointANumber];
                    Vector3[] newTrackPoints = new Vector3[pointANumber + pointBNumber];
                    Vector2[] newTrackUVs    = new Vector2[pointANumber + pointBNumber];
                    for (int pa = 0; pa < pointANumber; pa++)
                    {
                        float   lerpValue     = lerpASize * pa;
                        Vector3 crownVector   = Quaternion.LookRotation(trackUpA) * new Vector3(0, 0, Mathf.Sin(lerpValue * Mathf.PI) * trackCrownA);
                        Vector3 uncrownedVert = Vector3.Lerp(leftPointA, rightPointA, lerpValue);
                        uncrownedVerts[pa] = uncrownedVert;
                        Vector3 newVert = uncrownedVert + crownVector;
                        newAPoints[pa]     = newVert;
                        newTrackPoints[pa] = newVert;
                        Vector2 newUV = (!trackTextureFlip) ? new Vector2(lerpValue, curveLengthA) : new Vector2(curveLengthA, lerpValue);
                        newTrackUVs[pa] = newUV;
                    }

                    //track vertex/uv data for point prevNormIndex
                    if (curve.clipArrayLeft[sampleIndexB])
                    {
                        leftPointB = (pointB + (trackCrossB * -trackWidthB));
                    }
                    if (curve.clipArrayRight[sampleIndexB])
                    {
                        rightPointB = (pointB + (trackCrossB * trackWidthB));
                    }
                    float     lerpBSize  = 1.0f / (pointBNumber - 1);
                    Vector3[] newBPoints = new Vector3[pointBNumber];
                    for (int pb = 0; pb < pointBNumber; pb++)
                    {
                        float   lerpValue     = lerpBSize * pb;
                        Vector3 crownVector   = Quaternion.LookRotation(trackUpB) * new Vector3(0, 0, Mathf.Sin(lerpValue * Mathf.PI) * trackCrownB);
                        Vector3 uncrownedVert = Vector3.Lerp(leftPointB, rightPointB, lerpValue);
                        uncrownedVerts[pb + pointANumber] = uncrownedVert;
                        Vector3 newVert = uncrownedVert + crownVector;
                        newBPoints[pb] = newVert;
                        newTrackPoints[pb + pointANumber] = newVert;
                        Vector2 newUV = (!trackTextureFlip) ? new Vector2(lerpValue, curveLengthB) : new Vector2(curveLengthB, lerpValue);
                        newTrackUVs[pb + pointANumber] = newUV;
                    }
                    int   baseTriPointA     = 0;
                    int   baseTriPointB     = pointANumber;
                    int   triPointA         = baseTriPointA;
                    int   triPointB         = baseTriPointB;
                    int   newTriPointCountA = 1;
                    int   newTriPointCountB = 1;
                    int[] newTrackTris      = new int[(numberOfNewVerts - 2) * 3];
                    for (int v = 0; v < numberOfNewVerts - 2; v++)
                    {
                        int newTriPointA = baseTriPointA + newTriPointCountA;
                        int newTriPointB = baseTriPointB + newTriPointCountB;

                        float newTriPointADist, newTriPointBDist;
                        if (newTriPointA >= baseTriPointA + pointANumber)
                        {
                            newTriPointADist = float.PositiveInfinity;
                        }
                        else
                        {
                            newTriPointADist = Vector3.SqrMagnitude(uncrownedVerts[newTriPointA] - uncrownedVerts[baseTriPointA]);
                        }

                        if (newTriPointB >= baseTriPointB + pointBNumber)
                        {
                            newTriPointBDist = float.PositiveInfinity;
                        }
                        else
                        {
                            newTriPointBDist = Vector3.SqrMagnitude(uncrownedVerts[newTriPointB] - uncrownedVerts[baseTriPointB]);
                        }

                        if (newTriPointADist < newTriPointBDist)
                        {
                            newTrackTris[v * 3]     = triPointA;
                            newTrackTris[v * 3 + 1] = triPointB;
                            newTrackTris[v * 3 + 2] = newTriPointA;
                            triPointA = newTriPointA;
                            newTriPointCountA++;
                        }
                        else
                        {
                            newTrackTris[v * 3]     = triPointA;
                            newTrackTris[v * 3 + 1] = triPointB;
                            newTrackTris[v * 3 + 2] = newTriPointB;
                            triPointB = newTriPointB;
                            newTriPointCountB++;
                        }
                    }
                    dynamicTrackMesh.AddData(newTrackPoints, newTrackUVs, newTrackTris, 0);
                    dynamicColliderMesh.AddData(newTrackPoints, newTrackUVs, newTrackTris, 0);

                    //Boundary
                    float trackBoundaryWallHeight = curve.boundaryHeight;// track.boundaryHeight;

                    Vector3 leftBoundaryPointA, leftBoundaryPointB, rightBoundaryPointA, rightBoundaryPointB;
                    if (track.disconnectBoundary)
                    {
                        leftBoundaryPointA  = curve.sampledLeftBoundaryPoints[sampleIndexA];
                        leftBoundaryPointB  = curve.sampledLeftBoundaryPoints[sampleIndexB];
                        rightBoundaryPointA = curve.sampledRightBoundaryPoints[sampleIndexA];
                        rightBoundaryPointB = curve.sampledRightBoundaryPoints[sampleIndexB];
                    }
                    else
                    {
                        leftBoundaryPointA  = leftPointA;
                        leftBoundaryPointB  = leftPointB;
                        rightBoundaryPointA = rightPointA;
                        rightBoundaryPointB = rightPointB;
                    }

                    Vector3[] newWallVerts;
                    Vector2[] newWallUVs;
                    int[]     newWallTris;

                    //Boundary Render Mesh
                    if (curve.renderBounds)
                    {
                        //LEFT
                        newWallVerts = new[] { leftBoundaryPointA, leftBoundaryPointB, leftBoundaryPointA + trackUpA * trackBoundaryWallHeight, leftBoundaryPointB + trackUpB * trackBoundaryWallHeight };

                        if (!boundaryTextureFlip)
                        {
                            newWallUVs = new[] { new Vector2(curveLengthA, 0), new Vector2(curveLengthB, 0), new Vector2(curveLengthA, 1), new Vector2(curveLengthB, 1), }
                        }
                        ;
                        else
                        {
                            newWallUVs = new[] { new Vector2(1, curveLengthA), new Vector2(1, curveLengthB), new Vector2(0, curveLengthA), new Vector2(0, curveLengthB), }
                        };
                        newWallTris = new[] { 1, 0, 2, 1, 2, 3 };
                        //                    newWallTris = (boundaryTextureFlip) ? (new[] { 1, 0, 2, 1, 2, 3 }) : (new[] { 0,2,1,2,3,1 });
                        //                    newWallTris = (!track.renderBoundaryWallReverse) ? new[] { 1, 0, 2, 1, 2, 3 } : new[] { 1, 0, 2, 1, 2, 3, 0, 1, 2, 2, 1, 3 };
                        dynamicBoundaryMesh.AddData(newWallVerts, newWallUVs, newWallTris, 0);
                        if (track.renderBoundaryWallReverse)
                        {
                            newWallTris = new[] { 0, 1, 2, 2, 1, 3 };
                            //                        newWallTris = (boundaryTextureFlip) ? (new[] { 0, 1, 2, 2, 1, 3 }) : (new[] { 0, 2, 1, 2, 3, 1 });
                            dynamicBoundaryMesh.AddData(newWallVerts, newWallUVs, newWallTris, 0);
                        }

                        //RIGHT
                        newWallVerts = (new[] { rightBoundaryPointA, rightBoundaryPointB, rightBoundaryPointA + trackUpA * trackBoundaryWallHeight, rightBoundaryPointB + trackUpB * trackBoundaryWallHeight });
                        //newWallUVs = new[] { new Vector2(curveLengthA, 0), new Vector2(curveLengthB, 0), new Vector2(curveLengthA, 1), new Vector2(curveLengthB, 1), };
                        if (!boundaryTextureFlip)
                        {
                            newWallUVs = new[] { new Vector2(curveLengthA, 0), new Vector2(curveLengthB, 0), new Vector2(curveLengthA, 1), new Vector2(curveLengthB, 1), }
                        }
                        ;
                        else
                        {
                            newWallUVs = new[] { new Vector2(1, curveLengthA), new Vector2(1, curveLengthB), new Vector2(0, curveLengthA), new Vector2(0, curveLengthB), }
                        };

                        newWallTris = new[] { 0, 1, 2, 2, 1, 3 };
                        //newWallTris = (!track.renderBoundaryWallReverse) ? new[] { 0, 1, 2, 2, 1, 3 } : new[] { 1, 0, 2, 1, 2, 3, 0, 1, 2, 2, 1, 3 };
                        dynamicBoundaryMesh.AddData(newWallVerts, newWallUVs, newWallTris, 0);
                        if (track.renderBoundaryWallReverse)
                        {
                            newWallTris = new[] { 1, 0, 2, 1, 2, 3 };
                            dynamicBoundaryMesh.AddData(newWallVerts, newWallUVs, newWallTris, 0);
                        }
                    }

                    if (curve.trackCollider)
                    {
                        //COLLIDER walls for on track border
                        float trackColliderWallHeight = track.trackColliderWallHeight;
                        if (curve.colliderSides)
                        {
                            newWallVerts = (new[] { leftBoundaryPointA, leftBoundaryPointB, leftBoundaryPointA + trackUpA * trackColliderWallHeight, leftBoundaryPointB + trackUpB * trackColliderWallHeight });
                            newWallUVs   = (new[] { Vector2.zero, Vector2.zero, Vector2.zero, Vector2.zero });
                            newWallTris  = (new[] { 1, 0, 2, 1, 2, 3 });
                            dynamicColliderMesh.AddData(newWallVerts, newWallUVs, newWallTris, 0);
                            newWallVerts = (new[] { rightBoundaryPointA, rightBoundaryPointB, rightBoundaryPointA + trackUpA * trackColliderWallHeight, rightBoundaryPointB + trackUpB * trackColliderWallHeight });
                            newWallUVs   = (new[] { Vector2.zero, Vector2.zero, Vector2.zero, Vector2.zero });
                            newWallTris  = (new[] { 0, 1, 2, 2, 1, 3 });
                            dynamicColliderMesh.AddData(newWallVerts, newWallUVs, newWallTris, 0);
                        }

                        //offroad bits
                        if (track.disconnectBoundary)
                        {
                            Vector2 offroadTextureSize = Vector2.one;
                            if (track.numberOfTextures > 0)
                            {
                                offroadTextureSize = track.Texture(curve.offroadTextureStyleIndex).textureUnitSize;// track.offroadTexture.textureUnitSize;
                            }
                            newWallVerts = (new[] { leftPointA, leftPointB, leftBoundaryPointA, leftBoundaryPointB });
                            newWallUVs   = (new[] { new Vector2(leftPointA.x / offroadTextureSize.x, leftPointA.z / offroadTextureSize.y), new Vector2(leftPointB.x / offroadTextureSize.x, leftPointB.z / offroadTextureSize.y), new Vector2(leftBoundaryPointA.x / offroadTextureSize.x, leftBoundaryPointA.z / offroadTextureSize.y), new Vector2(leftBoundaryPointB.x / offroadTextureSize.x, leftBoundaryPointB.z / offroadTextureSize.y) });
                            newWallTris  = (new[] { 1, 0, 2, 1, 2, 3 });
                            dynamicOffroadMesh.AddData(newWallVerts, newWallUVs, newWallTris, 0);

                            newWallVerts = (new[] { rightPointA, rightPointB, rightBoundaryPointA, rightBoundaryPointB });
                            newWallUVs   = (new[] { new Vector2(rightPointA.x / offroadTextureSize.x, rightPointA.z / offroadTextureSize.y), new Vector2(rightPointB.x / offroadTextureSize.x, rightPointB.z / offroadTextureSize.y), new Vector2(rightBoundaryPointA.x / offroadTextureSize.x, rightBoundaryPointA.z / offroadTextureSize.y), new Vector2(rightBoundaryPointB.x / offroadTextureSize.x, rightBoundaryPointB.z / offroadTextureSize.y) });
                            newWallTris  = (new[] { 0, 1, 2, 2, 1, 3 });
                            dynamicOffroadMesh.AddData(newWallVerts, newWallUVs, newWallTris, 0);

                            newWallVerts = (new[] { leftPointA, leftPointB, leftBoundaryPointA, leftBoundaryPointB });
                            newWallUVs   = (new[] { Vector2.zero, Vector2.zero, Vector2.zero, Vector2.zero });
                            newWallTris  = (new[] { 1, 0, 2, 1, 2, 3 });
                            dynamicColliderMesh.AddData(newWallVerts, newWallUVs, newWallTris, 0);
                            newWallVerts = (new[] { rightPointA, rightPointB, rightBoundaryPointA, rightBoundaryPointB });
                            newWallUVs   = (new[] { Vector2.zero, Vector2.zero, Vector2.zero, Vector2.zero });
                            newWallTris  = (new[] { 0, 1, 2, 2, 1, 3 });
                            dynamicColliderMesh.AddData(newWallVerts, newWallUVs, newWallTris, 0);
                        }

                        if (track.includeColliderRoof)
                        {
                            newWallVerts = (new[] { leftBoundaryPointA + trackUpA * trackColliderWallHeight, leftBoundaryPointB + trackUpB * trackColliderWallHeight, rightBoundaryPointA + trackUpA * trackColliderWallHeight, rightBoundaryPointB + trackUpB * trackColliderWallHeight });
                            newWallUVs   = (new[] { Vector2.zero, Vector2.zero, Vector2.zero, Vector2.zero });
                            newWallTris  = (new[] { 1, 0, 2, 1, 2, 3 });
                            dynamicColliderMesh.AddData(newWallVerts, newWallUVs, newWallTris, 0);
                        }
                    }

                    if ((track.trackBumpers && curve.generateBumpers) || curve.generateBumpers)
                    {
                        float   bumperWidth          = track.bumperWidth;
                        float   bumperHeight         = track.bumperHeight;
                        Vector3 bumperRaisedA        = trackUpA * bumperHeight;
                        Vector3 bumperRaisedB        = trackUpB * bumperHeight;
                        float   trackAngleThreashold = track.bumperAngleThresold;

                        //left bumpers
                        if (trackAngle >= trackAngleThreashold)
                        {
                            Vector3 offroadEdgeDirectionA = (leftBoundaryPointA - leftPointA).normalized;
                            Vector3 trackEdgeDirectionA   = (newAPoints[1] - newAPoints[0]).normalized;
                            Vector3 bumperDirectionA      = (Vector3.Project(offroadEdgeDirectionA, trackUpA) - trackEdgeDirectionA).normalized;
                            Vector3 offroadEdgeDirectionB = (leftBoundaryPointB - leftPointB).normalized;
                            Vector3 trackEdgeDirectionB   = (newBPoints[1] - newBPoints[0]).normalized;
                            Vector3 bumperDirectionB      = (Vector3.Project(offroadEdgeDirectionB, trackUpB) - trackEdgeDirectionB).normalized;
                            float   trackEdgeA            = Vector3.Distance(pointA, leftPointA);
                            float   offroadEdgeA          = Vector3.Distance(pointA, leftBoundaryPointA);
                            bool    offroadBumper         = (trackEdgeA < (offroadEdgeA - bumperWidth));
                            Vector3 bumperLeft0           = (offroadBumper ? leftPointA + bumperDirectionA * bumperWidth : leftBoundaryPointA) + bumperRaisedA;
                            Vector3 bumperLeft1           = (offroadBumper ? leftPointA : bumperLeft0 - (bumperDirectionA * bumperWidth) - bumperRaisedB);//bumperLeft0 + (trackEdgeDirectionA * bumperWidth)) - bumperRaisedB;

                            Vector3 bumperLeft2 = (offroadBumper ? leftPointB + bumperDirectionB * bumperWidth : leftBoundaryPointB) + bumperRaisedB;
                            Vector3 bumperLeft3 = (offroadBumper ? leftPointB : bumperLeft2 - (bumperDirectionB * bumperWidth) - bumperRaisedB);

                            float bumperSegmentDistanceA = Vector3.Distance(bumperLeft0, bumperLeft2);
                            float uvStartA, uvEndA;
                            if (track.numberOfTextures > 0)
                            {
                                uvStartA = bumperDistanceA / track.Texture(curve.bumperTextureStyleIndex).textureUnitSize.y;                            // track.bumperTexture.textureUnitSize.y;
                                uvEndA   = (bumperDistanceA + bumperSegmentDistanceA) / track.Texture(curve.bumperTextureStyleIndex).textureUnitSize.y; // track.bumperTexture.textureUnitSize.y;
                            }
                            else
                            {
                                uvStartA = bumperDistanceA;                            // track.bumperTexture.textureUnitSize.y;
                                uvEndA   = (bumperDistanceA + bumperSegmentDistanceA); // track.bumperTexture.textureUnitSize.y;
                            }
                            newWallVerts = (new[] { bumperLeft0, bumperLeft1, bumperLeft2, bumperLeft3 });
                            if (!bumperTextureFlip)
                            {
                                newWallUVs = (new[] { new Vector2(uvStartA, 1), new Vector2(uvStartA, 0), new Vector2(uvEndA, 1), new Vector2(uvEndA, 0) });
                            }
                            else
                            {
                                newWallUVs = (new[] { new Vector2(1, uvStartA), new Vector2(0, uvStartA), new Vector2(1, uvEndA), new Vector2(0, uvEndA) });
                            }
                            newWallTris = (new[] { 1, 0, 2, 1, 2, 3 });
                            dynamicBumperMesh.AddData(newWallVerts, newWallUVs, newWallTris, 0);
                            bumperDistanceA += bumperSegmentDistanceA;

                            newWallVerts = (new[] { bumperLeft0, bumperLeft1, bumperLeft2, bumperLeft3 });
                            newWallUVs   = (new[] { Vector2.zero, Vector2.zero, Vector2.zero, Vector2.zero });
                            newWallTris  = (new[] { 1, 0, 2, 1, 2, 3 });
                            dynamicColliderMesh.AddData(newWallVerts, newWallUVs, newWallTris, 0);
                        }

                        //Right bumpers
                        if (trackAngle < -trackAngleThreashold)
                        {
                            Vector3 trackEdgeDirectionA = (newAPoints[pointANumber - 2] - newAPoints[pointANumber - 1]).normalized;
                            Vector3 trackEdgeDirectionB = (newBPoints[pointBNumber - 2] - newBPoints[pointBNumber - 1]).normalized;

                            Vector3 bumperRight0 = ((Vector3.Distance(pointA, rightPointA) < (Vector3.Distance(pointA, rightBoundaryPointA) - bumperWidth)) ? rightPointA : rightBoundaryPointA) + bumperRaisedA;
                            Vector3 bumperRight1 = bumperRight0 + (trackEdgeDirectionA * bumperWidth);

                            Vector3 bumperRight2 = ((Vector3.Distance(pointB, rightPointB) < (Vector3.Distance(pointB, rightBoundaryPointB) - bumperWidth)) ? rightPointB : rightBoundaryPointB) + bumperRaisedB;
                            Vector3 bumperRight3 = bumperRight2 + (trackEdgeDirectionB * bumperWidth);

                            float bumperSegmentDistanceB = Vector3.Distance(bumperRight0, bumperRight2);
                            //float bumperSegmentDistanceA = Vector3.Distance(bumperLeft0, bumperLeft2);

                            float uvStartB, uvEndB;
                            if (track.numberOfTextures > 0)
                            {
                                uvStartB = bumperDistanceB / track.Texture(curve.bumperTextureStyleIndex).textureUnitSize.y;                            // track.bumperTexture.textureUnitSize.y;
                                uvEndB   = (bumperDistanceB + bumperSegmentDistanceB) / track.Texture(curve.bumperTextureStyleIndex).textureUnitSize.y; // track.bumperTexture.textureUnitSize.y;
                            }
                            else
                            {
                                uvStartB = bumperDistanceB;
                                uvEndB   = (bumperDistanceB + bumperSegmentDistanceB);
                            }
                            newWallVerts = (new[] { bumperRight0, bumperRight1, bumperRight2, bumperRight3 });
                            if (!bumperTextureFlip)
                            {
                                newWallUVs = (new[] { new Vector2(uvStartB, 1), new Vector2(uvStartB, 0), new Vector2(uvEndB, 1), new Vector2(uvEndB, 0) });
                            }
                            else
                            {
                                newWallUVs = (new[] { new Vector2(1, uvStartB), new Vector2(0, uvStartB), new Vector2(1, uvEndB), new Vector2(0, uvEndB) });
                            }
//                            newWallTris = (new[] { 1, 0, 2, 1, 2, 3 });
                            newWallTris = (new[] { 0, 1, 2, 1, 3, 2 });
                            dynamicBumperMesh.AddData(newWallVerts, newWallUVs, newWallTris, 0);
                            bumperDistanceB += bumperSegmentDistanceB;
                        }
                    }


                    //Track Bottom Mesh
                    if (curve.extrudeTrack || curve.extrudeTrackBottom)
                    {
                        float   extrusionLength = curve.extrudeLength;
                        Vector3 extrusionA      = -trackUpA * extrusionLength;
                        Vector3 extrusionB      = -trackUpB * extrusionLength;
                        Vector3 pl0             = leftBoundaryPointA;
                        Vector3 pl1             = leftBoundaryPointB;
                        Vector3 pl2             = leftBoundaryPointA + extrusionA;
                        Vector3 pl3             = leftBoundaryPointB + extrusionB;
                        Vector3 pr0             = rightBoundaryPointA;
                        Vector3 pr1             = rightBoundaryPointB;
                        Vector3 pr2             = rightBoundaryPointA + extrusionA;
                        Vector3 pr3             = rightBoundaryPointB + extrusionB;

                        float   bevelLerp = 0.5f - curve.extrudeBevel * 0.3333f;
                        Vector3 bevelOutA = trackCrossA.normalized * (trackWidthA * 0.5f);
                        Vector3 bevelOutB = trackCrossB.normalized * (trackWidthB * 0.5f);
                        Vector3 pl2b      = Vector3.Lerp(pl2 - bevelOutA, pr2 + bevelOutA, bevelLerp);
                        Vector3 pl3b      = Vector3.Lerp(pl3 - bevelOutB, pr3 + bevelOutB, bevelLerp);
                        Vector3 pr2b      = Vector3.Lerp(pr2 + bevelOutA, pl2 - bevelOutA, bevelLerp);
                        Vector3 pr3b      = Vector3.Lerp(pr3 + bevelOutB, pl3 - bevelOutB, bevelLerp);

                        if (curve.extrudeTrack)
                        {
                            //LEFT

                            newWallVerts = new[] { pl0, pl1, pl2b, pl3b };

                            if (!bottomTextureFlip)
                            {
                                newWallUVs = new[] { new Vector2(curveLengthA, 0), new Vector2(curveLengthB, 0), new Vector2(curveLengthA, 1), new Vector2(curveLengthB, 1), }
                            }
                            ;
                            else
                            {
                                newWallUVs = new[] { new Vector2(1, curveLengthA), new Vector2(1, curveLengthB), new Vector2(0, curveLengthA), new Vector2(0, curveLengthB), }
                            };
                            newWallTris = new[] { 1, 0, 2, 1, 2, 3 };
                            dynamicBottomMesh.AddData(newWallVerts, newWallUVs, newWallTris, 0);
                            if (curve.trackCollider)
                            {
                                dynamicColliderMesh.AddData(newWallVerts, newWallUVs, newWallTris, 0);
                            }

                            //RIGHT
                            newWallVerts = (new[] { pr0, pr1, pr2b, pr3b });
                            if (!bottomTextureFlip)
                            {
                                newWallUVs = new[] { new Vector2(curveLengthA, 0), new Vector2(curveLengthB, 0), new Vector2(curveLengthA, 1), new Vector2(curveLengthB, 1), }
                            }
                            ;
                            else
                            {
                                newWallUVs = new[] { new Vector2(1, curveLengthA), new Vector2(1, curveLengthB), new Vector2(0, curveLengthA), new Vector2(0, curveLengthB), }
                            };

                            newWallTris = new[] { 0, 1, 2, 2, 1, 3 };
                            dynamicBottomMesh.AddData(newWallVerts, newWallUVs, newWallTris, 0);
                            if (curve.trackCollider)
                            {
                                dynamicColliderMesh.AddData(newWallVerts, newWallUVs, newWallTris, 0);
                            }

                            if (curve.extrudeCurveEnd)
                            {
                                //Ends
                                if (p == 0)
                                {
                                    newWallVerts = (new[] { pl0, pl2b, pr0, pr2b });
                                    if (!bottomTextureFlip)
                                    {
                                        newWallUVs = new[] { new Vector2(curveLengthA, 0), new Vector2(curveLengthB, 0), new Vector2(curveLengthA, 1), new Vector2(curveLengthB, 1), }
                                    }
                                    ;
                                    else
                                    {
                                        newWallUVs = new[] { new Vector2(1, curveLengthA), new Vector2(1, curveLengthB), new Vector2(0, curveLengthA), new Vector2(0, curveLengthB), }
                                    };
                                    newWallTris = new[] { 1, 0, 2, 1, 2, 3 };
                                    dynamicBottomMesh.AddData(newWallVerts, newWallUVs, newWallTris, 0);
                                    if (curve.trackCollider)
                                    {
                                        dynamicColliderMesh.AddData(newWallVerts, newWallUVs, newWallTris, 0);
                                    }
                                }
                                if (p == storedPointSize - 2)
                                {
                                    newWallVerts = (new[] { pl1, pl3b, pr1, pr3b });
                                    if (!bottomTextureFlip)
                                    {
                                        newWallUVs = new[] { new Vector2(curveLengthA, 0), new Vector2(curveLengthB, 0), new Vector2(curveLengthA, 1), new Vector2(curveLengthB, 1), }
                                    }
                                    ;
                                    else
                                    {
                                        newWallUVs = new[] { new Vector2(1, curveLengthA), new Vector2(1, curveLengthB), new Vector2(0, curveLengthA), new Vector2(0, curveLengthB), }
                                    };
                                    newWallTris = new[] { 0, 1, 2, 2, 1, 3 };
                                    dynamicBottomMesh.AddData(newWallVerts, newWallUVs, newWallTris, 0);
                                    if (curve.trackCollider)
                                    {
                                        dynamicColliderMesh.AddData(newWallVerts, newWallUVs, newWallTris, 0);
                                    }
                                }
                            }
                        }

                        if (curve.extrudeTrackBottom)
                        {
                            if (!curve.extrudeTrack)
                            {
                                newWallVerts = new[] { pl0, pl1, pr0, pr1 }
                            }
                            ;
                            else
                            {
                                newWallVerts = new[] { pl2b, pl3b, pr2b, pr3b }
                            };

                            if (!bottomTextureFlip)
                            {
                                newWallUVs = new[] { new Vector2(curveLengthA, 0), new Vector2(curveLengthB, 0), new Vector2(curveLengthA, 1), new Vector2(curveLengthB, 1), }
                            }
                            ;
                            else
                            {
                                newWallUVs = new[] { new Vector2(1, curveLengthA), new Vector2(1, curveLengthB), new Vector2(0, curveLengthA), new Vector2(0, curveLengthB), }
                            };

                            newWallTris = new[] { 1, 0, 2, 1, 2, 3 };
                            dynamicBottomMesh.AddData(newWallVerts, newWallUVs, newWallTris, 0);
                            if (curve.trackCollider)
                            {
                                dynamicColliderMesh.AddData(newWallVerts, newWallUVs, newWallTris, 0);
                            }
                        }
                    }

                    if (p == storedPointSize - 2)
                    {
                        UVOffset = curveLengthB;
                    }
                }

                if (curve.holder != null)
                {
                    DestroyImmediate(curve.holder);
                }

                GameObject newCurveMeshHolder = new GameObject("curve " + (i + 1));
                newCurveMeshHolder.transform.parent        = transform;
                newCurveMeshHolder.transform.localPosition = Vector3.zero;
                curve.holder = newCurveMeshHolder;
                int numberOfMeshes;
                if (!dynamicTrackMesh.isEmpty)
                {
                    dynamicTrackMesh.name = "Curve " + i + " Track Mesh";
                    dynamicTrackMesh.Build();
                    numberOfMeshes = dynamicTrackMesh.meshCount;
                    for (int m = 0; m < numberOfMeshes; m++)
                    {
                        GameObject newMeshHolder = new GameObject("model " + (m + 1));
                        newMeshHolder.transform.parent        = curve.holder.transform;
                        newMeshHolder.transform.localPosition = Vector3.zero;
                        newMeshHolder.AddComponent <MeshFilter>().sharedMesh = dynamicTrackMesh[m].mesh;
                        if (track.numberOfTextures > 0)
                        {
                            newMeshHolder.AddComponent <MeshRenderer>().material = track.Texture(curve.trackTextureStyleIndex).GetMaterial();// track.trackTexture.material;
                        }
#if UNITY_EDITOR
                        EditorUtility.SetSelectedWireframeHidden(newMeshHolder.renderer, !track.showWireframe);
#endif
                    }
                }


                if (!dynamicBoundaryMesh.isEmpty)
                {
                    dynamicBoundaryMesh.Build();
                    numberOfMeshes = dynamicBoundaryMesh.meshCount;
                    for (int m = 0; m < numberOfMeshes; m++)
                    {
                        GameObject newMeshHolder = new GameObject("boundary " + (m + 1));
                        newMeshHolder.transform.parent        = curve.holder.transform;
                        newMeshHolder.transform.localPosition = Vector3.zero;
                        newMeshHolder.AddComponent <MeshFilter>().sharedMesh = dynamicBoundaryMesh[m].mesh;
                        if (track.numberOfTextures > 0)
                        {
                            newMeshHolder.AddComponent <MeshRenderer>().material = track.Texture(curve.boundaryTextureStyleIndex).GetMaterial();// track.trackTexture.material;
                        }
#if UNITY_EDITOR
                        EditorUtility.SetSelectedWireframeHidden(newMeshHolder.renderer, !track.showWireframe);
#endif
                    }
                }

                if (track.disconnectBoundary && !dynamicOffroadMesh.isEmpty)
                {
                    dynamicOffroadMesh.Build();
                    numberOfMeshes = dynamicOffroadMesh.meshCount;
                    for (int m = 0; m < numberOfMeshes; m++)
                    {
                        GameObject newMeshHolder = new GameObject("offroad " + (m + 1));
                        newMeshHolder.transform.parent        = curve.holder.transform;
                        newMeshHolder.transform.localPosition = Vector3.zero;
                        newMeshHolder.AddComponent <MeshFilter>().sharedMesh = dynamicOffroadMesh[m].mesh;
                        if (track.numberOfTextures > 0)
                        {
                            newMeshHolder.AddComponent <MeshRenderer>().material = track.Texture(curve.offroadTextureStyleIndex).GetMaterial();// track.offroadTexture.material;
                        }
#if UNITY_EDITOR
                        EditorUtility.SetSelectedWireframeHidden(newMeshHolder.renderer, !track.showWireframe);
#endif
                    }
                }

                if (track.includeCollider && curve.trackCollider && !dynamicColliderMesh.isEmpty)
                {
                    dynamicColliderMesh.Build();
                    int numberOfColliderMeshes = dynamicColliderMesh.meshCount;
                    for (int m = 0; m < numberOfColliderMeshes; m++)
                    {
                        GameObject newMeshHolder = new GameObject("trackCollider " + (m + 1));
                        newMeshHolder.transform.parent        = curve.holder.transform;
                        newMeshHolder.transform.localPosition = Vector3.zero;
                        newMeshHolder.AddComponent <MeshCollider>().sharedMesh = dynamicColliderMesh[m].mesh;
                    }
                }

                if (track.trackBumpers && !dynamicBumperMesh.isEmpty)
                {
                    dynamicBumperMesh.Build();
                    numberOfMeshes = dynamicBumperMesh.meshCount;
                    for (int m = 0; m < numberOfMeshes; m++)
                    {
                        GameObject newMeshHolder = new GameObject("bumper " + (m + 1));
                        newMeshHolder.transform.parent        = curve.holder.transform;
                        newMeshHolder.transform.localPosition = Vector3.zero;
                        newMeshHolder.AddComponent <MeshFilter>().sharedMesh = dynamicBumperMesh[m].mesh;
                        if (track.numberOfTextures > 0)
                        {
                            newMeshHolder.AddComponent <MeshRenderer>().material = track.Texture(curve.bumperTextureStyleIndex).GetMaterial();// track.bumperTexture.material;
                        }
#if UNITY_EDITOR
                        EditorUtility.SetSelectedWireframeHidden(newMeshHolder.renderer, !track.showWireframe);
#endif
                    }
                }

                if (!dynamicBottomMesh.isEmpty)
                {
                    dynamicBottomMesh.Build();
                    numberOfMeshes = dynamicBottomMesh.meshCount;
                    for (int m = 0; m < numberOfMeshes; m++)
                    {
                        GameObject newMeshHolder = new GameObject("bottom " + (m + 1));
                        newMeshHolder.transform.parent        = curve.holder.transform;
                        newMeshHolder.transform.localPosition = Vector3.zero;
                        newMeshHolder.AddComponent <MeshFilter>().sharedMesh = dynamicBottomMesh[m].mesh;
                        if (track.numberOfTextures > 0)
                        {
                            newMeshHolder.AddComponent <MeshRenderer>().material = track.Texture(curve.bottomTextureStyleIndex).GetMaterial();// track.trackTexture.material;
                        }
#if UNITY_EDITOR
                        EditorUtility.SetSelectedWireframeHidden(newMeshHolder.renderer, !track.showWireframe);
#endif
                    }
                }
            }
            else
            {
                if (curve.holder != null && (!curve.render || !renderTrack))
                {
                    DestroyImmediate(curve.holder);
                }
            }

            polyCount += dynamicBottomMesh.triangleCount / 3;
            polyCount += dynamicBoundaryMesh.triangleCount / 3;
            polyCount += dynamicBumperMesh.triangleCount / 3;
            polyCount += dynamicOffroadMesh.triangleCount / 3;
            polyCount += dynamicTrackMesh.triangleCount / 3;
        }

        track.TrackRendered();

        track.lastPolycount = polyCount;

#if UNITY_EDITOR
        EditorUtility.UnloadUnusedAssets();
#endif
    }
Ejemplo n.º 12
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();
        }
    }
Ejemplo n.º 13
0
    private static void ExportModel(TrackBuildR track)
    {
        GameObject baseObject = new GameObject(track.exportFilename);

        baseObject.transform.position = CURRENT_TRANSFORM.position;
        baseObject.transform.rotation = CURRENT_TRANSFORM.rotation;
        EditorUtility.DisplayCancelableProgressBar(PROGRESSBAR_TEXT, "", 0.0f);
        track.ForceFullRecalculation();
        EditorUtility.DisplayCancelableProgressBar(PROGRESSBAR_TEXT, "", 0.1f);
        try
        {
            TrackBuildRTrack trackData = track.track;

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

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

            int              numberOfCurves  = trackData.numberOfCurves;
            float            exportProgress  = 0.75f / (numberOfCurves * 6.0f);
            ExportMaterial[] exportMaterials = new ExportMaterial[1];
            ExportMaterial   exportTexture   = new ExportMaterial();

            string[] dynNames = new [] { "track", "bumper", "boundary", "bottom", "offread", "trackCollider" };
            for (int c = 0; c < numberOfCurves; c++)
            {
                TrackBuildRPoint curve = trackData[c];

                int numberOfDynMeshes = 6;
                DynamicMeshGenericMultiMaterialMesh[] dynMeshes = new DynamicMeshGenericMultiMaterialMesh[6];
                dynMeshes[0] = curve.dynamicTrackMesh;
                dynMeshes[1] = curve.dynamicBumperMesh;
                dynMeshes[2] = curve.dynamicBoundaryMesh;
                dynMeshes[3] = curve.dynamicBottomMesh;
                dynMeshes[4] = curve.dynamicOffroadMesh;
                dynMeshes[5] = curve.dynamicColliderMesh;

                int[] textureIndeices = new int[] { curve.trackTextureStyleIndex, curve.bumperTextureStyleIndex, curve.boundaryTextureStyleIndex, curve.bottomTextureStyleIndex, curve.offroadTextureStyleIndex, 0 };

                for (int d = 0; d < numberOfDynMeshes; d++)
                {
                    if (EditorUtility.DisplayCancelableProgressBar(PROGRESSBAR_TEXT, "Exporting Track Curve " + c + " " + dynNames[d], 0.15f + exportProgress * (c * 6 + d)))
                    {
                        EditorUtility.ClearProgressBar();
                        return;
                    }
                    DynamicMeshGenericMultiMaterialMesh exportDynMesh = dynMeshes[d];
                    if (track.includeTangents || exportDynMesh.isEmpty)
                    {
                        exportDynMesh.Build(track.includeTangents);//rebuild with tangents
                    }
                    TrackBuildRTexture texture = trackData.Texture(textureIndeices[d]);
                    exportTexture.name      = texture.customName;
                    exportTexture.material  = texture.material;
                    exportTexture.generated = false;
                    exportTexture.filepath  = texture.filePath;
                    exportMaterials[0]      = exportTexture;

                    int meshCount = exportDynMesh.meshCount;
                    for (int i = 0; i < meshCount; i++)
                    {
                        Mesh exportMesh = exportDynMesh[i].mesh;
                        MeshUtility.Optimize(exportMesh);
                        string filenameSuffix = trackModelName(dynNames[d], c, (meshCount > 1) ? i : -1);// "trackCurve" + c + ((meshCount > 1) ? "_" + i.ToString() : "");
                        string filename       = track.exportFilename + filenameSuffix;
                        Export(filename, ROOT_FOLDER + track.exportFilename + "/", track, exportMesh, exportMaterials);

                        if (track.createPrefabOnExport)
                        {
                            AssetDatabase.Refresh();//ensure the database is up to date...

                            string modelFilePath = ROOT_FOLDER + track.exportFilename + "/" + filename + FILE_EXTENTION;
                            if (d < numberOfDynMeshes - 1)
                            {
                                GameObject newModel = (GameObject)PrefabUtility.InstantiatePrefab(AssetDatabase.LoadMainAssetAtPath(modelFilePath));
                                newModel.name                    = filename;
                                newModel.transform.parent        = baseObject.transform;
                                newModel.transform.localPosition = Vector3.zero;
                                newModel.transform.localRotation = Quaternion.identity;
                            }
                            else
                            {
                                GameObject colliderObject = new GameObject("trackCollider");
                                colliderObject.AddComponent <MeshCollider>().sharedMesh = (Mesh)AssetDatabase.LoadAssetAtPath(modelFilePath, typeof(Mesh));
                                colliderObject.transform.parent        = baseObject.transform;
                                colliderObject.transform.localPosition = Vector3.zero;
                                colliderObject.transform.localRotation = Quaternion.identity;
                            }
                        }
                    }
                }
            }
            if (track.createPrefabOnExport)
            {
                string prefabPath = ROOT_FOLDER + track.exportFilename + "/" + track.exportFilename + ".prefab";
                Object prefab     = AssetDatabase.LoadAssetAtPath(prefabPath, typeof(GameObject));
                if (prefab == null)
                {
                    prefab = PrefabUtility.CreateEmptyPrefab(prefabPath);
                }
                PrefabUtility.ReplacePrefab(baseObject, prefab, ReplacePrefabOptions.ConnectToPrefab);
            }

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

            AssetDatabase.Refresh();//ensure the database is up to date...
        }
        catch (System.Exception e)
        {
            Debug.LogError("BuildR Export Error: " + e);
            EditorUtility.ClearProgressBar();
        }
        Object.DestroyImmediate(baseObject);
        EditorUtility.ClearProgressBar();
        EditorUtility.UnloadUnusedAssets();
        AssetDatabase.Refresh();
    }
Ejemplo n.º 14
0
    public void UpdateInteriors()
    {
        while (interiorMeshHolders.Count > 0)
        {
            GameObject destroyOld = interiorMeshHolders[0];
            interiorMeshHolders.RemoveAt(0);
            DestroyImmediate(destroyOld);
        }

        interiorMeshes.Clear();

        if (data.renderInteriors)
        {
            int numberOfVolumes = data.plan.numberOfVolumes;
            for (int v = 0; v < numberOfVolumes; v++)
            {
                DynamicMeshGenericMultiMaterialMesh interiorMesh = new DynamicMeshGenericMultiMaterialMesh();
                interiorMesh.subMeshCount = data.textures.Count;
                BuildrVolume volume = _data.plan.volumes[v];
                BuildrInteriors.Build(interiorMesh, data, v);
                interiorMesh.Build(false);

                List <int>      unusedInteriorTextures    = interiorMesh.unusedSubmeshes;
                int             numberOfInteriorMaterials = data.textures.Count;
                List <Material> interiorMaterials         = new List <Material>();
                for (int m = 0; m < numberOfInteriorMaterials; m++)
                {
                    if (unusedInteriorTextures.Contains(m))
                    {
                        continue;//skip, unused
                    }
                    BuildrTexture bTexture = data.textures[m];
                    interiorMaterials.Add(bTexture.usedMaterial);
                }

                int numberOfInteriorMeshes = interiorMesh.meshCount;
                for (int i = 0; i < numberOfInteriorMeshes; i++)
                {
                    string meshName = "model interior";
                    if (numberOfVolumes > 0)
                    {
                        meshName += " volume " + (v + 1);
                    }
                    if (numberOfInteriorMeshes > 1)
                    {
                        meshName += " mesh " + (i + 1);
                    }
                    GameObject newMeshHolder = new GameObject(meshName);
                    newMeshHolder.transform.parent        = transform;
                    newMeshHolder.transform.localPosition = Vector3.zero;
                    meshFilt      = newMeshHolder.AddComponent <MeshFilter>();
                    meshRend      = newMeshHolder.AddComponent <MeshRenderer>();
                    meshFilt.mesh = interiorMesh[i].mesh;
                    interiorMeshHolders.Add(newMeshHolder);

                    int numberOfInterior = interiorMeshHolders.Count;
                    for (int m = 0; m < numberOfInterior; m++)
                    {
                        meshRend.sharedMaterials = interiorMaterials.ToArray();
                    }
                }
                interiorMeshes.Add(interiorMesh);

                if (!volume.generateStairs)
                {
                    continue;
                }

                DynamicMeshGenericMultiMaterialMesh stairwellMesh = new DynamicMeshGenericMultiMaterialMesh();
                stairwellMesh.subMeshCount = data.textures.Count;
                BuildrStairs.Build(stairwellMesh, data, v, BuildrStairs.StairModes.Stepped, true);
                stairwellMesh.Build(false);


                List <int>      unusedStairTextures    = stairwellMesh.unusedSubmeshes;
                int             numberOfStairMaterials = data.textures.Count;
                List <Material> stairMaterials         = new List <Material>();
                for (int m = 0; m < numberOfStairMaterials; m++)
                {
                    if (unusedStairTextures.Contains(m))
                    {
                        continue;//skip, unused
                    }
                    BuildrTexture bTexture = data.textures[m];
                    stairMaterials.Add(bTexture.usedMaterial);
                }

                int numberOfStairMeshes = stairwellMesh.meshCount;
                for (int i = 0; i < numberOfStairMeshes; i++)
                {
                    string meshName = "model stairs";
                    if (numberOfVolumes > 0)
                    {
                        meshName += " volume " + (v + 1);
                    }
                    if (numberOfStairMeshes > 1)
                    {
                        meshName += " mesh " + (i + 1);
                    }
                    GameObject newMeshHolder = new GameObject(meshName);
                    newMeshHolder.transform.parent        = transform;
                    newMeshHolder.transform.localPosition = volume.stairBaseVector[i];
                    meshFilt      = newMeshHolder.AddComponent <MeshFilter>();
                    meshRend      = newMeshHolder.AddComponent <MeshRenderer>();
                    meshFilt.mesh = stairwellMesh[i].mesh;
                    interiorMeshHolders.Add(newMeshHolder);
                    meshRend.sharedMaterials = stairMaterials.ToArray();
                }
                interiorMeshes.Add(stairwellMesh);
            }
        }
    }
    private static int[] ExportStairwells(BuildrData data)
    {
        int numberOfVolumes = data.plan.numberOfVolumes;
        int[] returnNumberOfMeshes = new int[numberOfVolumes];

        for (int v = 0; v < numberOfVolumes; v++)
        {
            BuildrVolume volume = data.plan.volumes[v];

            int numberOfUnpackedTextures = data.textures.Count;
            List<ExportMaterial> exportTextures = new List<ExportMaterial>();

            if (!volume.generateStairs) continue;
            DynamicMeshGenericMultiMaterialMesh INT_STAIRWELL = new DynamicMeshGenericMultiMaterialMesh();
            INT_STAIRWELL.subMeshCount = data.textures.Count;
            BuildrStairs.Build(INT_STAIRWELL, data, v, BuildrStairs.StairModes.Stepped, true);
            INT_STAIRWELL.Build(data.includeTangents);

            List<int> unusedStairTextures = INT_STAIRWELL.unusedSubmeshes;
            numberOfUnpackedTextures = data.textures.Count;
            for (int t = 0; t < numberOfUnpackedTextures; t++)
            {
                if (unusedStairTextures.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;
                exportTextures.Add(newTexture);
            }

            int numberOfStairMeshes = INT_STAIRWELL.meshCount;
            for (int i = 0; i < numberOfStairMeshes; i++)
            {
                MeshUtility.Optimize(INT_STAIRWELL[i].mesh);
                string VolumeSuffix = ((numberOfVolumes > 1) ? "_" + v : "");
                string DetailSuffixIndex = ((numberOfStairMeshes > 1) ? "_" + i : "");
                string DetailFileName = data.exportFilename + STAIR_SUFFIX + VolumeSuffix + DetailSuffixIndex;
                string DetailFolder = ROOT_FOLDER + data.exportFilename + "/";
                Export(DetailFileName, DetailFolder, data, INT_STAIRWELL[i].mesh, exportTextures.ToArray());
            }

            returnNumberOfMeshes[v] = numberOfStairMeshes;
        }

        return returnNumberOfMeshes;
    }
Ejemplo n.º 16
0
    public void UpdateInteriors()
    {
        while (interiorMeshHolders.Count > 0)
        {
            GameObject destroyOld = interiorMeshHolders[0];
            interiorMeshHolders.RemoveAt(0);
            DestroyImmediate(destroyOld);
        }

        interiorMeshes.Clear();

        if (data.renderInteriors)
        {
            int numberOfVolumes = data.plan.numberOfVolumes;
            for(int v = 0; v < numberOfVolumes; v++)
            {
                DynamicMeshGenericMultiMaterialMesh interiorMesh = new DynamicMeshGenericMultiMaterialMesh();
                interiorMesh.subMeshCount = data.textures.Count;
                BuildrVolume volume = _data.plan.volumes[v];
                BuildrInteriors.Build(interiorMesh, data, v);
                interiorMesh.Build(false);

                List<int> unusedInteriorTextures = interiorMesh.unusedSubmeshes;
                int numberOfInteriorMaterials = data.textures.Count;
                List<Material> interiorMaterials = new List<Material>();
                for (int m = 0; m < numberOfInteriorMaterials; m++)
                {
                    if (unusedInteriorTextures.Contains(m))
                        continue;//skip, unused
                    BuildrTexture bTexture = data.textures[m];
                    interiorMaterials.Add(bTexture.usedMaterial);
                }

                int numberOfInteriorMeshes = interiorMesh.meshCount;
                for (int i = 0; i < numberOfInteriorMeshes; i++)
                {
                    string meshName = "model interior";
                    if (numberOfVolumes > 0) meshName += " volume " + (v + 1);
                    if(numberOfInteriorMeshes>1)meshName += " mesh " + (i + 1);
                    GameObject newMeshHolder = new GameObject(meshName);
                    newMeshHolder.transform.parent = transform;
                    newMeshHolder.transform.localPosition = Vector3.zero;
                    meshFilt = newMeshHolder.AddComponent<MeshFilter>();
                    meshRend = newMeshHolder.AddComponent<MeshRenderer>();
                    meshFilt.mesh = interiorMesh[i].mesh;
                    interiorMeshHolders.Add(newMeshHolder);

                    int numberOfInterior = interiorMeshHolders.Count;
                    for (int m = 0; m < numberOfInterior; m++)
                        meshRend.sharedMaterials = interiorMaterials.ToArray();
                }
                interiorMeshes.Add(interiorMesh);

                if(!volume.generateStairs) continue;

                DynamicMeshGenericMultiMaterialMesh stairwellMesh = new DynamicMeshGenericMultiMaterialMesh();
                stairwellMesh.subMeshCount = data.textures.Count;
                BuildrStairs.Build(stairwellMesh, data, v, BuildrStairs.StairModes.Stepped, true);
                stairwellMesh.Build(false);

                List<int> unusedStairTextures = stairwellMesh.unusedSubmeshes;
                int numberOfStairMaterials = data.textures.Count;
                List<Material> stairMaterials = new List<Material>();
                for (int m = 0; m < numberOfStairMaterials; m++)
                {
                    if (unusedStairTextures.Contains(m))
                        continue;//skip, unused
                    BuildrTexture bTexture = data.textures[m];
                    stairMaterials.Add(bTexture.usedMaterial);
                }

                int numberOfStairMeshes = stairwellMesh.meshCount;
                for (int i = 0; i < numberOfStairMeshes; i++)
                {
                    string meshName = "model stairs";
                    if (numberOfVolumes > 0) meshName += " volume " + (v + 1);
                    if (numberOfStairMeshes > 1) meshName += " mesh " + (i + 1);
                    GameObject newMeshHolder = new GameObject(meshName);
                    newMeshHolder.transform.parent = transform;
                    newMeshHolder.transform.localPosition = volume.stairBaseVector[i];
                    meshFilt = newMeshHolder.AddComponent<MeshFilter>();
                    meshRend = newMeshHolder.AddComponent<MeshRenderer>();
                    meshFilt.mesh = stairwellMesh[i].mesh;
                    interiorMeshHolders.Add(newMeshHolder);
                    meshRend.sharedMaterials = stairMaterials.ToArray();
                }
                interiorMeshes.Add(stairwellMesh);
            }
        }
    }
Ejemplo n.º 17
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;
        }
    }
    /// <summary>
    /// Generate the detail meshes and return the export object
    /// </summary>
    /// <param name="mesh"></param>
    /// <param name="data"></param>
    /// <returns></returns>
    public static BuildrDetailExportObject Build(DynamicMeshGenericMultiMaterialMesh mesh, BuildrData data)
    {
        BuildrDetailExportObject exportObject = new BuildrDetailExportObject();
        List<Texture2D> detailTextures = new List<Texture2D>();
        List<int> detailSubmeshesWithTextures = new List<int>();
        int numberOfDetails = data.details.Count;
        mesh.Clear();
        mesh.subMeshCount = numberOfDetails;

        for(int d = 0; d < numberOfDetails; d++)
        {
            BuildrDetail detail = data.details[d];
            if(detail.mesh == null)
                continue;
            int faceIndex = detail.face;
            Vector3 position = Vector3.zero;
            BuildrPlan plan = data.plan;
            int numberOfVolumes = plan.numberOfVolumes;
            Vector2 faceUv = detail.faceUv;
            Quaternion faceAngle = Quaternion.identity;
            //Place the detail mesh
            if (detail.type == BuildrDetail.Types.Facade)
            {
                //find facade
                int facadeCount = 0;
                bool facadeFound = false;
                for (int s = 0; s < numberOfVolumes; s++)
                {
                    BuildrVolume volume = plan.volumes[s];
                    int numberOfVolumePoints = volume.points.Count;
                    for (int p = 0; p < numberOfVolumePoints; p++)
                    {
                        if (facadeCount == faceIndex)
                        {
                            int indexA = p;
                            int indexB = (p + 1) % numberOfVolumePoints;
                            Vector3 p0 = plan.points[volume.points[indexA]].vector3;
                            Vector3 p1 = plan.points[volume.points[indexB]].vector3;
                            Vector3 basePosition = Vector3.Lerp(p0, p1, faceUv.x);
                            Vector3 detailHeight = Vector3.up * (volume.numberOfFloors * data.floorHeight * faceUv.y);
                            Vector3 facadeCross = Vector3.Cross(Vector3.up, p1 - p0).normalized;
                            Vector3 detailDepth = facadeCross * detail.faceHeight;
                            faceAngle = Quaternion.LookRotation(facadeCross);
                            position = basePosition + detailHeight + detailDepth;
                            facadeFound = true;
                            break;
                        }
                        facadeCount++;
                    }
                    if (facadeFound)
                        break;
                }
            }
            else//roof detail
            {
                BuildrVolume volume = plan.volumes[Mathf.Clamp(0,numberOfVolumes-1,faceIndex)];
                int numberOfVolumePoints = volume.points.Count;
                Vector3 minimumRoofPoint = plan.points[volume.points[0]].vector3;
                Vector3 maximumRoofPoint = minimumRoofPoint;
                for (int p = 1; p < numberOfVolumePoints; p++)
                {
                    Vector3 p0 = plan.points[volume.points[p]].vector3;
                    if (p0.x < minimumRoofPoint.x) minimumRoofPoint.x = p0.x;
                    if (p0.z < minimumRoofPoint.y) minimumRoofPoint.y = p0.z;
                    if (p0.x > maximumRoofPoint.x) maximumRoofPoint.x = p0.x;
                    if (p0.z > maximumRoofPoint.y) maximumRoofPoint.y = p0.z;
                }
                position.x = Mathf.Lerp(minimumRoofPoint.x, maximumRoofPoint.x, faceUv.x);
                position.z = Mathf.Lerp(minimumRoofPoint.y, maximumRoofPoint.y, faceUv.y);
                position.y = volume.numberOfFloors * data.floorHeight + detail.faceHeight;
            }

            Quaternion userRotation = Quaternion.Euler(detail.userRotation);
            int vertexCount = detail.mesh.vertexCount;
            Vector3[] verts = new Vector3[vertexCount];
            Quaternion rotate = faceAngle * userRotation;
            for (int i = 0; i < vertexCount; i++)
            {
                Vector3 sourceVertex = Vector3.Scale(detail.mesh.vertices[i], detail.scale);
                Vector3 outputVertex = (rotate) * sourceVertex + position;
                verts[i] = outputVertex;
            }
            mesh.AddData(verts, detail.mesh.uv, detail.mesh.triangles, d);
            detail.worldPosition = position;
            detail.worldRotation = rotate;

            if (detail.material.mainTexture != null)
            {
        #if UNITY_EDITOR
                string texturePath = AssetDatabase.GetAssetPath(detail.material.mainTexture);
                TextureImporter textureImporter = (TextureImporter)AssetImporter.GetAtPath(texturePath);

                if (!textureImporter.isReadable)
                {
                    Debug.LogWarning("The texture you have selected is not readable. Cannot render");
                    return exportObject;
                }

                detailTextures.Add((Texture2D)detail.material.mainTexture);
                detailSubmeshesWithTextures.Add(d);
        #endif
            }
        }

        if(detailtexture!=null)
            Object.DestroyImmediate(detailtexture);

        List<Mesh> outputMeshes = new List<Mesh>();
        if (detailSubmeshesWithTextures.Count > 0)
        {
            Rect[] textureRects = BuildrTexturePacker2.Pack(out detailtexture, detailTextures.ToArray(), 512);
            if(detailSubmeshesWithTextures.Count > 0) mesh.Atlas(detailSubmeshesWithTextures.ToArray(), textureRects);
            mesh.CollapseSubmeshes();
            mesh.Build();
            int numberOfMeshes = mesh.meshCount;
            for (int i = 0; i < numberOfMeshes; i++)
                outputMeshes.Add(mesh[i].mesh);
        }

        exportObject.detailMeshes = outputMeshes.ToArray();
        exportObject.texture = detailtexture;
        return exportObject;
        /*if (detailMat == null)
                detailMat = new Material(Shader.Find("Diffuse"));
            detailMat.mainTexture = detailtexture;
            List<Mesh> outputMeshes = new List<Mesh>();
            for (int i = 0; i < numberOfMeshes; i++)
            {
                outputMeshes.Add(mesh[i].mesh);
                GameObject details = new GameObject("details " + i);
                details.AddComponent<MeshFilter>().mesh = mesh[i].mesh;
                details.AddComponent<MeshRenderer>().sharedMaterial = detailMat;
                detailGameobjects.Add(details);
            }
        }
        //        Debug.Log("BuildR Detail Pack Complete: " + (Time.realtimeSinceStartup - timestart) + " sec");
        return detailGameobjects.ToArray();*/
    }
Ejemplo n.º 19
0
    /// <summary>
    /// Generate the detail meshes and return the export object
    /// </summary>
    /// <param name="mesh"></param>
    /// <param name="data"></param>
    /// <returns></returns>
    public static BuildrDetailExportObject Build(DynamicMeshGenericMultiMaterialMesh mesh, BuildrData data)
    {
        BuildrDetailExportObject exportObject   = new BuildrDetailExportObject();
        List <Texture2D>         detailTextures = new List <Texture2D>();
        List <int> detailSubmeshesWithTextures  = new List <int>();
        int        numberOfDetails = data.details.Count;

        mesh.Clear();
        mesh.subMeshCount = numberOfDetails;

        for (int d = 0; d < numberOfDetails; d++)
        {
            BuildrDetail detail = data.details[d];
            if (detail.mesh == null)
            {
                continue;
            }
            int        faceIndex       = detail.face;
            Vector3    position        = Vector3.zero;
            BuildrPlan plan            = data.plan;
            int        numberOfVolumes = plan.numberOfVolumes;
            Vector2    faceUv          = detail.faceUv;
            Quaternion faceAngle       = Quaternion.identity;
            //Place the detail mesh
            if (detail.type == BuildrDetail.Types.Facade)
            {
                //find facade
                int  facadeCount = 0;
                bool facadeFound = false;
                for (int s = 0; s < numberOfVolumes; s++)
                {
                    BuildrVolume volume = plan.volumes[s];
                    int          numberOfVolumePoints = volume.points.Count;
                    for (int p = 0; p < numberOfVolumePoints; p++)
                    {
                        if (facadeCount == faceIndex)
                        {
                            int     indexA       = p;
                            int     indexB       = (p + 1) % numberOfVolumePoints;
                            Vector3 p0           = plan.points[volume.points[indexA]].vector3;
                            Vector3 p1           = plan.points[volume.points[indexB]].vector3;
                            Vector3 basePosition = Vector3.Lerp(p0, p1, faceUv.x);
                            Vector3 detailHeight = Vector3.up * (volume.numberOfFloors * data.floorHeight * faceUv.y);
                            Vector3 facadeCross  = Vector3.Cross(Vector3.up, p1 - p0).normalized;
                            Vector3 detailDepth  = facadeCross * detail.faceHeight;
                            faceAngle   = Quaternion.LookRotation(facadeCross);
                            position    = basePosition + detailHeight + detailDepth;
                            facadeFound = true;
                            break;
                        }
                        facadeCount++;
                    }
                    if (facadeFound)
                    {
                        break;
                    }
                }
            }
            else//roof detail
            {
                BuildrVolume volume = plan.volumes[Mathf.Clamp(0, numberOfVolumes - 1, faceIndex)];
                int          numberOfVolumePoints = volume.points.Count;
                Vector3      minimumRoofPoint     = plan.points[volume.points[0]].vector3;
                Vector3      maximumRoofPoint     = minimumRoofPoint;
                for (int p = 1; p < numberOfVolumePoints; p++)
                {
                    Vector3 p0 = plan.points[volume.points[p]].vector3;
                    if (p0.x < minimumRoofPoint.x)
                    {
                        minimumRoofPoint.x = p0.x;
                    }
                    if (p0.z < minimumRoofPoint.y)
                    {
                        minimumRoofPoint.y = p0.z;
                    }
                    if (p0.x > maximumRoofPoint.x)
                    {
                        maximumRoofPoint.x = p0.x;
                    }
                    if (p0.z > maximumRoofPoint.y)
                    {
                        maximumRoofPoint.y = p0.z;
                    }
                }
                position.x = Mathf.Lerp(minimumRoofPoint.x, maximumRoofPoint.x, faceUv.x);
                position.z = Mathf.Lerp(minimumRoofPoint.y, maximumRoofPoint.y, faceUv.y);
                position.y = volume.numberOfFloors * data.floorHeight + detail.faceHeight;
            }

            Quaternion userRotation = Quaternion.Euler(detail.userRotation);
            int        vertexCount  = detail.mesh.vertexCount;
            Vector3[]  verts        = new Vector3[vertexCount];
            Quaternion rotate       = faceAngle * userRotation;
            for (int i = 0; i < vertexCount; i++)
            {
                Vector3 sourceVertex = Vector3.Scale(detail.mesh.vertices[i], detail.scale);
                Vector3 outputVertex = (rotate) * sourceVertex + position;
                verts[i] = outputVertex;
            }
            mesh.AddData(verts, detail.mesh.uv, detail.mesh.triangles, d);
            detail.worldPosition = position;
            detail.worldRotation = rotate;

            if (detail.material.mainTexture != null)
            {
#if UNITY_EDITOR
                string          texturePath     = AssetDatabase.GetAssetPath(detail.material.mainTexture);
                TextureImporter textureImporter = (TextureImporter)AssetImporter.GetAtPath(texturePath);

                if (!textureImporter.isReadable)
                {
                    Debug.LogWarning("The texture you have selected is not readable. Cannot render");
                    return(exportObject);
                }

                detailTextures.Add((Texture2D)detail.material.mainTexture);
                detailSubmeshesWithTextures.Add(d);
#endif
            }
        }

        if (detailtexture != null)
        {
            Object.DestroyImmediate(detailtexture);
        }

        List <Mesh> outputMeshes = new List <Mesh>();
        if (detailSubmeshesWithTextures.Count > 0)
        {
            Rect[] textureRects = BuildrTexturePacker2.Pack(out detailtexture, detailTextures.ToArray(), 512);
            if (detailSubmeshesWithTextures.Count > 0)
            {
                mesh.Atlas(detailSubmeshesWithTextures.ToArray(), textureRects);
            }
            mesh.CollapseSubmeshes();
            mesh.Build();
            int numberOfMeshes = mesh.meshCount;
            for (int i = 0; i < numberOfMeshes; i++)
            {
                outputMeshes.Add(mesh[i].mesh);
            }
        }

        exportObject.detailMeshes = outputMeshes.ToArray();
        exportObject.texture      = detailtexture;
        return(exportObject);

        /*if (detailMat == null)
         *      detailMat = new Material(Shader.Find("Diffuse"));
         *  detailMat.mainTexture = detailtexture;
         *  List<Mesh> outputMeshes = new List<Mesh>();
         *  for (int i = 0; i < numberOfMeshes; i++)
         *  {
         *      outputMeshes.Add(mesh[i].mesh);
         *      GameObject details = new GameObject("details " + i);
         *      details.AddComponent<MeshFilter>().mesh = mesh[i].mesh;
         *      details.AddComponent<MeshRenderer>().sharedMaterial = detailMat;
         *      detailGameobjects.Add(details);
         *  }
         * }
         * //        Debug.Log("BuildR Detail Pack Complete: " + (Time.realtimeSinceStartup - timestart) + " sec");
         * return detailGameobjects.ToArray();*/
    }