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

//                break;

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

        case BuildrData.ColliderGenerationModes.Complex:
            BuildrBuilding.Build(_mesh, _data);
            BuildrRoof.Build(_mesh, _data);
            int numberOfVolumes = _data.plan.numberOfVolumes;
            for (int v = 0; v < numberOfVolumes; v++)
            {
                BuildrInteriors.Build(_mesh, _data, v);
                BuildrStairs.Build(_mesh, _data, v, BuildrStairs.StairModes.Flat, false);
            }
            _mesh.CollapseSubmeshes();
            break;
        }
    }
    public static void Build(DynamicMeshGenericMultiMaterialMesh _mesh, BuildrData _data)
    {
        switch(_data.generateCollider)
        {
                case BuildrData.ColliderGenerationModes.None:
                return;
//                break;

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

                case BuildrData.ColliderGenerationModes.Complex:
                BuildrBuilding.Build(_mesh,_data);
                BuildrRoof.Build(_mesh, _data);
                int numberOfVolumes = _data.plan.numberOfVolumes;
                for(int v = 0; v < numberOfVolumes; v++)
                {
                    BuildrInteriors.Build(_mesh,_data,v);
                    BuildrStairs.Build(_mesh,_data,v,BuildrStairs.StairModes.Flat,false);
                }
                _mesh.CollapseSubmeshes();
                break;
        }
    }
Example #3
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);
    }
    /// <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();*/
    }
    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);
    }
Example #6
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;
        }
    }
Example #7
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();*/
    }