Example #1
0
    private static void AddData(Vector3[] verts, int[] tris, int subMesh, bool flipped)
    {
        int           textureSubmesh = subMesh;
        BuildrTexture texture        = textures[textureSubmesh];
        Vector2       uvScale        = Vector2.one;

        if (texture.tiled)
        {
            uvScale.x = (1.0f / texture.textureUnitSize.x);
            uvScale.y = (1.0f / texture.textureUnitSize.y);
            if (texture.patterned)
            {
                Vector2 uvunits = texture.tileUnitUV;
                uvScale.x = Mathf.Max(Mathf.Floor(uvScale.x / uvunits.x), 0) * uvunits.x;
                uvScale.y = Mathf.Max(Mathf.Floor(uvScale.y / uvunits.y), 0) * uvunits.y;
            }
        }

        int numberOfVerts = verts.Length;

        Vector2[] uvs = new Vector2[numberOfVerts];
        for (int i = 0; i < numberOfVerts; i++)
        {
            uvs[i] = new Vector2(verts[i].x * uvScale.x, verts[i].z * uvScale.y);
            if (flipped)
            {
                Vector2 flippedUV = new Vector2(uvs[i].y, uvs[i].x);
                uvs[i] = flippedUV;
            }
        }

        mesh.AddData(verts, uvs, tris, textureSubmesh);
    }
Example #2
0
 private static void AddPlane(BuildrRoofDesign design, Vector3 w0, Vector3 w1, Vector3 w2, Vector3 w3, int subMesh, bool flipped)
 {
     int textureSubmesh = subMesh;
     BuildrTexture texture = textures[textureSubmesh];
     Vector2 uvSize = Vector2.one;
     if (texture.tiled)
     {
         float planeWidth = Vector3.Distance(w0, w1);
         float planeHeight = Vector3.Distance(w0, w2);
         uvSize = new Vector2(planeWidth * (1.0f / texture.textureUnitSize.x), planeHeight * (1.0f / texture.textureUnitSize.y));
         if (texture.patterned)
         {
             Vector2 uvunits = texture.tileUnitUV;
             uvSize.x = Mathf.Ceil(uvSize.x / uvunits.x) * uvunits.x;
             uvSize.y = Mathf.Ceil(uvSize.y / uvunits.y) * uvunits.y;
         }
     }
     else
     {
         uvSize.x = texture.tiledX;
         uvSize.y = texture.tiledY;
     }
     if (!flipped)
     {
         mesh.AddPlane(w0, w1, w2, w3, Vector2.zero, uvSize, textureSubmesh);
     }
     else
     {
         uvSize = new Vector2(uvSize.y, uvSize.x);
         mesh.AddPlane(w0, w1, w2, w3, Vector2.zero, uvSize, textureSubmesh);
     }
 }
    private void CheckData()
    {
        XmlNodeList xmlTextures = null;

        if (File.Exists(textureFilePath))
        {
            XmlDocument  xml = new XmlDocument();
            StreamReader sr  = new StreamReader(textureFilePath);
            xml.LoadXml(sr.ReadToEnd());
            sr.Close();
            xmlTextures = xml.SelectNodes("data/textures/texture");
        }

        if (xmlTextures != null)
        {
            textures.Clear();
            foreach (XmlNode node in xmlTextures)
            {
                string        filepath = node["filepath"].FirstChild.Value;
                string[]      splits   = filepath.Split(filenameDelimiters);
                BuildrTexture bTexture = new BuildrTexture(splits[splits.Length - 1]);
                Texture2D     texture  = (Texture2D)AssetDatabase.LoadAssetAtPath(filepath, typeof(Texture2D));
                bTexture.texture   = texture;
                bTexture.tiled     = node["tiled"].FirstChild.Value == "True";
                bTexture.patterned = node["patterned"].FirstChild.Value == "True";
                Vector2 tileUnitUV;
                tileUnitUV.x        = float.Parse(node["tileUnitUVX"].FirstChild.Value);
                tileUnitUV.y        = float.Parse(node["tileUnitUVY"].FirstChild.Value);
                bTexture.tileUnitUV = tileUnitUV;

                Vector2 textureUnitSize;
                textureUnitSize.x        = float.Parse(node["textureUnitSizeX"].FirstChild.Value);
                textureUnitSize.y        = float.Parse(node["textureUnitSizeY"].FirstChild.Value);
                bTexture.textureUnitSize = textureUnitSize;

                bTexture.tiledX = int.Parse(node["tiledX"].FirstChild.Value);
                bTexture.tiledY = int.Parse(node["tiledY"].FirstChild.Value);

                bTexture.door   = node["door"].FirstChild.Value == "True";
                bTexture.window = node["window"].FirstChild.Value == "True";
                bTexture.wall   = node["wall"].FirstChild.Value == "True";
                bTexture.roof   = node["roof"].FirstChild.Value == "True";

                textures.Add(bTexture);
            }
        }

        /*else
         * {
         *  GenerateData();
         * }*/
    }
    private void CheckData()
    {
        XmlNodeList xmlTextures = null;

        if (File.Exists(textureFilePath))
        {
            XmlDocument xml = new XmlDocument();
            StreamReader sr = new StreamReader(textureFilePath);
            xml.LoadXml(sr.ReadToEnd());
            sr.Close();
            xmlTextures = xml.SelectNodes("data/textures/texture");
        }

        if (xmlTextures != null)
        {
            textures.Clear();
            foreach (XmlNode node in xmlTextures)
            {
                string filepath = node["filepath"].FirstChild.Value;
                string[] splits = filepath.Split(filenameDelimiters);
                BuildrTexture bTexture = new BuildrTexture(splits[splits.Length - 1]);
                Texture2D texture = (Texture2D)AssetDatabase.LoadAssetAtPath(filepath, typeof(Texture2D));
                bTexture.texture = texture;
                bTexture.tiled = node["tiled"].FirstChild.Value == "True";
                bTexture.patterned = node["patterned"].FirstChild.Value == "True";
                Vector2 tileUnitUV;
                tileUnitUV.x = float.Parse(node["tileUnitUVX"].FirstChild.Value);
                tileUnitUV.y = float.Parse(node["tileUnitUVY"].FirstChild.Value);
                bTexture.tileUnitUV = tileUnitUV;

                Vector2 textureUnitSize;
                textureUnitSize.x = float.Parse(node["textureUnitSizeX"].FirstChild.Value);
                textureUnitSize.y = float.Parse(node["textureUnitSizeY"].FirstChild.Value);
                bTexture.textureUnitSize = textureUnitSize;

                bTexture.tiledX = int.Parse(node["tiledX"].FirstChild.Value);
                bTexture.tiledY = int.Parse(node["tiledY"].FirstChild.Value);

                bTexture.door = node["door"].FirstChild.Value == "True";
                bTexture.window = node["window"].FirstChild.Value == "True";
                bTexture.wall = node["wall"].FirstChild.Value == "True";
                bTexture.roof = node["roof"].FirstChild.Value == "True";

                textures.Add(bTexture);
            }
        }
        /*else
        {
            GenerateData();
        }*/
    }
Example #5
0
    public void RemoveTexture(BuildrTexture bTexture)
    {
        int bTextureIndex = textures.IndexOf(bTexture);

        textures.Remove(bTexture);

        foreach (BuildrFacadeDesign facade in facades)
        {
            int numberOfFacadeTextures = facade.textureValues.Length;
            for (int i = 0; i < numberOfFacadeTextures; i++)
            {
                if (facade.textureValues[i] >= bTextureIndex && facade.textureValues[i] > 0)
                {
                    facade.textureValues[i]--;
                }
            }

            BuildrBay bay = facade.simpleBay;
            int       numberOfBayTextures = bay.textureValues.Length;
            for (int i = 0; i < numberOfBayTextures; i++)
            {
                if (bay.textureValues[i] >= bTextureIndex && bay.textureValues[i] > 0)
                {
                    bay.textureValues[i]--;
                }
            }
        }
        foreach (BuildrRoofDesign roof in roofs)
        {
            int numberOfRoofTextures = roof.textureValues.Length;
            for (int i = 0; i < numberOfRoofTextures; i++)
            {
                if (roof.textureValues[i] >= bTextureIndex && roof.textureValues[i] > 0)
                {
                    roof.textureValues[i]--;
                }
            }
        }
        foreach (BuildrBay bay in bays)
        {
            int numberOfBayTextures = bay.textureValues.Length;
            for (int i = 0; i < numberOfBayTextures; i++)
            {
                if (bay.textureValues[i] >= bTextureIndex && bay.textureValues[i] > 0)
                {
                    bay.textureValues[i]--;
                }
            }
        }
    }
Example #6
0
    private static void ImportTextures(XmlDocument xml, BuildrData data)
    {
        foreach (XmlNode node in xml.SelectNodes("buildr/textures/texture"))
        {
            BuildrTexture texture = new BuildrTexture("");
            data.textures.Add(texture);

            texture.name = node["name"].FirstChild.Value;
            texture.tiled = node["tiled"].FirstChild.Value == valueTrue;
            texture.patterned = node["patterned"].FirstChild.Value == valueTrue;
            texture.texture = (Texture2D)AssetDatabase.LoadAssetAtPath(node["texture"].FirstChild.Value, typeof(Texture2D));
            texture.tileUnitUV = new Vector2(float.Parse(node["tileUnitUV"]["x"].FirstChild.Value), float.Parse(node["tileUnitUV"]["y"].FirstChild.Value));
            texture.textureUnitSize = new Vector2(float.Parse(node["textureUnitSize"]["x"].FirstChild.Value), float.Parse(node["textureUnitSize"]["y"].FirstChild.Value));
        }
    }
Example #7
0
    private static void Steeple(BuildrVolume volume, BuildrRoofDesign design)
    {
        BuildrPlan area = data.plan;
        int numberOfFloors = volume.numberOfFloors;
        float floorHeight = data.floorHeight;
        Vector3 volumeFloorHeight = Vector3.up * (numberOfFloors * floorHeight);
        Vector3 ridgeVector = Vector3.up * design.height;

        int numberOfVolumePoints = volume.points.Count;
        Vector3[] basePoints = new Vector3[numberOfVolumePoints];
        Vector3 centrePoint = Vector3.zero;
        for (int l = 0; l < numberOfVolumePoints; l++)
        {
            basePoints[l] = area.points[volume.points[l]].vector3 + volumeFloorHeight;
            centrePoint += area.points[volume.points[l]].vector3;
        }
        centrePoint = (centrePoint / numberOfVolumePoints) + volumeFloorHeight + ridgeVector;
        for (int l = 0; l < numberOfVolumePoints; l++)
        {
            int pointIndexA = l;
            int pointIndexB = (l < numberOfVolumePoints - 1) ? l + 1 : 0;
            Vector3[] verts = new Vector3[3] { basePoints[pointIndexA], basePoints[pointIndexB], centrePoint };
            float uvWdith = Vector3.Distance(basePoints[pointIndexA], basePoints[pointIndexB]);
            float uvHeight = design.height;
            int subMesh = design.GetTexture(BuildrRoofDesign.textureNames.tiles);
            BuildrTexture texture = textures[subMesh];

            if (texture.tiled)
            {
                uvWdith *= (1.0f / texture.textureUnitSize.x);
                uvHeight *= (1.0f / texture.textureUnitSize.y);
                if (texture.patterned)
                {
                    Vector2 uvunits = texture.tileUnitUV;
                    uvWdith = Mathf.Ceil(uvWdith / uvunits.x) * uvunits.x;
                    uvHeight = Mathf.Ceil(uvHeight / uvunits.y) * uvunits.y;
                }
            }
            else
            {
                uvWdith = texture.tiledX;
                uvHeight = texture.tiledY;
            }
            Vector2[] uvs = new Vector2[3] { new Vector2(-uvWdith / 2, 0), new Vector2(uvWdith / 2, 0), new Vector2(0, uvHeight) };
            int[] tri = new int[3] { 1, 0, 2 };
            AddData(verts, uvs, tri, subMesh);
        }
    }
Example #8
0
    private static void GetTextures(BuildrData data)
    {
        //Load in textures from the RESOURCES folder
        wallTexture         = new BuildrTexture("wall");//wall
        wallTexture.texture = (Texture2D)Resources.Load("Textures/BrickSmallBrown0078_2_S");
        data.textures.Add(wallTexture);

        windowTexture         = new BuildrTexture("window");//window
        windowTexture.texture = (Texture2D)Resources.Load("Textures/WindowsHouseOld0260_S");
        data.textures.Add(windowTexture);

        roofTexture         = new BuildrTexture("roof");//roof
        roofTexture.texture = (Texture2D)Resources.Load("Textures/RooftilesMetal0012_2_S");
        data.textures.Add(roofTexture);

        doorTexture         = new BuildrTexture("door");//door
        doorTexture.texture = (Texture2D)Resources.Load("Textures/DoorsWoodPanelled0124_S");
        data.textures.Add(doorTexture);
    }
 private void GenerateData()
 {
     string[] paths = Directory.GetFiles("Assets/Buildr/Textures");
     textures.Clear();
     foreach (string path in paths)
     {
         if (path.Contains(".meta"))
         {
             continue;
         }
         Texture2D texture = (Texture2D)AssetDatabase.LoadAssetAtPath(path, typeof(Texture2D));
         if (texture != null)
         {
             string[]      splits   = path.Split(filenameDelimiters);
             BuildrTexture bTexture = new BuildrTexture(splits[splits.Length - 1]);
             bTexture.texture = texture;
             textures.Add(bTexture);
         }
     }
 }
Example #10
0
    public void UpdateTextures()
    {
        int             numberOfMeshes    = fullMesh.meshCount;
        int             numberOfMaterials = data.textures.Count;
        List <Material> buildMaterials    = new List <Material>(numberOfMaterials);

        for (int i = 0; i < numberOfMeshes; i++)
        {
            buildMaterials.Clear();
            for (int m = 0; m < numberOfMaterials; m++)
            {
                if (!fullMesh[i].SubmeshUsed(m))
                {
                    continue;//skip, unused
                }
                BuildrTexture bTexture = data.textures[m];
                buildMaterials.Add(bTexture.usedMaterial);
            }
            meshHolders[i].GetComponent <MeshRenderer>().sharedMaterials = buildMaterials.ToArray();
        }
    }
Example #11
0
    public BuildrTexture Duplicate(string newName)
    {
        BuildrTexture newTexture = new BuildrTexture(newName);

        newTexture.tiled              = true;
        newTexture.patterned          = false;
        newTexture.tileUnitUV         = _tileUnitUV;
        newTexture.textureUnitSize    = _textureUnitSize;
        newTexture.tiledX             = tiledX;
        newTexture.tiledY             = tiledY;
        newTexture.maxUVTile          = maxUVTile;
        newTexture.material           = new Material(material);
        newTexture.tiledTexture       = tiledTexture;
        newTexture.door               = door;
        newTexture.window             = window;
        newTexture.wall               = wall;
        newTexture.roof               = roof;
        newTexture.proceduralMaterial = _proceduralMaterial;
        newTexture.userMaterial       = _userMaterial;

        return(newTexture);
    }
Example #12
0
    private static void AddPlane(Vector3 w0, Vector3 w1, Vector3 w2, Vector3 w3, int subMesh, bool flipped, Vector2 facadeUVStart, Vector2 facadeUVEnd)
    {
        int           textureSubmesh = subMesh;
        BuildrTexture texture        = textures[textureSubmesh];
        Vector2       uvStart        = facadeUVStart;
        Vector2       uvEnd          = facadeUVEnd;

        if (texture.tiled)
        {
            uvStart = new Vector2(facadeUVStart.x * (1.0f / texture.textureUnitSize.x), facadeUVStart.y * (1.0f / texture.textureUnitSize.y));
            uvEnd   = new Vector2(facadeUVEnd.x * (1.0f / texture.textureUnitSize.x), facadeUVEnd.y * (1.0f / texture.textureUnitSize.y));
            if (texture.patterned)
            {
                Vector2 uvunits = texture.tileUnitUV;
                uvStart.x = Mathf.Max(Mathf.Floor(uvStart.x / uvunits.x), 0) * uvunits.x;
                uvStart.y = Mathf.Max(Mathf.Floor(uvStart.y / uvunits.y), 0) * uvunits.y;
                uvEnd.x   = Mathf.Max(Mathf.Ceil(uvEnd.x / uvunits.x), 1) * uvunits.x;
                uvEnd.y   = Mathf.Max(Mathf.Ceil(uvEnd.y / uvunits.y), 1) * uvunits.y;
            }
        }
        else
        {
            uvStart = Vector2.zero;
            uvEnd.x = texture.tiledX;
            uvEnd.y = texture.tiledY;
        }

        if (!flipped)
        {
            mesh.AddPlane(w2, w3, w0, w1, uvStart, uvEnd, textureSubmesh);
        }
        else
        {
            uvStart = new Vector2(uvStart.y, uvStart.x);
            uvEnd   = new Vector2(uvEnd.y, uvEnd.x);
            mesh.AddPlane(w3, w1, w2, w0, uvStart, uvEnd, textureSubmesh);
        }
    }
Example #13
0
    private static void FlatRoof(BuildrVolume volume, BuildrRoofDesign design)
    {
        BuildrPlan area = data.plan;
        int volumeIndex = area.volumes.IndexOf(volume);
        int numberOfVolumePoints = volume.points.Count;
        int numberOfFloors = volume.numberOfFloors;
        float floorHeight = data.floorHeight;
        Vector3 volumeFloorHeight = Vector3.up * (numberOfFloors * floorHeight);

        //add top base of the flat roof
        Vector3[] newEndVerts = new Vector3[numberOfVolumePoints];
        Vector2[] newEndUVs = new Vector2[numberOfVolumePoints];
        int[] tris = new List<int>(area.GetTrianglesBySectorBase(volumeIndex)).ToArray();
        int roofTextureID = design.GetTexture(BuildrRoofDesign.textureNames.floor);
        BuildrTexture texture = data.textures[roofTextureID];
        for (int i = 0; i < numberOfVolumePoints; i++)
        {
            Vector2z point = area.points[volume.points[i]];
            newEndVerts[i] = point.vector3 + volumeFloorHeight;
            newEndUVs[i] = new Vector2(point.vector2.x / texture.textureUnitSize.x, point.vector2.y / texture.textureUnitSize.y);
        }

        AddData(newEndVerts, newEndUVs, tris, design.GetTexture(BuildrRoofDesign.textureNames.floor));
    }
    public BuildrTexture Duplicate(string newName)
    {
        BuildrTexture newTexture = new BuildrTexture(newName);

        newTexture.tiled = true;
        newTexture.patterned = false;
        newTexture.tileUnitUV = _tileUnitUV;
        newTexture.textureUnitSize = _textureUnitSize;
        newTexture.tiledX = tiledX;
        newTexture.tiledY = tiledY;
        newTexture.maxUVTile = maxUVTile;
        newTexture.material = new Material(material);
        newTexture.tiledTexture = tiledTexture;
        newTexture.door = door;
        newTexture.window = window;
        newTexture.wall = wall;
        newTexture.roof = roof;
        newTexture.proceduralMaterial = _proceduralMaterial;
        newTexture.userMaterial = _userMaterial;

        return newTexture;
    }
Example #15
0
    public static void Pack(BuildrData data)
    {
        data.texturesNotPacked.Clear();
        data.texturesPacked.Clear();

        int numberOfTextures           = data.textures.Count;
        List <Texture2D> useTextures   = new List <Texture2D>(numberOfTextures);
        List <int>       texturePacked = new List <int>();

        for (int t = 0; t < numberOfTextures; t++)
        {
            BuildrTexture texture = data.textures[t];

            //Debug.Log(texture.name+" "+texture.tiled);
            if (texture.tiled)
            {
                int   textureWidth        = texture.texture.width;
                int   textureHeight       = texture.texture.height;
                int   targetTextureWidth  = Mathf.RoundToInt(textureWidth * texture.maxUVTile.x);
                int   targetTextureHeight = Mathf.RoundToInt(textureHeight * texture.maxUVTile.y);
                float resizeToLargest     = Mathf.Min((float)MAX_SINGLE_TEXTURE_SIZE / (float)targetTextureWidth, (float)MAX_SINGLE_TEXTURE_SIZE / (float)targetTextureHeight, 1);        //ensure texture fits smallest size
                int   useTextureWidth     = Mathf.RoundToInt(resizeToLargest * targetTextureWidth);
                int   useTextureHeight    = Mathf.RoundToInt(resizeToLargest * targetTextureHeight);

                if (useTextureWidth == 0 || useTextureHeight == 0)         //texture no used on model
                {
                    data.texturesNotPacked.Add(t);
                    continue;
                }
                Texture2D useTexture = new Texture2D(useTextureWidth, useTextureHeight);

                Color32[] textureBlock = texture.texture.GetPixels32();
                Color32[] useBlock     = new Color32[useTextureWidth * useTextureHeight];
                //paint the textures onto a new texture canvas
                for (int x = 0; x < useTextureWidth; x++)
                {
                    for (int y = 0; y < useTextureHeight; y++)
                    {
                        int tx = Mathf.RoundToInt((x / resizeToLargest) % (textureWidth - 1));
                        int ty = Mathf.RoundToInt((y / resizeToLargest) % (textureHeight - 1));

                        int useIndex = x + y * useTextureWidth;
                        int tIndex   = tx + ty * textureWidth;
                        useBlock[useIndex] = textureBlock[tIndex];
                    }
                }
                useTexture.SetPixels32(useBlock);
                useTexture.Apply();
                useTexture.Compress(true);
                useTextures.Add(useTexture);
                texturePacked.Add(t);
                //Debug.Log(texture.name+" "+useTextureWidth+" "+useTextureHeight);
            }
            else
            {
                int       useTextureWidth  = texture.texture.width;
                int       useTextureHeight = texture.texture.height;
                Texture2D useTexture       = new Texture2D(useTextureWidth, useTextureHeight);
                useTexture.SetPixels32(texture.texture.GetPixels32());
                useTexture.Apply();
                useTexture.Compress(true);
                useTextures.Add(useTexture);
                texturePacked.Add(t);
                //Debug.Log(texture.name+" "+useTextureWidth+" "+useTextureHeight);
            }
        }

        Texture2D textureAtlas = new Texture2D(1, 1);

        Rect[] outputRect = textureAtlas.PackTextures(useTextures.ToArray(), PADDING, PACKED_SIZE, false);

        //remove textures from memory
        if (data.textureAtlas != null)
        {
            Object.DestroyImmediate(data.textureAtlas);
        }

        while (useTextures.Count > 0)
        {
            Object.DestroyImmediate(useTextures[0]);
            useTextures.RemoveAt(0);
        }

        data.textureAtlas   = textureAtlas;
        data.texturesPacked = texturePacked;
        data.atlasCoords    = outputRect;

        System.GC.Collect();
    }
 private void GenerateData()
 {
     string[] paths = Directory.GetFiles("Assets/Buildr/Textures");
     textures.Clear();
     foreach (string path in paths)
     {
         if (path.Contains(".meta")) continue;
         Texture2D texture = (Texture2D)AssetDatabase.LoadAssetAtPath(path, typeof(Texture2D));
         if (texture != null)
         {
             string[] splits = path.Split(filenameDelimiters);
             BuildrTexture bTexture = new BuildrTexture(splits[splits.Length - 1]);
             bTexture.texture = texture;
             textures.Add(bTexture);
         }
     }
 }
Example #17
0
    private static void Sawtooth(BuildrVolume volume, BuildrRoofDesign design)
    {
        BuildrPlan area = data.plan;
        int numberOfFloors = volume.numberOfFloors;
        float floorHeight = data.floorHeight;
        Vector3 volumeFloorHeight = Vector3.up * (numberOfFloors * floorHeight);
        Vector3 ridgeVector = Vector3.up * design.height;

        int[] pointIndexes = new int[4];
        switch (design.direction)
        {
            case 0:
                pointIndexes = new int[4] { 0, 1, 2, 3 };
                break;
            case 1:
                pointIndexes = new int[4] { 1, 2, 3, 0 };
                break;
            case 2:
                pointIndexes = new int[4] { 2, 3, 0, 1 };
                break;
            case 3:
                pointIndexes = new int[4] { 3, 0, 1, 2 };
                break;
        }
        Vector3[] basepoints = new Vector3[4];
        Vector3[] points = new Vector3[6];

        for (int i = 0; i < design.sawtoothTeeth; i++)
        {

            Vector3 toothBaseMovementA = (area.points[volume.points[pointIndexes[3]]].vector3 - area.points[volume.points[pointIndexes[0]]].vector3).normalized;
            float roofDepthA = Vector3.Distance(area.points[volume.points[pointIndexes[3]]].vector3, area.points[volume.points[pointIndexes[0]]].vector3);
            float toothDepthA = roofDepthA / design.sawtoothTeeth;
            Vector3 toothVectorA = toothBaseMovementA * toothDepthA;

            Vector3 toothBaseMovementB = (area.points[volume.points[pointIndexes[2]]].vector3 - area.points[volume.points[pointIndexes[1]]].vector3).normalized;
            float roofDepthB = Vector3.Distance(area.points[volume.points[pointIndexes[2]]].vector3, area.points[volume.points[pointIndexes[1]]].vector3);
            float toothDepthB = roofDepthB / design.sawtoothTeeth;
            Vector3 toothVectorB = toothBaseMovementB * toothDepthB;

            basepoints[0] = area.points[volume.points[pointIndexes[0]]].vector3 + toothVectorA * i;
            basepoints[1] = area.points[volume.points[pointIndexes[1]]].vector3 + toothVectorB * i;
            basepoints[2] = basepoints[1] + toothVectorB;
            basepoints[3] = basepoints[0] + toothVectorA;

            points[0] = basepoints[0] + volumeFloorHeight;
            points[1] = basepoints[1] + volumeFloorHeight;
            points[2] = basepoints[2] + volumeFloorHeight;
            points[3] = basepoints[3] + volumeFloorHeight;
            points[4] = basepoints[2] + volumeFloorHeight + ridgeVector;
            points[5] = basepoints[3] + volumeFloorHeight + ridgeVector;

            //top
            int subMeshTop = design.GetTexture(BuildrRoofDesign.textureNames.tiles);
            bool flippedTop = design.IsFlipped(BuildrRoofDesign.textureNames.tiles);
            AddPlane(design, points[0], points[1], points[5], points[4], subMeshTop, flippedTop);

            //window
            int subMeshWindow = design.GetTexture(BuildrRoofDesign.textureNames.window);
            bool flippedWindow = design.IsFlipped(BuildrRoofDesign.textureNames.window);
            AddPlane(design, points[2], points[3], points[4], points[5], subMeshWindow, flippedWindow);

            //sides
            Vector3[] vertsA = new Vector3[3] { points[1], points[2], points[4] };
            Vector3[] vertsB = new Vector3[3] { points[0], points[3], points[5] };
            float uvWdith = Vector3.Distance(points[0], points[3]);
            float uvHeight = design.height;
            int subMesh = design.GetTexture(BuildrRoofDesign.textureNames.wall);
            BuildrTexture texture = textures[subMesh];

            if (texture.tiled)
            {
                uvWdith *= (1.0f / texture.textureUnitSize.x);
                uvHeight *= (1.0f / texture.textureUnitSize.y);
                if (texture.patterned)
                {
                    Vector2 uvunits = texture.tileUnitUV;
                    uvWdith = Mathf.Ceil(uvWdith / uvunits.x) * uvunits.x;
                    uvHeight = Mathf.Ceil(uvHeight / uvunits.y) * uvunits.y;
                }
            }
            else
            {
                uvWdith = texture.tiledX;
                uvHeight = texture.tiledY;
            }

            Vector2[] uvs = new Vector2[3] { new Vector2(0, 0), new Vector2(uvWdith, 0), new Vector2(uvWdith, uvHeight) };
            int[] triA = new int[3] { 1, 0, 2 };
            int[] triB = new int[3] { 0, 1, 2 };
            AddData(vertsA, uvs, triA, subMesh);
            AddData(vertsB, uvs, triB, subMesh);

        }
    }
    private static void GetTextures(BuildrData data)
    {
        List<BuildrTexture> walltextures = new List<BuildrTexture>();
        List<BuildrTexture> windowtextures = new List<BuildrTexture>();
        List<BuildrTexture> doortextures = new List<BuildrTexture>();
        List<BuildrTexture> rooftextures = new List<BuildrTexture>();
        XmlNodeList xmlTextures = null;
        string textureFilePath = data.generatorConstraints.texturePackXML;

        if (File.Exists(textureFilePath))
        {
            XmlDocument xml = new XmlDocument();
            StreamReader sr = new StreamReader(textureFilePath);
            xml.LoadXml(sr.ReadToEnd());
            sr.Close();
            xmlTextures = xml.SelectNodes("data/textures/texture");

            if (xmlTextures == null)
                return;

            foreach (XmlNode node in xmlTextures)
            {
                string filepath = node["filepath"].FirstChild.Value;
                string[] splits = filepath.Split(filenameDelimiters);
                BuildrTexture bTexture = new BuildrTexture(splits[splits.Length - 1]);
        #if UNITY_EDITOR
                Texture2D texture = (Texture2D)AssetDatabase.LoadAssetAtPath(filepath, typeof(Texture2D));
        #else
                Texture2D texture = new WWW (filepath).texture;
        #endif
                bTexture.texture = texture;
                bTexture.tiled = node["tiled"].FirstChild.Value == "True";
                bTexture.patterned = node["patterned"].FirstChild.Value == "True";
                Vector2 tileUnitUV;
                tileUnitUV.x = float.Parse(node["tileUnitUVX"].FirstChild.Value);
                tileUnitUV.y = float.Parse(node["tileUnitUVY"].FirstChild.Value);
                bTexture.tileUnitUV = tileUnitUV;

                Vector2 textureUnitSize;
                textureUnitSize.x = float.Parse(node["textureUnitSizeX"].FirstChild.Value);
                textureUnitSize.y = float.Parse(node["textureUnitSizeY"].FirstChild.Value);
                bTexture.textureUnitSize = textureUnitSize;

                bTexture.tiledX = int.Parse(node["tiledX"].FirstChild.Value);
                bTexture.tiledY = int.Parse(node["tiledY"].FirstChild.Value);

                bTexture.door = node["door"].FirstChild.Value == "True";
                bTexture.window = node["window"].FirstChild.Value == "True";
                bTexture.wall = node["wall"].FirstChild.Value == "True";
                bTexture.roof = node["roof"].FirstChild.Value == "True";

                if (bTexture.wall) walltextures.Add(bTexture);
                if (bTexture.window) windowtextures.Add(bTexture);
                if (bTexture.door) doortextures.Add(bTexture);
                if (bTexture.roof) rooftextures.Add(bTexture);
            }
        }

        RandomGen rgen = data.generatorConstraints.rgen;
        wallTexture = walltextures[rgen.OutputRange(0, walltextures.Count - 1)];//wall
        data.textures.Add(wallTexture);

        windowTexture = windowtextures[rgen.OutputRange(0, windowtextures.Count - 1)];//window
        data.textures.Add(windowTexture);

        roofTexture = rooftextures[rgen.OutputRange(0, rooftextures.Count - 1)];//roof
        data.textures.Add(roofTexture);

        doorTexture = doortextures[rgen.OutputRange(0, doortextures.Count - 1)];//door
        data.textures.Add(doorTexture);

        groundFloorWindowTexture = windowtextures[rgen.OutputRange(0, windowtextures.Count - 1)];//window
        data.textures.Add(groundFloorWindowTexture);
    }
Example #19
0
    public static void InspectorGUI(BuildrEditMode _editMode, BuildrData _data)
    {
        data = _data;
        BuildrTexture[] textures         = data.textures.ToArray();
        int             numberOfTextures = textures.Length;

        selectedTexture = Mathf.Clamp(selectedTexture, 0, numberOfTextures - 1);
        int currentSelectedTexture = selectedTexture;//keep tack of what we had selected to reset fields if changed

        Undo.RecordObject(data, "Texture Modified");

        if (numberOfTextures == 0)
        {
            EditorGUILayout.HelpBox("There are no textures to show", MessageType.Info);
            if (GUILayout.Button("Add New"))
            {
                data.textures.Add(new BuildrTexture("new texture " + numberOfTextures));
                numberOfTextures++;
                selectedTexture = numberOfTextures - 1;
            }
            return;
        }

        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.LabelField("Texture", GUILayout.Width(75));
        string[] textureNames = new string[numberOfTextures];
        for (int t = 0; t < numberOfTextures; t++)
        {
            textureNames[t] = textures[t].name;
        }
        selectedTexture = EditorGUILayout.Popup(selectedTexture, textureNames);
        EditorGUILayout.EndHorizontal();

        BuildrTexture bTexture = textures[selectedTexture];

        EditorGUILayout.BeginHorizontal();

        EditorGUILayout.Space();

        if (GUILayout.Button("Add New", GUILayout.Width(81)))
        {
            data.textures.Add(new BuildrTexture("new texture " + numberOfTextures));
            numberOfTextures++;
            selectedTexture = numberOfTextures - 1;
        }


        if (GUILayout.Button("Duplicate", GUILayout.Width(90)))
        {
            data.textures.Add(bTexture.Duplicate());
            numberOfTextures++;
            selectedTexture = numberOfTextures - 1;
        }

        if (GUILayout.Button("Delete", GUILayout.Width(71)))
        {
            if (EditorUtility.DisplayDialog("Deleting Texture Entry", "Are you sure you want to delete this texture?", "Delete", "Cancel"))
            {
                data.RemoveTexture(bTexture);
                selectedTexture = 0;
                GUI.changed     = true;

                return;
            }
        }

        if (GUILayout.Button("Import", GUILayout.Width(71)))
        {
            string xmlPath = EditorUtility.OpenFilePanel("Select the XML file...", "Assets/BuildR/Exported/", "xml");
            if (xmlPath == "")
            {
                return;
            }
            BuildrXMLImporter.ImportTextures(xmlPath, _data);
            textures        = data.textures.ToArray();
            selectedTexture = 0;
            GUI.changed     = true;
        }

        if (GUILayout.Button("Export", GUILayout.Width(71)))
        {
            string xmlPath = EditorUtility.SaveFilePanel("Export as...", "Assets/BuildR/Exported/", _data.name + "_textureLibrary", "xml");
            if (xmlPath == "")
            {
                return;
            }
            BuildrXMLExporter.ExportTextures(xmlPath, _data);
            GUI.changed = true;
        }
        EditorGUILayout.EndHorizontal();
        EditorGUILayout.Space();

        textures     = data.textures.ToArray();
        textureNames = new string[numberOfTextures];
        for (int t = 0; t < numberOfTextures; t++)
        {
            textureNames[t] = textures[t].name;
        }
        bTexture = textures[selectedTexture];//reassign

        string   textureName = bTexture.name;
        GUIStyle redText     = new GUIStyle(GUI.skin.textField);

        if (textureName.Contains(" "))
        {
            redText.focused.textColor = Color.red;
            textureName = EditorGUILayout.TextField("Name", textureName, redText);
        }
        else
        {
            redText.focused.textColor = defaultCol;
            textureName = EditorGUILayout.TextField("Name", textureName, redText);
        }
        bTexture.name = textureName;

        bool conflictingName = false;

        for (int i = 0; i < textureNames.Length; i++)
        {
            if (selectedTexture != i)
            {
                if (textureNames[i] == bTexture.name)
                {
                    conflictingName = true;
                }
            }
        }

        if (conflictingName)
        {
            EditorGUILayout.HelpBox("You have named this texture the same as another.", MessageType.Warning);
        }


        if (currentSelectedTexture != selectedTexture)
        {
            GUIUtility.hotControl      = 0;
            GUIUtility.keyboardControl = 0;
        }

        bTexture.type = (BuildrTexture.Types)EditorGUILayout.EnumPopup("Type", bTexture.type);

        switch (bTexture.type)
        {
        case BuildrTexture.Types.Basic:

            if (bTexture.texture != null)
            {
                string          texturePath     = AssetDatabase.GetAssetPath(bTexture.texture);
                TextureImporter textureImporter = (TextureImporter)AssetImporter.GetAtPath(texturePath);

                if (!textureImporter.isReadable)
                {
                    EditorGUILayout.HelpBox("The texture you have selected is not readable." + "\nPlease select the readable checkbox under advanced texture settings." + "\nOr move this texture to the BuildR texture folder and reimport.", MessageType.Error);
                }
            }

            //Shader Time
            Shader[]      tempshaders = (Shader[])Resources.FindObjectsOfTypeAll(typeof(Shader));
            List <string> shaderNames = new List <string>(ShaderProperties.NAMES);
            foreach (Shader shader in tempshaders)
            {
                if (!string.IsNullOrEmpty(shader.name) && !shader.name.StartsWith("__") && !shader.name.Contains("hidden"))
                {
                    shaderNames.Add(shader.name);
                }
            }
            int selectedShaderIndex    = shaderNames.IndexOf(bTexture.material.shader.name);
            int newSelectedShaderIndex = EditorGUILayout.Popup("Shader", selectedShaderIndex, shaderNames.ToArray());
            if (selectedShaderIndex != newSelectedShaderIndex)
            {
                bTexture.material.shader = Shader.Find(shaderNames[newSelectedShaderIndex]);
            }

            Shader selectedShader = bTexture.material.shader;
            int    propertyCount  = ShaderUtil.GetPropertyCount(selectedShader);

            for (int s = 0; s < propertyCount; s++)
            {
                ShaderUtil.ShaderPropertyType propertyTpe = ShaderUtil.GetPropertyType(selectedShader, s);
                string shaderPropertyName = ShaderUtil.GetPropertyName(selectedShader, s);
                switch (propertyTpe)
                {
                case ShaderUtil.ShaderPropertyType.TexEnv:
                    Texture shaderTexture    = bTexture.material.GetTexture(shaderPropertyName);
                    Texture newShaderTexture = (Texture)EditorGUILayout.ObjectField(shaderPropertyName, shaderTexture, typeof(Texture), false);
                    if (shaderTexture != newShaderTexture)
                    {
                        bTexture.material.SetTexture(shaderPropertyName, newShaderTexture);
                    }
                    break;

                case ShaderUtil.ShaderPropertyType.Color:
                    Color shaderColor    = bTexture.material.GetColor(shaderPropertyName);
                    Color newShaderColor = EditorGUILayout.ColorField(shaderPropertyName, shaderColor);
                    if (shaderColor != newShaderColor)
                    {
                        bTexture.material.SetColor(shaderPropertyName, newShaderColor);
                    }
                    break;

                case ShaderUtil.ShaderPropertyType.Float:
                    float shaderFloat    = bTexture.material.GetFloat(shaderPropertyName);
                    float newShaderFloat = EditorGUILayout.FloatField(shaderPropertyName, shaderFloat);
                    if (shaderFloat != newShaderFloat)
                    {
                        bTexture.material.SetFloat(shaderPropertyName, newShaderFloat);
                    }
                    break;

                case ShaderUtil.ShaderPropertyType.Range:
                    float shaderRange    = bTexture.material.GetFloat(shaderPropertyName);
                    float rangeMin       = ShaderUtil.GetRangeLimits(selectedShader, s, 1);
                    float rangeMax       = ShaderUtil.GetRangeLimits(selectedShader, s, 2);
                    float newShaderRange = EditorGUILayout.Slider(shaderPropertyName, shaderRange, rangeMin, rangeMax);
                    if (shaderRange != newShaderRange)
                    {
                        bTexture.material.SetFloat(shaderPropertyName, newShaderRange);
                    }
                    break;

                case ShaderUtil.ShaderPropertyType.Vector:
                    Vector3 shaderVector    = bTexture.material.GetVector(shaderPropertyName);
                    Vector3 newShaderVector = EditorGUILayout.Vector3Field(shaderPropertyName, shaderVector);
                    if (shaderVector != newShaderVector)
                    {
                        bTexture.material.SetVector(shaderPropertyName, newShaderVector);
                    }
                    break;
                }
            }

            bool tiled = EditorGUILayout.Toggle("Is Tiled", bTexture.tiled);
            if (tiled != bTexture.tiled)
            {
                bTexture.tiled = tiled;
            }
            if (bTexture.tiled)
            {
                bool patterned = EditorGUILayout.Toggle("Has Pattern", bTexture.patterned);
                if (patterned != bTexture.patterned)
                {
                    bTexture.patterned = patterned;
                }
            }
            else
            {
                bTexture.patterned = false;
            }

            if (bTexture.texture == null)
            {
                return;
            }

            Vector2 textureUnitSize = bTexture.textureUnitSize;
            if (bTexture.tiled)
            {
                EditorGUILayout.BeginHorizontal();
                EditorGUILayout.LabelField("texture width", GUILayout.Width(75)); //, GUILayout.Width(42));
                textureUnitSize.x = EditorGUILayout.FloatField(bTexture.textureUnitSize.x, GUILayout.Width(25));
                EditorGUILayout.LabelField("metres", GUILayout.Width(40));        //, GUILayout.Width(42));
                EditorGUILayout.EndHorizontal();
                EditorGUILayout.BeginHorizontal();
                EditorGUILayout.LabelField("texture height", GUILayout.Width(75));//, GUILayout.Width(42));
                textureUnitSize.y = EditorGUILayout.FloatField(bTexture.textureUnitSize.y, GUILayout.Width(25));
                EditorGUILayout.LabelField("metres", GUILayout.Width(40));
                EditorGUILayout.EndHorizontal();
                if (bTexture.textureUnitSize != textureUnitSize)
                {
                    bTexture.textureUnitSize = textureUnitSize;
                }
            }

            Vector2 tileUnitSize = bTexture.tileUnitUV;
            if (bTexture.patterned)
            {
                float minWidth  = 2 / bTexture.texture.width;
                float minHeight = 2 / bTexture.texture.height;

                EditorGUILayout.BeginHorizontal();
                EditorGUILayout.LabelField("unit width", GUILayout.Width(75));
                float tileUnitSizex = EditorGUILayout.Slider(tileUnitSize.x, minWidth, 1.0f);
                if (tileUnitSizex != tileUnitSize.x)
                {
                    tileUnitSize.x = tileUnitSizex;
                }
                EditorGUILayout.EndHorizontal();
                EditorGUILayout.BeginHorizontal();
                EditorGUILayout.LabelField("unit height", GUILayout.Width(75));
                float tileUnitSizey = EditorGUILayout.Slider(tileUnitSize.y, minHeight, 1.0f);
                if (tileUnitSizey != tileUnitSize.y)
                {
                    tileUnitSize.y = tileUnitSizey;
                }
                EditorGUILayout.EndHorizontal();
                bTexture.tileUnitUV = tileUnitSize;

                EditorGUILayout.Space();
            }

            const int previewTextureUnitSize = 120;
            const int previewTileUnitSize    = 59;
            const int previewTileUnitPadding = 2;
            const int previewPadding         = 25;

            EditorGUILayout.BeginHorizontal();
            if (bTexture.tiled)
            {
                EditorGUILayout.LabelField("1 Metre Squared", GUILayout.Width(previewTextureUnitSize));
            }
            GUILayout.Space(previewPadding);
            if (bTexture.patterned)
            {
                EditorGUILayout.LabelField("Texture Pattern Units", GUILayout.Width(previewTileUnitSize * 2));
            }
            EditorGUILayout.EndHorizontal();
            EditorGUILayout.Space();


            if (Event.current.type == EventType.Repaint)
            {
                texturePreviewPostion = GUILayoutUtility.GetLastRect();
            }

            if (bTexture.tiled)
            {
                Rect previewRect = new Rect(texturePreviewPostion.x, texturePreviewPostion.y, previewTextureUnitSize, previewTextureUnitSize);
                Rect sourceRect  = new Rect(0, 0, (1.0f / textureUnitSize.x), (1.0f / textureUnitSize.y));

                Graphics.DrawTexture(previewRect, bTexture.texture, sourceRect, 0, 0, 0, 0);
            }

            if (bTexture.patterned)
            {
                Rect previewRect = new Rect(previewTextureUnitSize + previewPadding, 0, previewTileUnitSize, previewTileUnitSize);
                Rect sourceRect  = new Rect(0, tileUnitSize.y, tileUnitSize.x, tileUnitSize.y);

                previewRect.x += texturePreviewPostion.x;
                previewRect.y += texturePreviewPostion.y;

                Graphics.DrawTexture(previewRect, bTexture.texture, sourceRect, 0, 0, 0, 0);

                sourceRect.x  += tileUnitSize.x;
                previewRect.x += previewTileUnitSize + previewTileUnitPadding;

                Graphics.DrawTexture(previewRect, bTexture.texture, sourceRect, 0, 0, 0, 0);

                sourceRect.x  += -tileUnitSize.x;
                sourceRect.y  += -tileUnitSize.y;
                previewRect.x += -(previewTileUnitSize + previewTileUnitPadding);
                previewRect.y += previewTileUnitSize + previewTileUnitPadding;

                Graphics.DrawTexture(previewRect, bTexture.texture, sourceRect, 0, 0, 0, 0);

                sourceRect.x  += tileUnitSize.x;
                previewRect.x += previewTileUnitSize + previewTileUnitPadding;

                Graphics.DrawTexture(previewRect, bTexture.texture, sourceRect, 0, 0, 0, 0);
            }

            if (!bTexture.tiled)
            {
                EditorGUILayout.LabelField("Tile texture");

                EditorGUILayout.BeginHorizontal();
                int currentXTiles = bTexture.tiledX;
                GUILayout.Label("tile x", GUILayout.Width(38));
                currentXTiles = EditorGUILayout.IntField(currentXTiles, GUILayout.Width(20));
                if (GUILayout.Button("+", GUILayout.Width(25)))
                {
                    currentXTiles++;
                }
                EditorGUI.BeginDisabledGroup(currentXTiles < 2);
                if (GUILayout.Button("-", GUILayout.Width(25)))
                {
                    currentXTiles--;
                }
                EditorGUI.EndDisabledGroup();
                bTexture.tiledX = currentXTiles;

                int currentYTiles = bTexture.tiledY;
                GUILayout.Label("tile y", GUILayout.Width(38));
                currentYTiles = EditorGUILayout.IntField(currentYTiles, GUILayout.Width(20));
                if (GUILayout.Button("+", GUILayout.Width(25)))
                {
                    currentYTiles++;
                }
                EditorGUI.BeginDisabledGroup(currentYTiles < 2);
                if (GUILayout.Button("-", GUILayout.Width(25)))
                {
                    currentYTiles--;
                }
                EditorGUI.EndDisabledGroup();
                bTexture.tiledY = currentYTiles;
                EditorGUILayout.EndHorizontal();

                GUILayout.Space(10);
                EditorGUILayout.Space();
                if (Event.current.type == EventType.Repaint)
                {
                    texturePreviewPostion = GUILayoutUtility.GetLastRect();
                }

                Rect previewRect = new Rect(texturePreviewPostion.x, texturePreviewPostion.y, previewTextureUnitSize, previewTextureUnitSize);
                Rect sourceRect  = new Rect(0, 0, currentXTiles, currentYTiles);

                Graphics.DrawTexture(previewRect, bTexture.texture, sourceRect, 0, 0, 0, 0);
            }

            GUILayout.Space(previewTextureUnitSize);

            break;

        case BuildrTexture.Types.Substance:

            bTexture.proceduralMaterial = (ProceduralMaterial)EditorGUILayout.ObjectField("Procedural Material", bTexture.proceduralMaterial, typeof(ProceduralMaterial), false);

            if (bTexture.proceduralMaterial != null)
            {
                ProceduralMaterial pMat = bTexture.proceduralMaterial;
                GUILayout.Label(pMat.GetGeneratedTexture(pMat.mainTexture.name), GUILayout.Width(400));
            }
            else
            {
                EditorGUILayout.HelpBox("There is no substance material set.", MessageType.Error);
            }
            break;

        case BuildrTexture.Types.User:
            bTexture.userMaterial = (Material)EditorGUILayout.ObjectField("User Material", bTexture.userMaterial, typeof(Material), false);

            if (bTexture.userMaterial != null)
            {
                Material mat = bTexture.userMaterial;
                GUILayout.Label(mat.mainTexture, GUILayout.Width(400));
            }
            else
            {
                EditorGUILayout.HelpBox("There is no substance material set.", MessageType.Error);
            }
            break;
        }
    }
    /// <summary>
    /// Atlas the specified modifySubmeshes using newTextureCoords and textures.
    /// </summary>
    /// <param name='modifySubmeshes'>
    /// Submeshes indicies to atlas.
    /// </param>
    /// <param name='newTextureCoords'>
    /// New texture coords generated from Pack Textures.
    /// </param>
    /// <param name='textures'>
    /// BuildR Textures library reference.
    /// </param>
    public void Atlas(int[] modifySubmeshes, Rect[] newTextureCoords, BuildrTexture[] textures)
    {
        if (modifySubmeshes.Length == 0)
        {
            Debug.Log("No submeshes to atlas!");
            return;
        }
        List<int> atlasedSubmesh = new List<int>();
        int numberOfSubmeshesToModify = modifySubmeshes.Length;
        for (int s = 0; s < numberOfSubmeshesToModify; s++)
        {
            int submeshIndex = modifySubmeshes[s];
            Rect textureRect = newTextureCoords[s];
            if (!subTriangles.ContainsKey(submeshIndex))
                continue;
            int[] submeshIndices = subTriangles[submeshIndex].ToArray();
            subTriangles.Remove(submeshIndex);
            atlasedSubmesh.AddRange(submeshIndices);

            BuildrTexture bTexture = textures[submeshIndex];
            List<int> ModifiedUVs = new List<int>();
            foreach (int index in submeshIndices)
            {
                if (ModifiedUVs.Contains(index))
                    continue;//don't move the UV more than once
                Vector2 uvCoords = uv[index];
                float xUV = uvCoords.x / bTexture.maxUVTile.x;
                float yUV = uvCoords.y / bTexture.maxUVTile.y;
                if (xUV > 1)
                {
                    bTexture.maxUVTile.x = uvCoords.x;
                    xUV = 1.0f;
                }
                if (yUV > 1)
                {
                    bTexture.maxUVTile.y = uvCoords.y;
                    yUV = 1;
                }

                uvCoords.x = Mathf.Lerp(textureRect.xMin, textureRect.xMax, xUV);
                uvCoords.y = Mathf.Lerp(textureRect.yMin, textureRect.yMax, yUV);

                if (float.IsNaN(uvCoords.x))
                {
                    uvCoords.x = 1;
                }
                if (float.IsNaN(uvCoords.y))
                {
                    uvCoords.y = 1;
                }
                uv[index] = uvCoords;
                ModifiedUVs.Add(index);//keep a record of moved UVs
            }
        }
        subMeshCount = subMeshCount - modifySubmeshes.Length + 1;
        subTriangles.Add(modifySubmeshes[0], atlasedSubmesh);
    }
Example #21
0
//    private static float timestart;

    /// <summary>
    /// Custom BuildR texture packer. Uses the BuildR Data class to create a single texture used by the generated building, taking into account tiling.
    /// </summary>
    /// <param name="data">BuildR Building Data</param>
    public static void Pack(BuildrData data)
    {
//        timestart = Time.realtimeSinceStartup;
        data.texturesNotPacked.Clear();
        data.texturesPacked.Clear();

        int         numberOfTextures       = data.textures.Count;
        List <Rect> packedTexturePositions = new List <Rect>();
        List <int>  texturePacked          = new List <int>();

        for (int t = 0; t < numberOfTextures; t++)
        {
            BuildrTexture texture = data.textures[t];
            if (texture.tiled)
            {
                int   textureWidth        = texture.texture.width;
                int   textureHeight       = texture.texture.height;
                int   targetTextureWidth  = Mathf.RoundToInt(textureWidth * texture.maxUVTile.x);
                int   targetTextureHeight = Mathf.RoundToInt(textureHeight * texture.maxUVTile.y);
                float resizeToLargest     = Mathf.Min((float)MAX_SOURCE_TEXTURE_SIZE / (float)targetTextureWidth, (float)MAX_SOURCE_TEXTURE_SIZE / (float)targetTextureHeight, 1);//ensure texture fits smallest size
                int   useTextureWidth     = Mathf.RoundToInt(resizeToLargest * targetTextureWidth);
                int   useTextureHeight    = Mathf.RoundToInt(resizeToLargest * targetTextureHeight);

                if (useTextureWidth == 0 || useTextureHeight == 0)//texture no used on model
                {
                    data.texturesNotPacked.Add(t);
                    continue;
                }
                packedTexturePositions.Add(new Rect(0, 0, useTextureWidth, useTextureHeight));
                texturePacked.Add(t);
            }
            else
            {
                int useTextureWidth  = texture.texture.width;
                int useTextureHeight = texture.texture.height;
                packedTexturePositions.Add(new Rect(0, 0, useTextureWidth, useTextureHeight));
                texturePacked.Add(t);
            }
        }

        int atlasedTextureWidth = RectanglePack.Pack(packedTexturePositions, ATLAS_PADDING);

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

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

        int textureSize = atlasedTextureWidth * atlasedTextureWidth;

        Color32[] colourArray = new Color32[textureSize];

        //Build colour array
        for (int t = 0; t < numberOfTextures; t++)
        {
            BuildrTexture texture             = data.textures[t];
            Rect          packedPosition      = packedTexturePositions[t];
            int           targetTextureWidth  = (int)packedPosition.width;
            int           targetTextureHeight = (int)packedPosition.height;
            int           sourceTextureWidth  = texture.texture.width;
            int           sourceTextureHeight = texture.texture.height;
//            int sourceTextureSize = sourceTextureWidth * sourceTextureHeight;
            int       paintTextureWidth  = Mathf.RoundToInt(targetTextureWidth / (texture.tiled ? texture.maxUVTile.x : texture.tiledX));
            int       paintTextureHeight = Mathf.RoundToInt(targetTextureHeight / (texture.tiled ? texture.maxUVTile.y : texture.tiledY));
            int       paintTextureSize   = paintTextureWidth * paintTextureHeight;
            Color32[] paintColourArray   = TextureScale.NearestNeighbourSample(texture.texture.GetPixels32(), sourceTextureWidth, sourceTextureHeight, paintTextureWidth, paintTextureHeight);

            for (int x = 0; x < targetTextureWidth; x++)
            {
                for (int y = 0; y < targetTextureHeight; y++)
                {
                    int drawX       = Mathf.FloorToInt(x + packedPosition.x);
                    int drawY       = Mathf.FloorToInt(y + packedPosition.y);
                    int colourIndex = drawX + drawY * atlasedTextureWidth;

                    int sx         = x % paintTextureWidth;
                    int sy         = y % paintTextureHeight;
                    int paintIndex = sx + sy * paintTextureWidth;
                    if (paintIndex >= paintTextureSize)
                    {
                        Debug.Log("Source Index too big " + sx + " " + sy + " " + paintTextureWidth + " " + paintTextureSize + " " + texture.maxUVTile + " " + texture.name);
                    }
                    Color32 sourceColour = paintColourArray[paintIndex];
                    if (colourIndex >= textureSize)
                    {
                        Debug.Log("Output Index Too big " + drawX + " " + drawY + " " + colourIndex + " " + textureSize + " " + packedPosition);
                    }
                    colourArray[colourIndex] = sourceColour;
                }
            }
        }

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

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

        //remove textures from memory
        if (data.textureAtlas != null)
        {
            DestroyImmediate(data.textureAtlas);
        }

        data.textureAtlas   = packedTexture;
        data.texturesPacked = texturePacked;
        data.atlasCoords    = RectanglePack.ConvertToUVSpace(packedTexturePositions.ToArray(), atlasedTextureWidth);

        System.GC.Collect();

        //Debug.Log("BuildR Texutre Pack Complete: " + (Time.realtimeSinceStartup - timestart)+" sec");
    }
Example #22
0
    private static void GenerateFacades(BuildrData data)
    {
        RandomGen rgen = constraints.rgen;

        //generate bays
        //blank
        BuildrBay blankBay = new BuildrBay("Blank");

        blankBay.isOpening = false;
        data.bays.Add(blankBay);
        //door
        BuildrBay doorBay = new BuildrBay("Door");

        doorBay.openingHeight      = data.floorHeight * 0.9f;
        doorBay.openingHeightRatio = 0.0f;
        float doorWidth = (doorTexture.texture != null) ? (doorTexture.texture.width / (float)doorTexture.texture.height) * doorBay.openingHeight : doorBay.openingHeight * 0.5f;

        doorBay.openingWidth = doorWidth;
        doorBay.openingDepth = rgen.OutputRange(0.0f, 0.3f);
        doorBay.SetTexture(BuildrBay.TextureNames.OpeningBackTexture, data.textures.IndexOf(doorTexture));
        data.bays.Add(doorBay);
        //ground window
        BuildrBay groundWindow = new BuildrBay("Ground Window");

        groundWindow.openingWidth       = rgen.OutputRange(constraints.openingMinimumWidth, constraints.openingMaximumWidth);
        groundWindow.openingHeight      = rgen.OutputRange(constraints.openingMinimumHeight, Mathf.Min(data.floorHeight, constraints.openingMinimumHeight));
        groundWindow.openingDepth       = rgen.OutputRange(constraints.openingMinimumDepth, constraints.openingMaximumDepth);
        groundWindow.openingHeightRatio = 0.8f;
        data.bays.Add(groundWindow);

        BuildrTexture groundFloorWindowTexture = windowTexture.Duplicate("groundWindowTexture");

        groundFloorWindowTexture.tiled  = false;
        groundFloorWindowTexture.tiledX = Mathf.RoundToInt(groundWindow.openingWidth / groundWindow.openingHeight);
        int groundtextureIndex = data.textures.Count;

        data.textures.Add(groundFloorWindowTexture);
        groundWindow.SetTexture(BuildrBay.TextureNames.OpeningBackTexture, groundtextureIndex);
        //other windows
        BuildrBay windowBay = new BuildrBay("Window");

        data.bays.Add(windowBay);
        //util window
        BuildrBay utilBay = new BuildrBay("Utility Window");

        data.bays.Add(utilBay);

        //generate facades
        BuildrFacadeDesign basicFacadeDesign = new BuildrFacadeDesign("default");

        basicFacadeDesign.simpleBay.openingWidth    = rgen.OutputRange(constraints.openingMinimumWidth, constraints.openingMaximumWidth);
        basicFacadeDesign.simpleBay.openingHeight   = rgen.OutputRange(constraints.openingMinimumHeight, Mathf.Min(data.floorHeight, constraints.openingMinimumHeight));
        basicFacadeDesign.simpleBay.openingDepth    = rgen.OutputRange(constraints.openingMinimumDepth, constraints.openingMaximumDepth);
        basicFacadeDesign.simpleBay.minimumBayWidth = rgen.OutputRange(constraints.minimumBayMaximumWidth, constraints.minimumBayMaximumWidth);
        data.facades.Add(basicFacadeDesign);
        //ground floor with and without door
        BuildrFacadeDesign groundFloorDoor = new BuildrFacadeDesign("Ground Floor With Door");

        groundFloorDoor.type = BuildrFacadeDesign.types.patterned;
        int patternSize = rgen.OutputRange(1, 8);

        for (int i = 0; i < patternSize; i++)
        {
            groundFloorDoor.bayPattern.Add(rgen.output > 0.2f?2:0);
        }
        groundFloorDoor.bayPattern.Insert(rgen.OutputRange(0, patternSize), 1);//insert door into pattern
        data.facades.Add(groundFloorDoor);

        BuildrPlan plan = data.plan;

        for (int v = 0; v < plan.numberOfVolumes; v++)
        {
            BuildrVolume volume         = plan.volumes[v];
            int          numberOfFloors = volume.numberOfFloors;
            volume.styles.Clear();
            for (int f = 0; f < volume.points.Count; f++)
            {
                int facadeIndex = volume.points[f];
                volume.styles.AddStyle(0, facadeIndex, numberOfFloors - 1);
                volume.styles.AddStyle(1, facadeIndex, 1);
            }
        }
    }
    private static void ImportTextures(XmlDocument xml, BuildrData data)
    {
        foreach (XmlNode node in xml.SelectNodes("buildr/textures/texture"))
        {
            BuildrTexture texture = new BuildrTexture("");
            data.textures.Add(texture);

            texture.name = node["name"].FirstChild.Value;
            texture.tiled = node["tiled"].FirstChild.Value == valueTrue;
            texture.patterned = node["patterned"].FirstChild.Value == valueTrue;
            texture.texture = (Texture2D)AssetDatabase.LoadAssetAtPath(node["texture"].FirstChild.Value, typeof(Texture2D));
            texture.tileUnitUV = new Vector2(float.Parse(node["tileUnitUV"]["x"].FirstChild.Value), float.Parse(node["tileUnitUV"]["y"].FirstChild.Value));
            texture.textureUnitSize = new Vector2(float.Parse(node["textureUnitSize"]["x"].FirstChild.Value), float.Parse(node["textureUnitSize"]["y"].FirstChild.Value));
        }
    }
Example #24
0
    public static void InspectorGUI(BuildrEditMode editMode, BuildrData _data)
    {
        data = _data;
        Undo.RecordObject(data, "Roof Modified");

        BuildrRoofDesign[] roofs = data.roofs.ToArray();
        int numberOfRoofs        = roofs.Length;

        selectedRoof = Mathf.Clamp(selectedRoof, 0, numberOfRoofs - 1);

        if (GUILayout.Button("Add new roof design"))
        {
            data.roofs.Add(new BuildrRoofDesign("new roof " + numberOfRoofs));
            roofs = data.roofs.ToArray();
            numberOfRoofs++;
            selectedRoof = numberOfRoofs - 1;
        }
        if (numberOfRoofs == 0)
        {
            EditorGUILayout.HelpBox("There are no roof designs to show", MessageType.Info);
            return;
        }

        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.LabelField("Design: ", GUILayout.Width(75));
        string[] roofNames = new string[numberOfRoofs];
        for (int f = 0; f < numberOfRoofs; f++)
        {
            roofNames[f] = roofs[f].name;
        }
        selectedRoof = EditorGUILayout.Popup(selectedRoof, roofNames);

        BuildrRoofDesign bRoof = roofs[selectedRoof];

        EditorGUILayout.EndHorizontal();

        EditorGUILayout.BeginHorizontal();
        if (GUILayout.Button("Delete", GUILayout.Width(75)))
        {
            if (EditorUtility.DisplayDialog("Deleting Roof Design Entry", "Are you sure you want to delete this roof?", "Delete", "Cancel"))
            {
                data.RemoveRoofDesign(bRoof);
                selectedRoof = 0;
                GUI.changed  = true;

                return;
            }
        }

        if (GUILayout.Button("Import", GUILayout.Width(71)))
        {
            string xmlPath = EditorUtility.OpenFilePanel("Select the XML file...", "Assets/BuildR/Exported/", "xml");
            if (xmlPath == "")
            {
                return;
            }
            BuildrXMLImporter.ImportRoofs(xmlPath, _data);
            GUI.changed = true;
        }

        if (GUILayout.Button("Export", GUILayout.Width(71)))
        {
            string xmlPath = EditorUtility.SaveFilePanel("Export as...", "Assets/BuildR/Exported/", _data.name + "_roofLibrary", "xml");
            if (xmlPath == "")
            {
                return;
            }
            BuildrXMLExporter.ExportRoofs(xmlPath, _data);
            GUI.changed = true;
        }
        EditorGUILayout.EndHorizontal();

        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.LabelField("Name: ", GUILayout.Width(75));
        bRoof.name = EditorGUILayout.TextField(bRoof.name);
        EditorGUILayout.EndHorizontal();

        //ROOF STYLE
        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.LabelField("Style: ", GUILayout.Width(75));
        BuildrRoofDesign.styles bRoofstyle = (BuildrRoofDesign.styles)EditorGUILayout.EnumPopup(bRoof.style);
        if (bRoofstyle != bRoof.style)
        {
            bRoof.style = bRoofstyle;
        }
        EditorGUILayout.EndHorizontal();

        if (bRoof.style != BuildrRoofDesign.styles.flat && bRoof.style != BuildrRoofDesign.styles.mansard && bRoof.style != BuildrRoofDesign.styles.steepled && bRoof.style != BuildrRoofDesign.styles.hipped)
        {
            EditorGUILayout.HelpBox("Please note that this design can only be used on sections with 4 points." +
                                    "\nComplex sections can only use the Flat, Mansard and Steeple designs.", MessageType.Warning);
        }

        if (bRoof.style != BuildrRoofDesign.styles.flat)
        {
            bRoof.height = Mathf.Max(EditorGUILayout.FloatField("Height", bRoof.height), 0);
        }

        if (bRoof.style == BuildrRoofDesign.styles.mansard)
        {
            bRoof.floorDepth = Mathf.Max(EditorGUILayout.FloatField("Base Depth", bRoof.floorDepth), 0);
            bRoof.depth      = Mathf.Max(EditorGUILayout.FloatField("Top Depth", bRoof.depth), 0);
        }

        if (bRoof.style == BuildrRoofDesign.styles.barrel)
        {
            bRoof.barrelSegments = Mathf.Max(EditorGUILayout.IntField("Barrel Segments", bRoof.barrelSegments), 3);
        }

        if (bRoof.style == BuildrRoofDesign.styles.barrel || bRoof.style == BuildrRoofDesign.styles.gabled || bRoof.style == BuildrRoofDesign.styles.hipped)
        {
            //two directions of the ridge
            bRoof.direction = Mathf.Clamp(bRoof.direction, 0, 1);
            string[] options = new string[2] {
                "short", "long"
            };
            bRoof.direction = EditorGUILayout.Popup(bRoof.direction, options);
        }

        if (bRoof.style == BuildrRoofDesign.styles.leanto || bRoof.style == BuildrRoofDesign.styles.sawtooth)
        {
            //four directions of the ridge
            bRoof.direction = Mathf.Clamp(bRoof.direction, 0, 3);
            string[] options = new string[4] {
                "left", "up", "right", "down"
            };
            bRoof.direction = EditorGUILayout.Popup(bRoof.direction, options);
        }

        if (bRoof.style == BuildrRoofDesign.styles.sawtooth)
        {
            bRoof.sawtoothTeeth = Mathf.Max(EditorGUILayout.IntField("Number of 'teeth'", bRoof.sawtoothTeeth), 2);
        }

        //PARAPET
        bool bRoofparapet = EditorGUILayout.Toggle("Has Parapet", bRoof.parapet);

        if (bRoofparapet != bRoof.parapet)
        {
            bRoof.parapet = bRoofparapet;
        }
        if (bRoof.parapet)
        {
            float bRoofparapetHeight = Mathf.Max(EditorGUILayout.FloatField("Parapet Width", bRoof.parapetHeight), 0);
            if (bRoofparapetHeight != bRoof.parapetHeight)
            {
                bRoof.parapetHeight = bRoofparapetHeight;
            }
            float bRoofparapetFrontDepth = Mathf.Max(EditorGUILayout.FloatField("Parapet Front Depth", bRoof.parapetFrontDepth), 0);
            if (bRoofparapetFrontDepth != bRoof.parapetFrontDepth)
            {
                bRoof.parapetFrontDepth = bRoofparapetFrontDepth;
            }
            float bRoofparapetBackDepth = Mathf.Max(EditorGUILayout.FloatField("Parapet Back Depth", bRoof.parapetBackDepth), 0);
            if (bRoofparapetBackDepth != bRoof.parapetBackDepth)
            {
                bRoof.parapetBackDepth = bRoofparapetBackDepth;
            }

            if (bRoof.parapetStyle == BuildrRoofDesign.parapetStyles.fancy)//NOT IMPLMENTED...YET...
            {
                EditorGUILayout.HelpBox("This allows you to specify a model mesh that will be used to create a parapet." +
                                        "\nIt should not repeat as Buildr will attempt to repeat the style to fit the length of the facade.", MessageType.Info);
                bRoof.parapetDesign      = (Mesh)EditorGUILayout.ObjectField("Parapet Mesh", bRoof.parapetDesign, typeof(Mesh), false);
                bRoof.parapetDesignWidth = Mathf.Max(EditorGUILayout.FloatField("Parapet Design Width", bRoof.parapetDesignWidth), 0);
            }
        }

        //DORMERS
        if (bRoof.style == BuildrRoofDesign.styles.mansard)
        {
            bool bRoofhasDormers = EditorGUILayout.Toggle("Has Dormers", bRoof.hasDormers);
            if (bRoofhasDormers != bRoof.hasDormers)
            {
                bRoof.hasDormers = bRoofhasDormers;
            }
            if (bRoof.hasDormers)
            {
                float bRoofdormerWidth = Mathf.Max(EditorGUILayout.FloatField("Dormer Width", bRoof.dormerWidth), 0);
                if (bRoofdormerWidth != bRoof.dormerWidth)
                {
                    bRoof.dormerWidth = bRoofdormerWidth;
                }
                float bRoofdormerHeight = Mathf.Clamp(EditorGUILayout.FloatField("Dormer Height", bRoof.dormerHeight), 0, bRoof.height);
                if (bRoofdormerHeight != bRoof.dormerHeight)
                {
                    bRoof.dormerHeight = bRoofdormerHeight;
                }
                float bRoofdormerRoofHeight = Mathf.Clamp(EditorGUILayout.FloatField("Dormer Roof Height", bRoof.dormerRoofHeight), 0, bRoof.dormerHeight);
                if (bRoofdormerRoofHeight != bRoof.dormerRoofHeight)
                {
                    bRoof.dormerRoofHeight = bRoofdormerRoofHeight;
                }
                float bRoofminimumDormerSpacing = Mathf.Max(EditorGUILayout.FloatField("Dormer Minimum Spacing", bRoof.minimumDormerSpacing), 0);
                if (bRoofminimumDormerSpacing != bRoof.minimumDormerSpacing)
                {
                    bRoof.minimumDormerSpacing = bRoofminimumDormerSpacing;
                }
                float bRoofdormerHeightRatio = EditorGUILayout.Slider("Dormer Height Ratio", bRoof.dormerHeightRatio, 0, 1);
                if (bRoofdormerHeightRatio != bRoof.dormerHeightRatio)
                {
                    bRoof.dormerHeightRatio = bRoofdormerHeightRatio;
                }
            }
        }

        //TEXTURES
        int numberOfTextures = data.textures.Count;

        string[] textureNames = new string[numberOfTextures];
        for (int t = 0; t < numberOfTextures; t++)
        {
            textureNames[t] = data.textures[t].name;
        }

        int numberOfTextureSlots = bRoof.numberOfTextures;

        string[] titles = new string[numberOfTextureSlots];
        for (int brt = 0; brt < numberOfTextureSlots; brt++)
        {
            titles[brt] = ((BuildrRoofDesign.textureNames)(brt)).ToString();
        }

        editTextureOnRoof = EditorGUILayout.Popup("Texture Surface:", editTextureOnRoof, titles);

        int selectedRoofTexture = EditorGUILayout.Popup("Selected Texture:", bRoof.textureValues[editTextureOnRoof], textureNames);

        if (selectedRoofTexture != bRoof.textureValues[editTextureOnRoof])
        {
            bRoof.textureValues[editTextureOnRoof] = selectedRoofTexture;
        }
        BuildrTexture bTexture = data.textures[bRoof.textureValues[editTextureOnRoof]];
        Texture2D     texture  = bTexture.texture;

        EditorGUILayout.BeginHorizontal();

        if (texture != null)
        {
            GUILayout.Label(texture, GUILayout.Width(100), GUILayout.Height(100));
        }
        else
        {
            EditorGUILayout.HelpBox("No texture assigned for '" + textureNames[bRoof.textureValues[editTextureOnRoof]] + "', assign one in the Textures menu above", MessageType.Warning);
        }

        bRoof.flipValues[editTextureOnRoof] = EditorGUILayout.Toggle("Flip 90\u00B0", bRoof.flipValues[editTextureOnRoof]);

        EditorGUILayout.EndHorizontal();
    }
    public void RemoveTexture(BuildrTexture bTexture)
    {
        int bTextureIndex = textures.IndexOf(bTexture);
        textures.Remove(bTexture);

        foreach (BuildrFacadeDesign facade in facades)
        {
            int numberOfFacadeTextures = facade.textureValues.Length;
            for (int i = 0; i < numberOfFacadeTextures; i++)
            {
                if (facade.textureValues[i] >= bTextureIndex && facade.textureValues[i] > 0)
                    facade.textureValues[i]--;
            }

            BuildrBay bay = facade.simpleBay;
            int numberOfBayTextures = bay.textureValues.Length;
            for (int i = 0; i < numberOfBayTextures; i++)
            {
                if (bay.textureValues[i] >= bTextureIndex && bay.textureValues[i] > 0)
                    bay.textureValues[i]--;
            }
        }
        foreach (BuildrRoofDesign roof in roofs)
        {
            int numberOfRoofTextures = roof.textureValues.Length;
            for (int i = 0; i < numberOfRoofTextures; i++)
            {
                if (roof.textureValues[i] >= bTextureIndex && roof.textureValues[i] > 0)
                    roof.textureValues[i]--;
            }
        }
        foreach (BuildrBay bay in bays)
        {
            int numberOfBayTextures = bay.textureValues.Length;
            for (int i = 0; i < numberOfBayTextures; i++)
            {
                if (bay.textureValues[i] >= bTextureIndex && bay.textureValues[i] > 0)
                    bay.textureValues[i]--;
            }
        }
    }
Example #26
0
    private static void BuildTextures()
    {
        List <TexturePaintObject> buildSourceTextures = new List <TexturePaintObject>();

        foreach (BuildrTexture btexture in data.textures)//Gather the source textures, resized into Color32 arrays
        {
            TexturePaintObject texturePaintObject = new TexturePaintObject();
            texturePaintObject.pixels = ((Texture2D)btexture.texture).GetPixels32();
            texturePaintObject.width  = btexture.texture.width;
            texturePaintObject.height = btexture.texture.height;
            texturePaintObject.tiles  = new Vector2(btexture.tiledX, btexture.tiledY);
            if (btexture.tiled)
            {
                int resizedTextureWidth  = Mathf.RoundToInt(btexture.textureUnitSize.x * PIXELS_PER_METER * packedScale);
                int resizedTextureHeight = Mathf.RoundToInt(btexture.textureUnitSize.y * PIXELS_PER_METER * packedScale);
                texturePaintObject.pixels = TextureScale.NearestNeighbourSample(texturePaintObject.pixels, texturePaintObject.width, texturePaintObject.height, resizedTextureWidth, resizedTextureHeight);
                texturePaintObject.width  = resizedTextureWidth;
                texturePaintObject.height = resizedTextureHeight;
            }
            else
            {
                texturePaintObject.tiled = false;
            }
            buildSourceTextures.Add(texturePaintObject);
        }
        LogTimer("Gather Source into Arrays");
        TexturePaintObject[] sourceTextures = buildSourceTextures.ToArray();
        textures = data.textures.ToArray();
        BuildrFacadeDesign facadeDesign = data.facades[0];
        BuildrPlan         plan         = data.plan;

        int numberOfVolumes = data.plan.numberOfVolumes;
        int facadeNumber    = 0;

        for (int s = 0; s < numberOfVolumes; s++)
        {
            BuildrVolume volume = plan.volumes[s];
            int          numberOfVolumePoints = volume.points.Count;

            for (int f = 0; f < numberOfVolumePoints; f++)
            {
                if (!volume.renderFacade[f])
                {
                    continue;
                }
                int     indexA, indexB;
                Vector3 p0, p1;
                indexA = f;
                indexB = (f < numberOfVolumePoints - 1) ? f + 1 : 0;
                p0     = plan.points[volume.points[indexA]].vector3;
                p1     = plan.points[volume.points[indexB]].vector3;
                Rect packedPosition = packedTexturePositions[facadeNumber];

                float facadeWidth    = Vector3.Distance(p0, p1);
                int   floorBase      = plan.GetFacadeFloorHeight(s, volume.points[indexA], volume.points[indexB]);
                int   numberOfFloors = volume.numberOfFloors - floorBase;
                if (numberOfFloors < 1)
                {
                    //no facade - adjacent facade is taller and covers this one
                    continue;
                }
                float floorHeight = data.floorHeight;

                BuildrVolumeStylesUnit[] styleUnits = volume.styles.GetContentsByFacade(volume.points[indexA]);
                int        floorPatternSize         = 0;
                List <int> facadePatternReference   = new List <int>();  //this contains a list of all the facade style indices to refence when looking for the appropriate style per floor
                int        patternCount             = 0;
                foreach (BuildrVolumeStylesUnit styleUnit in styleUnits) //need to knw how big all the styles are together so we can loop through them
                {
                    floorPatternSize += styleUnit.floors;
                    for (int i = 0; i < styleUnit.floors; i++)
                    {
                        facadePatternReference.Add(patternCount);
                    }
                    patternCount++;
                }
                facadePatternReference.Reverse();

                int rows = numberOfFloors;

                Vector2 bayBase          = Vector2.zero;
                float   currentFloorBase = 0;
                for (int r = 0; r < rows; r++)
                {
                    currentFloorBase = floorHeight * r;
                    int modFloor = (r % floorPatternSize);

                    facadeDesign = data.facades[styleUnits[facadePatternReference[modFloor]].styleID];

                    bool isBlankWall = !facadeDesign.hasWindows;
                    if (facadeDesign.type == BuildrFacadeDesign.types.patterned)
                    {
                        BuildrBay firstBay = data.bays[facadeDesign.bayPattern[0]];
                        if (firstBay.openingWidth > facadeWidth)
                        {
                            isBlankWall = true;
                        }
                        if (facadeDesign.bayPattern.Count == 0)
                        {
                            isBlankWall = true;
                        }
                    }
                    else
                    {
                        if (facadeDesign.simpleBay.openingWidth + facadeDesign.simpleBay.minimumBayWidth > facadeWidth)
                        {
                            isBlankWall = true;
                        }
                    }
                    if (!isBlankWall)
                    {
                        float       patternSize  = 0;//the space the pattern fills, there will be a gap that will be distributed to all bay styles
                        int         numberOfBays = 0;
                        BuildrBay[] bays;
                        int         numberOfBayDesigns = 0;
                        if (facadeDesign.type == BuildrFacadeDesign.types.patterned)
                        {
                            numberOfBayDesigns = facadeDesign.bayPattern.Count;
                            bays = new BuildrBay[numberOfBayDesigns];
                            for (int i = 0; i < numberOfBayDesigns; i++)
                            {
                                bays[i] = data.bays[facadeDesign.bayPattern[i]];
                            }
                        }
                        else
                        {
                            bays = new[] { facadeDesign.simpleBay };
                            numberOfBayDesigns = 1;
                        }
                        //start with first window width - we'll be adding to this until we have filled the facade width
                        int it = 100;
                        while (true)
                        {
                            int   patternModIndex = numberOfBays % numberOfBayDesigns;
                            float patternAddition = bays[patternModIndex].openingWidth + bays[patternModIndex].minimumBayWidth;
                            if (patternSize + patternAddition < facadeWidth)
                            {
                                patternSize += patternAddition;
                                numberOfBays++;
                            }
                            else
                            {
                                break;
                            }
                            it--;
                            if (it < 0)
                            {
                                break;
                            }
                        }
                        float perBayAdditionalSpacing = (facadeWidth - patternSize) / numberOfBays;

                        float windowXBase = 0;
                        for (int c = 0; c < numberOfBays; c++)
                        {
                            BuildrBay bayStyle;
                            if (facadeDesign.type == BuildrFacadeDesign.types.patterned)
                            {
                                int numberOfBayStyles = facadeDesign.bayPattern.Count;
                                bayStyle = bays[c % numberOfBayStyles];
                            }
                            else
                            {
                                bayStyle = facadeDesign.simpleBay;
                            }
                            float actualWindowSpacing = bayStyle.minimumBayWidth + perBayAdditionalSpacing;
                            float leftSpace           = actualWindowSpacing * bayStyle.openingWidthRatio;
                            float rightSpace          = actualWindowSpacing - leftSpace;
                            float openingSpace        = bayStyle.openingWidth;

                            Vector3 bayDimensions;
                            int     subMesh;
                            bool    flipped;

                            if (!bayStyle.isOpening)
                            {
                                subMesh   = bayStyle.GetTexture(BuildrBay.TextureNames.WallTexture);
                                flipped   = bayStyle.IsFlipped(BuildrBay.TextureNames.WallTexture);
                                bayBase.x = windowXBase;
                                bayBase.y = currentFloorBase;
                                float bayWidth  = (openingSpace + actualWindowSpacing);
                                float bayHeight = floorHeight;
                                bayDimensions = new Vector2(bayWidth, bayHeight);
                                DrawFacadeTexture(sourceTextures, bayBase, bayDimensions, subMesh, flipped, packedPosition);

                                windowXBase += bayWidth; //move base vertor to next bay
                                continue;                //bay filled - move onto next bay
                            }

                            float rowBottomHeight = ((floorHeight - bayStyle.openingHeight) * bayStyle.openingHeightRatio);
                            float rowTopHeight    = (floorHeight - rowBottomHeight - bayStyle.openingHeight);

                            //Window
                            subMesh       = bayStyle.GetTexture(BuildrBay.TextureNames.OpeningBackTexture);
                            flipped       = bayStyle.IsFlipped(BuildrBay.TextureNames.OpeningBackTexture);
                            bayBase.x     = windowXBase + leftSpace;
                            bayBase.y     = currentFloorBase + rowBottomHeight;
                            bayDimensions = new Vector2(bayStyle.openingWidth, bayStyle.openingHeight);
                            DrawFacadeTexture(sourceTextures, bayBase, bayDimensions, subMesh, flipped, packedPosition);

                            //Column Left
                            if (leftSpace > 0)
                            {
                                subMesh       = bayStyle.GetTexture(BuildrBay.TextureNames.ColumnTexture);
                                flipped       = bayStyle.IsFlipped(BuildrBay.TextureNames.ColumnTexture);
                                bayBase.x     = windowXBase;
                                bayBase.y     = currentFloorBase + rowBottomHeight;
                                bayDimensions = new Vector2(leftSpace, bayStyle.openingHeight);
                                DrawFacadeTexture(sourceTextures, bayBase, bayDimensions, subMesh, flipped, packedPosition);
                            }

                            //Column Right
                            if (rightSpace > 0)
                            {
                                subMesh       = bayStyle.GetTexture(BuildrBay.TextureNames.ColumnTexture);
                                flipped       = bayStyle.IsFlipped(BuildrBay.TextureNames.ColumnTexture);
                                bayBase.x     = windowXBase + leftSpace + openingSpace;
                                bayBase.y     = currentFloorBase + rowBottomHeight;
                                bayDimensions = new Vector2(rightSpace, bayStyle.openingHeight);
                                DrawFacadeTexture(sourceTextures, bayBase, bayDimensions, subMesh, flipped, packedPosition);
                            }

                            //Row Bottom
                            if (rowBottomHeight > 0)
                            {
                                subMesh       = bayStyle.GetTexture(BuildrBay.TextureNames.RowTexture);
                                flipped       = bayStyle.IsFlipped(BuildrBay.TextureNames.RowTexture);
                                bayBase.x     = windowXBase + leftSpace;
                                bayBase.y     = currentFloorBase;
                                bayDimensions = new Vector2(openingSpace, rowBottomHeight);
                                DrawFacadeTexture(sourceTextures, bayBase, bayDimensions, subMesh, flipped, packedPosition);
                            }

                            //Row Top
                            if (rowTopHeight > 0)
                            {
                                subMesh       = bayStyle.GetTexture(BuildrBay.TextureNames.RowTexture);
                                flipped       = bayStyle.IsFlipped(BuildrBay.TextureNames.RowTexture);
                                bayBase.x     = windowXBase + leftSpace;
                                bayBase.y     = currentFloorBase + rowBottomHeight + bayStyle.openingHeight;
                                bayDimensions = new Vector2(openingSpace, rowTopHeight);
                                DrawFacadeTexture(sourceTextures, bayBase, bayDimensions, subMesh, flipped, packedPosition);
                            }

                            //Cross Left
                            if (leftSpace > 0)
                            {
                                //Cross Left Bottom
                                subMesh       = bayStyle.GetTexture(BuildrBay.TextureNames.CrossTexture);
                                flipped       = bayStyle.IsFlipped(BuildrBay.TextureNames.CrossTexture);
                                bayBase.x     = windowXBase;
                                bayBase.y     = currentFloorBase;
                                bayDimensions = new Vector2(leftSpace, rowBottomHeight);
                                DrawFacadeTexture(sourceTextures, bayBase, bayDimensions, subMesh, flipped, packedPosition);

                                //Cross Left Top
                                subMesh       = bayStyle.GetTexture(BuildrBay.TextureNames.CrossTexture);
                                flipped       = bayStyle.IsFlipped(BuildrBay.TextureNames.CrossTexture);
                                bayBase.x     = windowXBase;
                                bayBase.y     = currentFloorBase + rowBottomHeight + bayStyle.openingHeight;
                                bayDimensions = new Vector2(leftSpace, rowTopHeight);
                                DrawFacadeTexture(sourceTextures, bayBase, bayDimensions, subMesh, flipped, packedPosition);
                            }

                            //Cross Right
                            if (rightSpace > 0)
                            {
                                //Cross Left Bottom
                                subMesh       = bayStyle.GetTexture(BuildrBay.TextureNames.CrossTexture);
                                flipped       = bayStyle.IsFlipped(BuildrBay.TextureNames.CrossTexture);
                                bayBase.x     = windowXBase + leftSpace + openingSpace;
                                bayBase.y     = currentFloorBase;
                                bayDimensions = new Vector2(rightSpace, rowBottomHeight);
                                DrawFacadeTexture(sourceTextures, bayBase, bayDimensions, subMesh, flipped, packedPosition);

                                //Cross Left Top
                                subMesh       = bayStyle.GetTexture(BuildrBay.TextureNames.CrossTexture);
                                flipped       = bayStyle.IsFlipped(BuildrBay.TextureNames.CrossTexture);
                                bayBase.x     = windowXBase + leftSpace + openingSpace;
                                bayBase.y     = currentFloorBase + rowBottomHeight + bayStyle.openingHeight;
                                bayDimensions = new Vector2(rightSpace, rowTopHeight);
                                DrawFacadeTexture(sourceTextures, bayBase, bayDimensions, subMesh, flipped, packedPosition);
                            }

                            windowXBase += leftSpace + openingSpace + rightSpace;//move base vertor to next bay
                        }
                    }
                    else
                    {
                        // windowless wall
                        int  subMesh = facadeDesign.simpleBay.GetTexture(BuildrBay.TextureNames.WallTexture);
                        bool flipped = facadeDesign.simpleBay.IsFlipped(BuildrBay.TextureNames.WallTexture);
                        bayBase.x = 0;
                        bayBase.y = currentFloorBase;
                        Vector2 dimensions = new Vector2(facadeWidth, floorHeight);
                        DrawFacadeTexture(sourceTextures, bayBase, dimensions, subMesh, flipped, packedPosition);
                    }
                }
                facadeNumber++;
            }
        }
        LogTimer("generate facade textures");

        //add roof textures
        int numberOfroofTextures = roofTextures.Count;
        int scaledPadding        = Mathf.FloorToInt(ATLAS_PADDING * packedScale);

        for (int i = 0; i < numberOfroofTextures; i++)
        {
            Rect          roofTexturePosition = packedTexturePositions[i + facadeNumber];
            BuildrTexture bTexture            = roofTextures[i];
            int           roofTextureWidth    = bTexture.texture.width;
            int           roofTextureHeight   = bTexture.texture.height;
            int           targetTextureWidth  = Mathf.RoundToInt(roofTexturePosition.width);
            int           targetTextureHeight = Mathf.RoundToInt(roofTexturePosition.height);
            if (bTexture.maxUVTile == Vector2.zero)
            {
                LogTimer("BuildTextures: Skip texture " + bTexture.name + " as it appears it's not used");
                continue;
            }
            int sourceTextureWidth  = Mathf.RoundToInt(targetTextureWidth / (bTexture.tiled ? bTexture.maxUVTile.x : bTexture.tiledX));
            int sourceTextureHeight = Mathf.RoundToInt(targetTextureHeight / (bTexture.tiled ? bTexture.maxUVTile.y : bTexture.tiledY));
            int sourceTextureSize   = sourceTextureWidth * sourceTextureHeight;
            if (sourceTextureSize == 0)
            {
                //Debug.Log(sourceTextureWidth+" "+sourceTextureHeight+" "+bTexture.tiledX+" "+bTexture.maxUVTile+" "+bTexture.tiledX+","+bTexture.tiledY);
                continue;
            }
            Color32[] roofColourArray = TextureScale.NearestNeighbourSample(((Texture2D)bTexture.texture).GetPixels32(), roofTextureWidth, roofTextureHeight, sourceTextureWidth, sourceTextureHeight);
            //Color32[] roofColourArray = bTexture.texture.GetPixels32();

            for (int x = 0; x < targetTextureWidth; x++)
            {
                for (int y = 0; y < targetTextureHeight; y++)
                {
                    int drawX       = Mathf.FloorToInt(x + roofTexturePosition.x);
                    int drawY       = Mathf.FloorToInt(y + roofTexturePosition.y);
                    int colourIndex = drawX + drawY * textureWidth;

                    int sx          = x % sourceTextureWidth;
                    int sy          = y % sourceTextureHeight;
                    int sourceIndex = sx + sy * sourceTextureWidth;
                    if (sourceIndex >= sourceTextureSize)
                    {
                        Debug.Log("Source Index too big " + sx + " " + sy + " " + sourceTextureWidth + " " + sourceTextureSize + " " + bTexture.maxUVTile + " " + bTexture.name);
                    }
                    Color32 sourceColour = roofColourArray[sourceIndex];
                    if (colourIndex >= textureSize)
                    {
                        Debug.Log("Output Index Too big " + drawX + " " + drawY + " " + colourIndex + " " + textureSize + " " + roofTexturePosition);
                    }
                    colourArray[colourIndex] = sourceColour;

                    //Padding
                    if (x == 0)
                    {
                        for (int p = 0; p < scaledPadding; p++)
                        {
                            colourArray[colourIndex - p] = sourceColour;
                        }
                    }
                    if (x == targetTextureWidth - 1)
                    {
                        for (int p = 0; p < scaledPadding; p++)
                        {
                            colourArray[colourIndex + p] = sourceColour;
                        }
                    }

                    if (y == 0)
                    {
                        for (int p = 0; p < scaledPadding; p++)
                        {
                            colourArray[colourIndex - (p * textureWidth)] = sourceColour;
                        }
                    }

                    if (y == targetTextureHeight - 1)
                    {
                        for (int p = 0; p < scaledPadding; p++)
                        {
                            colourArray[colourIndex + (p * textureWidth)] = sourceColour;
                        }
                    }
                }
            }
        }
        LogTimer("generate roof textures");
    }
Example #27
0
    private static void Gabled(BuildrVolume volume, BuildrRoofDesign design)
    {
        BuildrPlan area = data.plan;
        int numberOfFloors = volume.numberOfFloors;
        float floorHeight = data.floorHeight;
        Vector3 volumeFloorHeight = Vector3.up * (numberOfFloors * floorHeight);
        Vector3 ridgeVector = Vector3.up * design.height;

        Vector3[] basePoints = new Vector3[4];
        if (design.direction == 0)
        {
            basePoints[0] = area.points[volume.points[0]].vector3 + volumeFloorHeight;
            basePoints[1] = area.points[volume.points[1]].vector3 + volumeFloorHeight;
            basePoints[2] = area.points[volume.points[2]].vector3 + volumeFloorHeight;
            basePoints[3] = area.points[volume.points[3]].vector3 + volumeFloorHeight;
        }
        else
        {
            basePoints[0] = area.points[volume.points[1]].vector3 + volumeFloorHeight;
            basePoints[1] = area.points[volume.points[2]].vector3 + volumeFloorHeight;
            basePoints[2] = area.points[volume.points[3]].vector3 + volumeFloorHeight;
            basePoints[3] = area.points[volume.points[0]].vector3 + volumeFloorHeight;
        }
        Vector3 centrePoint = Vector3.zero;
        for (int l = 0; l < 4; l++)
            centrePoint += area.points[volume.points[l]].vector3;
        centrePoint = (centrePoint / 4) + volumeFloorHeight + ridgeVector;

        Vector3 r0 = Vector3.Lerp(basePoints[0], basePoints[1], 0.5f) + ridgeVector;
        Vector3 r1 = Vector3.Lerp(basePoints[2], basePoints[3], 0.5f) + ridgeVector;

        int subMesh = design.GetTexture(BuildrRoofDesign.textureNames.tiles);
        bool flipped = design.IsFlipped(BuildrRoofDesign.textureNames.tiles);
        AddPlane(design, basePoints[0], r0, basePoints[3], r1, subMesh, flipped);//top
        AddPlane(design, basePoints[2], r1, basePoints[1], r0, subMesh, flipped);//top

        Vector3[] vertsA = new Vector3[3] { basePoints[0], basePoints[1], r0 };
        Vector3[] vertsB = new Vector3[3] { basePoints[2], basePoints[3], r1 };
        float uvWdithA = Vector3.Distance(basePoints[0], basePoints[1]);
        float uvWdithB = Vector3.Distance(basePoints[2], basePoints[3]);
        float uvHeight = design.height;
        subMesh = design.GetTexture(BuildrRoofDesign.textureNames.wall);
        BuildrTexture texture = textures[subMesh];

        if (texture.tiled)
        {
            uvWdithA *= (1.0f / texture.textureUnitSize.x);
            uvWdithB *= (1.0f / texture.textureUnitSize.x);
            uvHeight *= (1.0f / texture.textureUnitSize.y);
            if (texture.patterned)
            {
                Vector2 uvunits = texture.tileUnitUV;
                uvWdithA = Mathf.Ceil(uvWdithA / uvunits.x) * uvunits.x;
                uvWdithB = Mathf.Ceil(uvWdithB / uvunits.x) * uvunits.x;
                uvHeight = Mathf.Ceil(uvHeight / uvunits.y) * uvunits.y;
            }
        }
        else
        {
            uvWdithA = texture.tiledX;
            uvWdithB = texture.tiledX;
            uvHeight = texture.tiledY;
        }
        Vector2[] uvsA = new Vector2[3] { new Vector2(-uvWdithA / 2, 0), new Vector2(uvWdithA / 2, 0), new Vector2(0, uvHeight) };
        Vector2[] uvsB = new Vector2[3] { new Vector2(-uvWdithB / 2, 0), new Vector2(uvWdithB / 2, 0), new Vector2(0, uvHeight) };
        int[] tri = new int[3] { 1, 0, 2 };
        AddData(vertsA, uvsA, tri, subMesh);
        AddData(vertsB, uvsB, tri, subMesh);

    }
Example #28
0
    private static void LeanTo(BuildrVolume volume, BuildrRoofDesign design)
    {
        BuildrPlan area = data.plan;
        int numberOfFloors = volume.numberOfFloors;
        float floorHeight = data.floorHeight;
        Vector3 volumeFloorHeight = Vector3.up * (numberOfFloors * floorHeight);
        Vector3 ridgeVector = Vector3.up * design.height;

        int[] pointIndexes = new int[4];
        switch (design.direction)
        {
            case 0:
                pointIndexes = new int[4] { 0, 1, 2, 3 };
                break;
            case 1:
                pointIndexes = new int[4] { 1, 2, 3, 0 };
                break;
            case 2:
                pointIndexes = new int[4] { 2, 3, 0, 1 };
                break;
            case 3:
                pointIndexes = new int[4] { 3, 0, 1, 2 };
                break;
        }
        Vector3[] points = new Vector3[6];
        points[0] = area.points[volume.points[pointIndexes[0]]].vector3 + volumeFloorHeight;
        points[1] = area.points[volume.points[pointIndexes[1]]].vector3 + volumeFloorHeight;
        points[2] = area.points[volume.points[pointIndexes[2]]].vector3 + volumeFloorHeight;
        points[3] = area.points[volume.points[pointIndexes[3]]].vector3 + volumeFloorHeight;
        points[4] = area.points[volume.points[pointIndexes[2]]].vector3 + volumeFloorHeight + ridgeVector;
        points[5] = area.points[volume.points[pointIndexes[3]]].vector3 + volumeFloorHeight + ridgeVector;

        //top
        int subMeshTop = design.GetTexture(BuildrRoofDesign.textureNames.tiles);
        bool flippedTop = design.IsFlipped(BuildrRoofDesign.textureNames.tiles);
        AddPlane(design, points[0], points[1], points[5], points[4], subMeshTop, flippedTop);

        //window
        int subMeshWindow = design.GetTexture(BuildrRoofDesign.textureNames.window);
        bool flippedWindow = design.IsFlipped(BuildrRoofDesign.textureNames.window);
        AddPlane(design, points[2], points[3], points[4], points[5], subMeshWindow, flippedWindow);

        //sides
        Vector3[] vertsA = new Vector3[3] { points[1], points[2], points[4] };
        Vector3[] vertsB = new Vector3[3] { points[0], points[3], points[5] };
        float uvWdith = Vector3.Distance(points[0], points[3]);
        float uvHeight = design.height;
        int subMesh = design.GetTexture(BuildrRoofDesign.textureNames.wall);
        BuildrTexture texture = textures[subMesh];

        if (texture.tiled)
        {
            uvWdith *= (1.0f / texture.textureUnitSize.x);
            uvHeight *= (1.0f / texture.textureUnitSize.y);
            if (texture.patterned)
            {
                Vector2 uvunits = texture.tileUnitUV;
                uvWdith = Mathf.Ceil(uvWdith / uvunits.x) * uvunits.x;
                uvHeight = Mathf.Ceil(uvHeight / uvunits.y) * uvunits.y;
            }
        }
        else
        {
            uvWdith = texture.tiledX;
            uvHeight = texture.tiledY;
        }

        Vector2[] uvs = new Vector2[3] { new Vector2(0, 0), new Vector2(uvWdith, 0), new Vector2(uvWdith, uvHeight) };
        if (!design.IsFlipped(BuildrRoofDesign.textureNames.wall))
            uvs = new Vector2[3] { new Vector2(uvWdith, 0), new Vector2(0, 0), new Vector2(uvHeight, uvWdith / 2) };

        int[] triA = new int[3] { 1, 0, 2 };
        int[] triB = new int[3] { 0, 1, 2 };

        AddData(vertsA, uvs, triA, subMesh);
        AddData(vertsB, uvs, triB, subMesh);
    }
Example #29
0
    private static void GetTextures(BuildrData data)
    {
        List <BuildrTexture> walltextures   = new List <BuildrTexture>();
        List <BuildrTexture> windowtextures = new List <BuildrTexture>();
        List <BuildrTexture> doortextures   = new List <BuildrTexture>();
        List <BuildrTexture> rooftextures   = new List <BuildrTexture>();
        XmlNodeList          xmlTextures    = null;
        string textureFilePath = data.generatorConstraints.texturePackXML;

        if (File.Exists(textureFilePath))
        {
            XmlDocument  xml = new XmlDocument();
            StreamReader sr  = new StreamReader(textureFilePath);
            xml.LoadXml(sr.ReadToEnd());
            sr.Close();
            xmlTextures = xml.SelectNodes("data/textures/texture");

            if (xmlTextures == null)
            {
                return;
            }

            foreach (XmlNode node in xmlTextures)
            {
                string        filepath = node["filepath"].FirstChild.Value;
                string[]      splits   = filepath.Split(filenameDelimiters);
                BuildrTexture bTexture = new BuildrTexture(splits[splits.Length - 1]);
#if UNITY_EDITOR
                Texture2D texture = (Texture2D)AssetDatabase.LoadAssetAtPath(filepath, typeof(Texture2D));
#else
                Texture2D texture = new WWW(filepath).texture;
#endif
                bTexture.texture   = texture;
                bTexture.tiled     = node["tiled"].FirstChild.Value == "True";
                bTexture.patterned = node["patterned"].FirstChild.Value == "True";
                Vector2 tileUnitUV;
                tileUnitUV.x        = float.Parse(node["tileUnitUVX"].FirstChild.Value);
                tileUnitUV.y        = float.Parse(node["tileUnitUVY"].FirstChild.Value);
                bTexture.tileUnitUV = tileUnitUV;

                Vector2 textureUnitSize;
                textureUnitSize.x        = float.Parse(node["textureUnitSizeX"].FirstChild.Value);
                textureUnitSize.y        = float.Parse(node["textureUnitSizeY"].FirstChild.Value);
                bTexture.textureUnitSize = textureUnitSize;

                bTexture.tiledX = int.Parse(node["tiledX"].FirstChild.Value);
                bTexture.tiledY = int.Parse(node["tiledY"].FirstChild.Value);

                bTexture.door   = node["door"].FirstChild.Value == "True";
                bTexture.window = node["window"].FirstChild.Value == "True";
                bTexture.wall   = node["wall"].FirstChild.Value == "True";
                bTexture.roof   = node["roof"].FirstChild.Value == "True";

                if (bTexture.wall)
                {
                    walltextures.Add(bTexture);
                }
                if (bTexture.window)
                {
                    windowtextures.Add(bTexture);
                }
                if (bTexture.door)
                {
                    doortextures.Add(bTexture);
                }
                if (bTexture.roof)
                {
                    rooftextures.Add(bTexture);
                }
            }
        }

        RandomGen rgen = data.generatorConstraints.rgen;
        wallTexture = walltextures[rgen.OutputRange(0, walltextures.Count - 1)];//wall
        data.textures.Add(wallTexture);

        windowTexture = windowtextures[rgen.OutputRange(0, windowtextures.Count - 1)];//window
        data.textures.Add(windowTexture);

        roofTexture = rooftextures[rgen.OutputRange(0, rooftextures.Count - 1)];//roof
        data.textures.Add(roofTexture);

        doorTexture = doortextures[rgen.OutputRange(0, doortextures.Count - 1)];//door
        data.textures.Add(doorTexture);

        groundFloorWindowTexture = windowtextures[rgen.OutputRange(0, windowtextures.Count - 1)];//window
        data.textures.Add(groundFloorWindowTexture);
    }
 /// <summary>
 /// Atlas the specified modifySubmeshes using newTextureCoords and textures.
 /// </summary>
 /// <param name='modifySubmeshes'>
 /// Submeshes indicies to atlas.
 /// </param>
 /// <param name='newTextureCoords'>
 /// New texture coords generated from Pack Textures.
 /// </param>
 /// <param name='textures'>
 /// BuildR Textures library reference.
 /// </param>
 public void Atlas(int[] modifySubmeshes, Rect[] newTextureCoords, BuildrTexture[] textures)
 {
     foreach (DynamicMeshGenericMultiMaterial mesh in _meshes)
         mesh.Atlas(modifySubmeshes, newTextureCoords, textures);
 }
    private void OnGUI()
    {
        string asterisk = GUI.changed ? "*" : "";

        EditorGUILayout.LabelField("Texture Designs" + asterisk, GUILayout.Height(12), GUILayout.Width(280));
        Texture2D facadeTexture = new Texture2D(1, 1);

        facadeTexture.SetPixel(0, 0, BuildrColours.BLUE);
        facadeTexture.Apply();
        Rect sqrPos = new Rect(0, 0, 0, 0);

        if (Event.current.type == EventType.Repaint)
        {
            sqrPos = GUILayoutUtility.GetLastRect();
        }
        GUI.DrawTexture(sqrPos, facadeTexture);
        EditorGUI.DropShadowLabel(sqrPos, "Texture Designs" + asterisk);
        //int currentSelectedTexture = selectedTexture;//keep tack of what we had selected to reset fields if changed

        int numberOfFiles = xmlfilelist.Count;

        string[] fileNames = new string[numberOfFiles];
        for (int t = 0; t < numberOfFiles; t++)
        {
            string   filepath      = xmlfilelist[t];
            string[] filepathsplit = filepath.Split(filenameDelimiters);
            string   displayPath   = filepathsplit[filepathsplit.Length - 1];
            fileNames[t] = displayPath;
        }
        int newSelectedFile = EditorGUILayout.Popup(selectedFile, fileNames);

        if (newSelectedFile != selectedFile)
        {
            selectedFile    = newSelectedFile;
            textureFilePath = xmlfilelist[selectedFile];
            CheckData();
            selectedTexture = 0;//reset the selected texture to 0 to avoid index out of range...
        }

        if (GUILayout.Button("Create New Texture Pack"))
        {
            if (EditorUtility.DisplayDialog("New Texture Pack", "Are you sure you want to start a new texture pack.\nAll unsaved data will be shown the door.", "ok, do it!", "no no no no"))
            {
                GenerateData();
            }
        }

        int numberOfTextures = textures.Count;

        selectedTexture = Mathf.Clamp(selectedTexture, 0, numberOfTextures - 1);

        EditorGUILayout.BeginHorizontal();
        string[] texturePaths     = GetTextureFilenames();
        string[] textureFilenames = new string[texturePaths.Length];
        for (int t = 0; t < texturePaths.Length; t++)
        {
            string[] splits = texturePaths[t].Split(filenameDelimiters);
            textureFilenames[t] = splits[splits.Length - 1];
        }
        addSelectedTexture = EditorGUILayout.Popup(addSelectedTexture, textureFilenames);
        if (GUILayout.Button("Add New Texture to Pack"))
        {
            string    path    = texturePaths[addSelectedTexture];
            Texture2D texture = (Texture2D)AssetDatabase.LoadAssetAtPath(path, typeof(Texture2D));
            if (texture != null)
            {
                string[]      splits      = path.Split(filenameDelimiters);
                BuildrTexture newBTexture = new BuildrTexture(splits[splits.Length - 1]);
                newBTexture.texture = texture;
                textures.Add(newBTexture);
                selectedTexture = textures.Count - 1;
            }
        }
        EditorGUILayout.EndHorizontal();

        if (numberOfTextures == 0)
        {
            EditorGUILayout.HelpBox("There are no textures to show", MessageType.Info);
            return;
        }

        EditorGUILayout.LabelField("Selected Texture");
        EditorGUILayout.BeginHorizontal();
        string[] textureNames = new string[numberOfTextures];
        for (int t = 0; t < numberOfTextures; t++)
        {
            textureNames[t] = textures[t].name;
        }
        selectedTexture = EditorGUILayout.Popup(selectedTexture, textureNames);

        EditorGUI.BeginDisabledGroup(selectedTexture <= 0);
        if (GUILayout.Button("<", GUILayout.Width(25)))
        {
            selectedTexture--;
        }
        EditorGUI.EndDisabledGroup();

        EditorGUI.BeginDisabledGroup(selectedTexture >= numberOfTextures - 1);
        if (GUILayout.Button(">", GUILayout.Width(25)))
        {
            selectedTexture++;
        }
        EditorGUI.EndDisabledGroup();

        BuildrTexture bTexture = textures[selectedTexture];

        EditorGUILayout.EndHorizontal();

        EditorGUILayout.BeginHorizontal();
        if (GUILayout.Button("Delete"))
        {
            textures.Remove(bTexture);
        }
        if (GUILayout.Button("Delete All"))
        {
            textures.Clear();
        }

        EditorGUILayout.EndHorizontal();

        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.LabelField("Is Tiled");
        bTexture.tiled = EditorGUILayout.Toggle(bTexture.tiled, GUILayout.Width(18));
        EditorGUILayout.EndHorizontal();

        EditorGUI.BeginDisabledGroup(!bTexture.tiled);
        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.LabelField("Has Pattern");
        bTexture.patterned = EditorGUILayout.Toggle(bTexture.patterned, GUILayout.Width(18));
        EditorGUILayout.EndHorizontal();
        EditorGUI.EndDisabledGroup();
        if (!bTexture.tiled)
        {
            bTexture.patterned = false;
        }

        Vector2 textureUnitSize = bTexture.textureUnitSize;

        if (bTexture.tiled)
        {
            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("Texture Width", GUILayout.Width(180)); //, GUILayout.Width(42));
            textureUnitSize.x = EditorGUILayout.FloatField(bTexture.textureUnitSize.x, GUILayout.Width(35));
            EditorGUILayout.LabelField("metres", GUILayout.Width(45));         //, GUILayout.Width(42));
            EditorGUILayout.EndHorizontal();
            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("Texture Height", GUILayout.Width(180));//, GUILayout.Width(42));
            textureUnitSize.y = EditorGUILayout.FloatField(bTexture.textureUnitSize.y, GUILayout.Width(35));
            EditorGUILayout.LabelField("metres", GUILayout.Width(45));
            EditorGUILayout.EndHorizontal();
            bTexture.textureUnitSize = textureUnitSize;
        }

        Vector2 tileUnitSize = bTexture.tileUnitUV;

        if (bTexture.patterned)
        {
            float minWidth  = 2 / bTexture.texture.width;
            float minHeight = 2 / bTexture.texture.height;

            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("Unit Width", GUILayout.Width(75));
            tileUnitSize.x = EditorGUILayout.Slider(tileUnitSize.x, minWidth, 1.0f);
            EditorGUILayout.EndHorizontal();
            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("Unit Height", GUILayout.Width(75));
            tileUnitSize.y = EditorGUILayout.Slider(tileUnitSize.y, minHeight, 1.0f);
            EditorGUILayout.EndHorizontal();
            bTexture.tileUnitUV = tileUnitSize;

            EditorGUILayout.Space();
        }

        const int previewTextureUnitSize = 120;
        const int previewTileUnitSize    = 59;
        const int previewTileUnitPadding = 2;
        const int previewPadding         = 25;

        EditorGUILayout.BeginHorizontal();
        if (bTexture.tiled)
        {
            EditorGUILayout.LabelField("1 Metre Squared", GUILayout.Width(110));
        }
        GUILayout.Space(previewPadding);
        if (bTexture.patterned)
        {
            EditorGUILayout.LabelField("Texture Pattern Units", GUILayout.Width(120));
        }
        EditorGUILayout.EndHorizontal();
        EditorGUILayout.Space();


        if (Event.current.type == EventType.Repaint)
        {
            texturePreviewPostion = GUILayoutUtility.GetLastRect();
        }

        if (bTexture.tiled)
        {
            Rect previewRect = new Rect(texturePreviewPostion.x, texturePreviewPostion.y, previewTextureUnitSize, previewTextureUnitSize);
            Rect sourceRect  = new Rect(0, 0, (1.0f / textureUnitSize.x), (1.0f / textureUnitSize.y));

            Graphics.DrawTexture(previewRect, bTexture.texture, sourceRect, 0, 0, 0, 0);
        }

        if (bTexture.patterned)
        {
            Rect previewRect = new Rect(previewTextureUnitSize + previewPadding, 0, previewTileUnitSize, previewTileUnitSize);
            Rect sourceRect  = new Rect(0, tileUnitSize.y, tileUnitSize.x, tileUnitSize.y);

            previewRect.x += texturePreviewPostion.x;
            previewRect.y += texturePreviewPostion.y;

            Graphics.DrawTexture(previewRect, bTexture.texture, sourceRect, 0, 0, 0, 0);

            sourceRect.x  += tileUnitSize.x;
            previewRect.x += previewTileUnitSize + previewTileUnitPadding;

            Graphics.DrawTexture(previewRect, bTexture.texture, sourceRect, 0, 0, 0, 0);

            sourceRect.x  += -tileUnitSize.x;
            sourceRect.y  += -tileUnitSize.y;
            previewRect.x += -(previewTileUnitSize + previewTileUnitPadding);
            previewRect.y += previewTileUnitSize + previewTileUnitPadding;

            Graphics.DrawTexture(previewRect, bTexture.texture, sourceRect, 0, 0, 0, 0);

            sourceRect.x  += tileUnitSize.x;
            previewRect.x += previewTileUnitSize + previewTileUnitPadding;

            Graphics.DrawTexture(previewRect, bTexture.texture, sourceRect, 0, 0, 0, 0);
        }

        if (!bTexture.tiled)
        {
            //EditorGUILayout.LabelField("Tile texture");

            EditorGUILayout.BeginHorizontal();
            int currentXTiles = bTexture.tiledX;
            GUILayout.Label("Texture Tile X");
            currentXTiles = EditorGUILayout.IntField(currentXTiles, GUILayout.Width(30));
            if (GUILayout.Button("+", GUILayout.Width(25)))
            {
                currentXTiles++;
            }
            EditorGUI.BeginDisabledGroup(currentXTiles < 2);
            if (GUILayout.Button("-", GUILayout.Width(25)))
            {
                currentXTiles--;
            }
            EditorGUI.EndDisabledGroup();
            bTexture.tiledX = currentXTiles;
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal();
            int currentYTiles = bTexture.tiledY;
            GUILayout.Label("Texture Tile Y");
            currentYTiles = EditorGUILayout.IntField(currentYTiles, GUILayout.Width(30));
            if (GUILayout.Button("+", GUILayout.Width(25)))
            {
                currentYTiles++;
            }
            EditorGUI.BeginDisabledGroup(currentYTiles < 2);
            if (GUILayout.Button("-", GUILayout.Width(25)))
            {
                currentYTiles--;
            }
            EditorGUI.EndDisabledGroup();
            bTexture.tiledY = currentYTiles;
            EditorGUILayout.EndHorizontal();

            GUILayout.Space(10);
            EditorGUILayout.Space();
            if (Event.current.type == EventType.Repaint)
            {
                texturePreviewPostion = GUILayoutUtility.GetLastRect();
            }

            Rect previewRect = new Rect(texturePreviewPostion.x, texturePreviewPostion.y, previewTextureUnitSize, previewTextureUnitSize);
            Rect sourceRect  = new Rect(0, 0, currentXTiles, currentYTiles);

            Graphics.DrawTexture(previewRect, bTexture.texture, sourceRect, 0, 0, 0, 0);
        }

        GUILayout.Space(previewTextureUnitSize);

        EditorGUILayout.LabelField("Texture Usage");

        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.LabelField("Walls");
        bTexture.wall = EditorGUILayout.Toggle(bTexture.wall);
        EditorGUILayout.EndHorizontal();

        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.LabelField("Doors");
        bTexture.door = EditorGUILayout.Toggle(bTexture.door);
        EditorGUILayout.EndHorizontal();

        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.LabelField("Windows");
        bTexture.window = EditorGUILayout.Toggle(bTexture.window);
        EditorGUILayout.EndHorizontal();

        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.LabelField("Roofs");
        bTexture.roof = EditorGUILayout.Toggle(bTexture.roof);
        EditorGUILayout.EndHorizontal();

        if (GUILayout.Button("Save Data"))
        {
            SaveData();
        }

        if (GUILayout.Button("Save Data As..."))
        {
            SaveDataAs();
        }
    }
Example #32
0
    /// <summary>
    /// Atlas the specified modifySubmeshes using newTextureCoords and textures.
    /// </summary>
    /// <param name='modifySubmeshes'>
    /// Submeshes indicies to atlas.
    /// </param>
    /// <param name='newTextureCoords'>
    /// New texture coords generated from Pack Textures.
    /// </param>
    /// <param name='textures'>
    /// BuildR Textures library reference.
    /// </param>
    public void Atlas(int[] modifySubmeshes, Rect[] newTextureCoords, BuildrTexture[] textures)
    {
        if (modifySubmeshes.Length == 0)
        {
            Debug.Log("No submeshes to atlas!");
            return;
        }
        List <int> atlasedSubmesh            = new List <int>();
        int        numberOfSubmeshesToModify = modifySubmeshes.Length;

        for (int s = 0; s < numberOfSubmeshesToModify; s++)
        {
            int  submeshIndex = modifySubmeshes[s];
            Rect textureRect  = newTextureCoords[s];
            if (!subTriangles.ContainsKey(submeshIndex))
            {
                continue;
            }
            int[] submeshIndices = subTriangles[submeshIndex].ToArray();
            subTriangles.Remove(submeshIndex);
            atlasedSubmesh.AddRange(submeshIndices);

            BuildrTexture bTexture    = textures[submeshIndex];
            List <int>    ModifiedUVs = new List <int>();
            foreach (int index in submeshIndices)
            {
                if (ModifiedUVs.Contains(index))
                {
                    continue;//don't move the UV more than once
                }
                Vector2 uvCoords = uv[index];
                float   xUV      = uvCoords.x / bTexture.maxUVTile.x;
                float   yUV      = uvCoords.y / bTexture.maxUVTile.y;
                if (xUV > 1)
                {
                    bTexture.maxUVTile.x = uvCoords.x;
                    xUV = 1.0f;
                }
                if (yUV > 1)
                {
                    bTexture.maxUVTile.y = uvCoords.y;
                    yUV = 1;
                }

                uvCoords.x = Mathf.Lerp(textureRect.xMin, textureRect.xMax, xUV);
                uvCoords.y = Mathf.Lerp(textureRect.yMin, textureRect.yMax, yUV);

                if (float.IsNaN(uvCoords.x))
                {
                    uvCoords.x = 1;
                }
                if (float.IsNaN(uvCoords.y))
                {
                    uvCoords.y = 1;
                }
                uv[index] = uvCoords;
                ModifiedUVs.Add(index);//keep a record of moved UVs
            }
        }
        subMeshCount = subMeshCount - modifySubmeshes.Length + 1;
        subTriangles.Add(modifySubmeshes[0], atlasedSubmesh);
    }
Example #33
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 void OnGUI()
    {
        string asterisk = GUI.changed ? "*" : "";

        EditorGUILayout.LabelField("Texture Designs" + asterisk, GUILayout.Height(12), GUILayout.Width(280));
        Texture2D facadeTexture = new Texture2D(1, 1);
        facadeTexture.SetPixel(0, 0, BuildrColours.BLUE);
        facadeTexture.Apply();
        Rect sqrPos = new Rect(0, 0, 0, 0);
        if (Event.current.type == EventType.Repaint)
            sqrPos = GUILayoutUtility.GetLastRect();
        GUI.DrawTexture(sqrPos, facadeTexture);
        EditorGUI.DropShadowLabel(sqrPos, "Texture Designs" + asterisk);
        //int currentSelectedTexture = selectedTexture;//keep tack of what we had selected to reset fields if changed

        int numberOfFiles = xmlfilelist.Count;
        string[] fileNames = new string[numberOfFiles];
        for (int t = 0; t < numberOfFiles; t++)
        {
            string filepath = xmlfilelist[t];
            string[] filepathsplit = filepath.Split(filenameDelimiters);
            string displayPath = filepathsplit[filepathsplit.Length-1];
            fileNames[t] = displayPath;
        }
        int newSelectedFile = EditorGUILayout.Popup(selectedFile, fileNames);
        if (newSelectedFile != selectedFile)
        {
            selectedFile = newSelectedFile;
            textureFilePath = xmlfilelist[selectedFile];
            CheckData();
            selectedTexture = 0;//reset the selected texture to 0 to avoid index out of range...
        }

        if (GUILayout.Button("Create New Texture Pack"))
        {
            if(EditorUtility.DisplayDialog("New Texture Pack","Are you sure you want to start a new texture pack.\nAll unsaved data will be shown the door.","ok, do it!","no no no no"))
                GenerateData();
        }

        int numberOfTextures = textures.Count;
        selectedTexture = Mathf.Clamp(selectedTexture, 0, numberOfTextures - 1);

        EditorGUILayout.BeginHorizontal();
        string[] texturePaths = GetTextureFilenames();
        string[] textureFilenames = new string[texturePaths.Length];
        for (int t = 0; t < texturePaths.Length; t++)
        {
            string[] splits = texturePaths[t].Split(filenameDelimiters);
            textureFilenames[t] = splits[splits.Length - 1];
        }
        addSelectedTexture = EditorGUILayout.Popup(addSelectedTexture, textureFilenames);
        if (GUILayout.Button("Add New Texture to Pack"))
        {
            string path = texturePaths[addSelectedTexture];
            Texture2D texture = (Texture2D)AssetDatabase.LoadAssetAtPath(path, typeof(Texture2D));
            if (texture != null)
            {
                string[] splits = path.Split(filenameDelimiters);
                BuildrTexture newBTexture = new BuildrTexture(splits[splits.Length - 1]);
                newBTexture.texture = texture;
                textures.Add(newBTexture);
                selectedTexture = textures.Count - 1;
            }
        }
        EditorGUILayout.EndHorizontal();

        if (numberOfTextures == 0)
        {
            EditorGUILayout.HelpBox("There are no textures to show", MessageType.Info);
            return;
        }

        EditorGUILayout.LabelField("Selected Texture");
        EditorGUILayout.BeginHorizontal();
        string[] textureNames = new string[numberOfTextures];
        for (int t = 0; t < numberOfTextures; t++)
            textureNames[t] = textures[t].name;
        selectedTexture = EditorGUILayout.Popup(selectedTexture, textureNames);

        EditorGUI.BeginDisabledGroup(selectedTexture <= 0);
        if (GUILayout.Button("<", GUILayout.Width(25)))
            selectedTexture--;
        EditorGUI.EndDisabledGroup();

        EditorGUI.BeginDisabledGroup(selectedTexture >= numberOfTextures - 1);
        if (GUILayout.Button(">", GUILayout.Width(25)))
            selectedTexture++;
        EditorGUI.EndDisabledGroup();

        BuildrTexture bTexture = textures[selectedTexture];

        EditorGUILayout.EndHorizontal();

        EditorGUILayout.BeginHorizontal();
        if (GUILayout.Button("Delete"))
            textures.Remove(bTexture);
        if (GUILayout.Button("Delete All"))
            textures.Clear();

        EditorGUILayout.EndHorizontal();

        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.LabelField("Is Tiled");
        bTexture.tiled = EditorGUILayout.Toggle(bTexture.tiled, GUILayout.Width(18));
        EditorGUILayout.EndHorizontal();

        EditorGUI.BeginDisabledGroup(!bTexture.tiled);
        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.LabelField("Has Pattern");
        bTexture.patterned = EditorGUILayout.Toggle(bTexture.patterned, GUILayout.Width(18));
        EditorGUILayout.EndHorizontal();
        EditorGUI.EndDisabledGroup();
        if (!bTexture.tiled)
            bTexture.patterned = false;

        Vector2 textureUnitSize = bTexture.textureUnitSize;
        if (bTexture.tiled)
        {
            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("Texture Width", GUILayout.Width(180));//, GUILayout.Width(42));
            textureUnitSize.x = EditorGUILayout.FloatField(bTexture.textureUnitSize.x, GUILayout.Width(35));
            EditorGUILayout.LabelField("metres", GUILayout.Width(45));//, GUILayout.Width(42));
            EditorGUILayout.EndHorizontal();
            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("Texture Height", GUILayout.Width(180));//, GUILayout.Width(42));
            textureUnitSize.y = EditorGUILayout.FloatField(bTexture.textureUnitSize.y, GUILayout.Width(35));
            EditorGUILayout.LabelField("metres", GUILayout.Width(45));
            EditorGUILayout.EndHorizontal();
            bTexture.textureUnitSize = textureUnitSize;
        }

        Vector2 tileUnitSize = bTexture.tileUnitUV;
        if (bTexture.patterned)
        {
            float minWidth = 2 / bTexture.texture.width;
            float minHeight = 2 / bTexture.texture.height;

            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("Unit Width", GUILayout.Width(75));
            tileUnitSize.x = EditorGUILayout.Slider(tileUnitSize.x, minWidth, 1.0f);
            EditorGUILayout.EndHorizontal();
            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("Unit Height", GUILayout.Width(75));
            tileUnitSize.y = EditorGUILayout.Slider(tileUnitSize.y, minHeight, 1.0f);
            EditorGUILayout.EndHorizontal();
            bTexture.tileUnitUV = tileUnitSize;

            EditorGUILayout.Space();
        }

        const int previewTextureUnitSize = 120;
        const int previewTileUnitSize = 59;
        const int previewTileUnitPadding = 2;
        const int previewPadding = 25;

        EditorGUILayout.BeginHorizontal();
        if (bTexture.tiled)
        {
            EditorGUILayout.LabelField("1 Metre Squared", GUILayout.Width(110));
        }
        GUILayout.Space(previewPadding);
        if (bTexture.patterned)
        {
            EditorGUILayout.LabelField("Texture Pattern Units", GUILayout.Width(120));
        }
        EditorGUILayout.EndHorizontal();
        EditorGUILayout.Space();

        if (Event.current.type == EventType.Repaint)
            texturePreviewPostion = GUILayoutUtility.GetLastRect();

        if (bTexture.tiled)
        {
            Rect previewRect = new Rect(texturePreviewPostion.x, texturePreviewPostion.y, previewTextureUnitSize, previewTextureUnitSize);
            Rect sourceRect = new Rect(0, 0, (1.0f / textureUnitSize.x), (1.0f / textureUnitSize.y));

            Graphics.DrawTexture(previewRect, bTexture.texture, sourceRect, 0, 0, 0, 0);
        }

        if (bTexture.patterned)
        {
            Rect previewRect = new Rect(previewTextureUnitSize + previewPadding, 0, previewTileUnitSize, previewTileUnitSize);
            Rect sourceRect = new Rect(0, tileUnitSize.y, tileUnitSize.x, tileUnitSize.y);

            previewRect.x += texturePreviewPostion.x;
            previewRect.y += texturePreviewPostion.y;

            Graphics.DrawTexture(previewRect, bTexture.texture, sourceRect, 0, 0, 0, 0);

            sourceRect.x += tileUnitSize.x;
            previewRect.x += previewTileUnitSize + previewTileUnitPadding;

            Graphics.DrawTexture(previewRect, bTexture.texture, sourceRect, 0, 0, 0, 0);

            sourceRect.x += -tileUnitSize.x;
            sourceRect.y += -tileUnitSize.y;
            previewRect.x += -(previewTileUnitSize + previewTileUnitPadding);
            previewRect.y += previewTileUnitSize + previewTileUnitPadding;

            Graphics.DrawTexture(previewRect, bTexture.texture, sourceRect, 0, 0, 0, 0);

            sourceRect.x += tileUnitSize.x;
            previewRect.x += previewTileUnitSize + previewTileUnitPadding;

            Graphics.DrawTexture(previewRect, bTexture.texture, sourceRect, 0, 0, 0, 0);
        }

        if (!bTexture.tiled)
        {
            //EditorGUILayout.LabelField("Tile texture");

            EditorGUILayout.BeginHorizontal();
            int currentXTiles = bTexture.tiledX;
            GUILayout.Label("Texture Tile X");
            currentXTiles = EditorGUILayout.IntField(currentXTiles, GUILayout.Width(30));
            if (GUILayout.Button("+", GUILayout.Width(25)))
                currentXTiles++;
            EditorGUI.BeginDisabledGroup(currentXTiles < 2);
            if (GUILayout.Button("-", GUILayout.Width(25)))
                currentXTiles--;
            EditorGUI.EndDisabledGroup();
            bTexture.tiledX = currentXTiles;
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal();
            int currentYTiles = bTexture.tiledY;
            GUILayout.Label("Texture Tile Y");
            currentYTiles = EditorGUILayout.IntField(currentYTiles, GUILayout.Width(30));
            if (GUILayout.Button("+", GUILayout.Width(25)))
                currentYTiles++;
            EditorGUI.BeginDisabledGroup(currentYTiles < 2);
            if (GUILayout.Button("-", GUILayout.Width(25)))
                currentYTiles--;
            EditorGUI.EndDisabledGroup();
            bTexture.tiledY = currentYTiles;
            EditorGUILayout.EndHorizontal();

            GUILayout.Space(10);
            EditorGUILayout.Space();
            if (Event.current.type == EventType.Repaint)
                texturePreviewPostion = GUILayoutUtility.GetLastRect();

            Rect previewRect = new Rect(texturePreviewPostion.x, texturePreviewPostion.y, previewTextureUnitSize, previewTextureUnitSize);
            Rect sourceRect = new Rect(0, 0, currentXTiles, currentYTiles);

            Graphics.DrawTexture(previewRect, bTexture.texture, sourceRect, 0, 0, 0, 0);
        }

        GUILayout.Space(previewTextureUnitSize);

        EditorGUILayout.LabelField("Texture Usage");

        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.LabelField("Walls");
        bTexture.wall = EditorGUILayout.Toggle(bTexture.wall);
        EditorGUILayout.EndHorizontal();

        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.LabelField("Doors");
        bTexture.door = EditorGUILayout.Toggle(bTexture.door);
        EditorGUILayout.EndHorizontal();

        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.LabelField("Windows");
        bTexture.window = EditorGUILayout.Toggle(bTexture.window);
        EditorGUILayout.EndHorizontal();

        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.LabelField("Roofs");
        bTexture.roof = EditorGUILayout.Toggle(bTexture.roof);
        EditorGUILayout.EndHorizontal();

        if (GUILayout.Button("Save Data"))
            SaveData();

        if (GUILayout.Button("Save Data As..."))
            SaveDataAs();
    }
 /// <summary>
 ///  Atlas the entire mesh using newTextureCoords and textures.
 /// </summary>
 /// <param name="newTextureCoords"></param>
 /// <param name="textures"></param>
 public void Atlas(Rect[] newTextureCoords, BuildrTexture[] textures)
 {
     List<int> keys = new List<int>(subTriangles.Keys);
     Atlas(keys.ToArray(), newTextureCoords, textures);
 }
Example #36
0
    public static void InspectorGUI(BuildrEditMode editMode, BuildrData _data)
    {
        int helpWidth = 20;

        data = _data;

        Undo.RecordObject(data, "Facade Modified");

        BuildrFacadeDesign[] facades = data.facades.ToArray();
        int numberOfFacades          = facades.Length;

        selectedFacade = Mathf.Clamp(selectedFacade, 0, numberOfFacades - 1);

        if (numberOfFacades == 0)
        {
            EditorGUILayout.HelpBox("There are no facade designs to show", MessageType.Info);
            return;
        }

        bool hasUnusedFacades = false;
        int  unusedIndex      = 0;

        //Check all facades have een used and warn if there are unused ones
        for (int i = 0; i < numberOfFacades; i++)
        {
            bool facadeUnused = true;
            foreach (BuildrVolume volume in data.plan.volumes)
            {
                if (volume.ContainsFacade(i))
                {
                    facadeUnused = false;
                    break;
                }
            }
            if (facadeUnused)
            {
                hasUnusedFacades = true;
                unusedIndex      = i;
                break;
            }
        }
        if (hasUnusedFacades)
        {
            EditorGUILayout.HelpBox("There are facade designs that are not applied to your building and are unused.\nGo to the Building section to apply them to a facade.\nCheck facade design \"" + facades[unusedIndex].name + "\"", MessageType.Warning);
        }

        //Facade Selector
        EditorGUILayout.BeginVertical("box");
        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.LabelField("Facade Design:", GUILayout.Width(145));
        string[] facadeNames = new string[numberOfFacades];
        for (int f = 0; f < numberOfFacades; f++)
        {
            facadeNames[f] = facades[f].name;
        }
        selectedFacade = EditorGUILayout.Popup(selectedFacade, facadeNames);
        BuildrFacadeDesign bFacade = facades[selectedFacade];

        EditorGUILayout.EndHorizontal();

        EditorGUILayout.BeginHorizontal();

        if (GUILayout.Button("Add", GUILayout.Width(60)))
        {
            data.facades.Add(new BuildrFacadeDesign("new facade " + numberOfFacades));
            facades = data.facades.ToArray();
            numberOfFacades++;
            selectedFacade = numberOfFacades - 1;
        }

        if (GUILayout.Button("Duplicate", GUILayout.Width(90)))
        {
            data.facades.Add(bFacade.Duplicate());
            facades = data.facades.ToArray();
            numberOfFacades++;
            selectedFacade = numberOfFacades - 1;
        }

        if (GUILayout.Button("Delete", GUILayout.Width(70)))
        {
            if (EditorUtility.DisplayDialog("Deleting Facade Design Entry", "Are you sure you want to delete this facade?", "Delete", "Cancel"))
            {
                data.RemoveFacadeDesign(bFacade);
                selectedFacade = 0;
                GUI.changed    = true;

                return;
            }
        }

        if (GUILayout.Button("Import", GUILayout.Width(71)))
        {
            string xmlPath = EditorUtility.OpenFilePanel("Select the XML file...", "Assets/BuildR/Exported/", "xml");
            if (xmlPath == "")
            {
                return;
            }
            BuildrXMLImporter.ImportFacades(xmlPath, _data);
            facades        = _data.facades.ToArray();
            selectedFacade = 0;
            GUI.changed    = true;
        }

        if (GUILayout.Button("Export", GUILayout.Width(71)))
        {
            string xmlPath = EditorUtility.SaveFilePanel("Export as...", "Assets/BuildR/Exported/", _data.name + "_facadeLibrary", "xml");
            if (xmlPath == "")
            {
                return;
            }
            BuildrXMLExporter.ExportFacades(xmlPath, _data);
            GUI.changed = true;
        }
        EditorGUILayout.EndHorizontal();
        EditorGUILayout.Space();
        EditorGUILayout.EndVertical();

        bFacade      = facades[selectedFacade];//reassign
        bFacade.name = EditorGUILayout.TextField("Facade Name: ", bFacade.name);


        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.LabelField("Facade Design Type:", GUILayout.Width(145));
        bFacade.type = (BuildrFacadeDesign.types)EditorGUILayout.EnumPopup(bFacade.type);
        if (GUILayout.Button("?", GUILayout.Width(helpWidth)))
        {
            string helpTitle = "Help - Design Type";
            string helpBody  = "This allows you to select the type of design you're using.\n" +
                               "Simple - the facade openings will be uniform\n" +
                               "Patterned - the facade openings will follow a pattern of defined dimensions and textures\n";
            EditorUtility.DisplayDialog(helpTitle, helpBody, "close");
        }
        EditorGUILayout.EndHorizontal();

        int numberOfTextures = data.textures.Count;

        string[] textureNames = new string[numberOfTextures];
        for (int t = 0; t < numberOfTextures; t++)
        {
            textureNames[t] = data.textures[t].name;
        }

        bFacade.hasWindows = EditorGUILayout.Toggle("Facade Has Bays", bFacade.hasWindows);

        if (bFacade.hasWindows)
        {
            if (bFacade.type == BuildrFacadeDesign.types.simple)
            {
                BuildrBay bbay = bFacade.simpleBay;

                EditorGUILayout.BeginHorizontal();
                EditorGUILayout.LabelField("Render Bay", GUILayout.Width(146));
                bool renderBayBack = EditorGUILayout.Toggle(bbay.renderBack);
                if (renderBayBack != bbay.renderBack)
                {
                    bbay.renderBack = renderBayBack;
                }
                EditorGUILayout.EndHorizontal();

                EditorGUILayout.BeginHorizontal();
                EditorGUILayout.LabelField("Bay Model", GUILayout.Width(146));
                bbay.bayModel = (GameObject)EditorGUILayout.ObjectField(bbay.bayModel, typeof(GameObject), false);
                if (GUILayout.Button("Clear", GUILayout.Width(70)))
                {
                    bbay.bayModel = null;
                }
                EditorGUILayout.EndHorizontal();

                float bbayopeningWidth = Mathf.Max(EditorGUILayout.FloatField("Opening Width", bbay.openingWidth), 0);
                if (bbayopeningWidth != bbay.openingWidth)
                {
                    bbay.openingWidth = bbayopeningWidth;
                }
                float bbayopeningHeight = Mathf.Max(EditorGUILayout.FloatField("Opening Height", bbay.openingHeight), 0);
                if (bbayopeningHeight > data.floorHeight)
                {
                    bbayopeningHeight = data.floorHeight;
                }
                if (bbayopeningHeight != bbay.openingHeight)
                {
                    bbay.openingHeight = bbayopeningHeight;
                }
                float bbayminimumBayWidth = Mathf.Max(EditorGUILayout.FloatField("Min. Spacing", bbay.minimumBayWidth), 0);
                if (bbayminimumBayWidth != bbay.minimumBayWidth)
                {
                    bbay.minimumBayWidth = bbayminimumBayWidth;
                }

                float bbayopeningWidthRatio = EditorGUILayout.Slider("Horizontal Space Ratio", bbay.openingWidthRatio, 0, 1);
                if (bbayopeningWidthRatio != bbay.openingWidthRatio)
                {
                    bbay.openingWidthRatio = bbayopeningWidthRatio;
                }
                float bbayopeningHeightRatio = EditorGUILayout.Slider("Vertical Space Ratio", bbay.openingHeightRatio, 0, 1);
                if (bbayopeningHeightRatio != bbay.openingHeightRatio)
                {
                    bbay.openingHeightRatio = bbayopeningHeightRatio;
                }

                float bbayopeningDepth = EditorGUILayout.Slider("Opening Depth", bbay.openingDepth, -depth, depth);
                if (bbayopeningDepth != bbay.openingDepth)
                {
                    bbay.openingDepth = bbayopeningDepth;
                }
                float bbaycolumnDepth = EditorGUILayout.Slider("Column Depth", bbay.columnDepth, -depth, depth);
                if (bbaycolumnDepth != bbay.columnDepth)
                {
                    bbay.columnDepth = bbaycolumnDepth;
                }
                float bbayrowDepth = EditorGUILayout.Slider("Row Depth", bbay.rowDepth, -depth, depth);
                if (bbayrowDepth != bbay.rowDepth)
                {
                    bbay.rowDepth = bbayrowDepth;
                }
                float bbaycrossDepth = EditorGUILayout.Slider("Cross Depth", bbay.crossDepth, -depth, depth);
                if (bbaycrossDepth != bbay.crossDepth)
                {
                    bbay.crossDepth = bbaycrossDepth;
                }

                int      numberOfTextureSlots = bbay.numberOfTextures;
                string[] titles = new string[numberOfTextureSlots];
                for (int bft = 0; bft < numberOfTextureSlots; bft++)
                {
                    titles[bft] = ((BuildrBay.TextureNames)(bft)).ToString();
                }

                EditorGUILayout.BeginHorizontal();
                EditorGUILayout.LabelField("Wall Surface:", GUILayout.Width(75));
                editTextureOnFacade = EditorGUILayout.Popup(editTextureOnFacade, titles);
                EditorGUILayout.EndHorizontal();

                EditorGUILayout.BeginHorizontal();
                EditorGUILayout.LabelField("Wall Texture:", GUILayout.Width(75));
                int newFacadeTextureID = EditorGUILayout.Popup(bbay.textureValues[editTextureOnFacade], textureNames);
                if (newFacadeTextureID != bbay.textureValues[editTextureOnFacade])
                {
                    bbay.textureValues[editTextureOnFacade] = newFacadeTextureID;
                }
                EditorGUILayout.EndHorizontal();
                BuildrTexture bTexture = data.textures[bbay.textureValues[editTextureOnFacade]];
                Texture2D     texture  = bTexture.texture;
                EditorGUILayout.BeginHorizontal();

                if (texture != null)
                {
                    GUILayout.Label(texture, GUILayout.Width(100), GUILayout.Height(100));
                }
                else
                {
                    EditorGUILayout.HelpBox("No texture assigned for '" + textureNames[bbay.textureValues[editTextureOnFacade]] + "', assign one in the Textures menu above", MessageType.Warning);
                }

                bbay.flipValues[editTextureOnFacade] = EditorGUILayout.Toggle("Flip 90\u00B0", bbay.flipValues[editTextureOnFacade]);

                EditorGUILayout.EndHorizontal();
            }
            else
            {
                //Patterned design GUI

                int numberOfBays       = bFacade.bayPattern.Count;
                int numberOfBayDesigns = data.bays.Count;

                EditorGUILayout.BeginHorizontal();
                GUILayout.BeginHorizontal("box");
                if (GUILayout.Button("Add New Bay Design"))
                {
                    BuildrBay newBay = new BuildrBay("new bay design " + (numberOfBayDesigns + 1));
                    data.bays.Add(newBay);
                    bFacade.bayPattern.Add(numberOfBayDesigns);
                    numberOfBays++;
                    selectedBayPatternIndex = numberOfBays - 1;
                    numberOfBayDesigns++;
                    GUI.changed = true;
                }
                EditorGUILayout.EndHorizontal();
                if (numberOfBays == 0 || data.bays.Count == 0)
                {
                    EditorGUILayout.HelpBox("There are no bay designs to show", MessageType.Info);
//                    EditorGUILayout.EndHorizontal();
                    EditorGUILayout.EndVertical();
                    return;
                }

                BuildrBay[] bays = new BuildrBay[numberOfBays];
                for (int i = 0; i < numberOfBays; i++)
                {
                    bays[i] = data.bays[bFacade.bayPattern[i]];
                }
                selectedBayPatternIndex = Mathf.Clamp(selectedBayPatternIndex, 0, numberOfBays - 1);

                EditorGUILayout.EndHorizontal();
                EditorGUILayout.BeginHorizontal();
                GUILayout.BeginHorizontal("box");
                string[] bayDesignNames = new string[data.bays.Count];
                for (int i = 0; i < numberOfBayDesigns; i++)
                {
                    bayDesignNames[i] = data.bays[i].name;
                }
                selectedBayDesign = EditorGUILayout.Popup(selectedBayDesign, bayDesignNames);
                if (GUILayout.Button("Add Selected"))
                {
                    bFacade.bayPattern.Add(selectedBayDesign);
                    GUI.changed = true;
                }
                if (GUILayout.Button("Duplicate Selected"))
                {
                    BuildrBay newBay = data.bays[selectedBayDesign].Duplicate();
                    data.bays.Add(newBay);
                    bFacade.bayPattern.Add(numberOfBayDesigns);
                    numberOfBays++;
                    selectedBayPatternIndex = numberOfBays - 1;
                    numberOfBayDesigns++;
                    GUI.changed = true;
                }
                EditorGUILayout.EndHorizontal();
                EditorGUILayout.EndHorizontal();

                GUILayout.BeginVertical("box");
                EditorGUILayout.LabelField("Bay Design Order:");
                var scrollbarHStyle    = new GUIStyle(GUI.skin.horizontalScrollbar);
                var scrollbarBackStyle = new GUIStyle();
                var scrollbarVStyle    = new GUIStyle(GUI.skin.verticalScrollbar);
                scrollbarVStyle.fixedHeight = scrollbarVStyle.fixedWidth = 0;
                bayDesignPatternScrollView  = EditorGUILayout.BeginScrollView(bayDesignPatternScrollView, false, false, scrollbarHStyle, scrollbarVStyle, scrollbarBackStyle, GUILayout.Height(40));
                List <string> bayNames = new List <string>();
                foreach (int bayIndex in bFacade.bayPattern)
                {
                    bayNames.Add(data.bays[bayIndex].name);
                }
                selectedBayPatternIndex = GUILayout.Toolbar(selectedBayPatternIndex, bayNames.ToArray());
                EditorGUILayout.EndScrollView();
                BuildrBay bBay = data.bays[bFacade.bayPattern[selectedBayPatternIndex]];

                EditorGUILayout.BeginHorizontal();

                EditorGUI.BeginDisabledGroup(selectedBayPatternIndex == 0);
                if (GUILayout.Button("<<", GUILayout.Width(40)))
                {
                    int bayDesignIndex = bFacade.bayPattern[selectedBayPatternIndex];
                    bFacade.bayPattern.RemoveAt(selectedBayPatternIndex);
                    bFacade.bayPattern.Insert(selectedBayPatternIndex - 1, bayDesignIndex);
                    selectedBayPatternIndex--;
                    GUI.changed = true;
                }
                EditorGUI.EndDisabledGroup();
                if (GUILayout.Button("Remove"))
                {
                    bFacade.bayPattern.RemoveAt(selectedBayPatternIndex);
                    GUI.changed = true;
                }
                if (GUILayout.Button("Delete"))
                {
                    if (EditorUtility.DisplayDialog("Deleting Bay Design Entry", "Are you sure you want to delete this bay?", "Delete", "Cancel"))
                    {
                        int deletedBayDesignIndex = bFacade.bayPattern[selectedBayPatternIndex];
                        Debug.Log("Delete Bay Design " + deletedBayDesignIndex);
                        Debug.Log("Delete Bay Design " + data.bays[deletedBayDesignIndex].name);
                        data.bays.RemoveAt(deletedBayDesignIndex);
                        int numberOfFacadeDesigns = data.facades.Count;
                        for (int i = 0; i < numberOfFacadeDesigns; i++)
                        {
                            BuildrFacadeDesign checkFacade = data.facades[i];
                            int bayPatternSize             = checkFacade.bayPattern.Count;
                            for (int j = 0; j < bayPatternSize; j++)
                            {
                                if (checkFacade.bayPattern[j] == deletedBayDesignIndex)
                                {
                                    checkFacade.bayPattern.RemoveAt(j);
                                    j--;
                                    bayPatternSize--;
                                }
                                else if (checkFacade.bayPattern[j] > deletedBayDesignIndex)
                                {
                                    checkFacade.bayPattern[j]--;
                                }
                            }
                        }
                        GUI.changed = true;
                    }
                }
                EditorGUI.BeginDisabledGroup(selectedBayPatternIndex == numberOfBays - 1);
                if (GUILayout.Button(">>", GUILayout.Width(40)))
                {
                    int bayDesignIndex = bFacade.bayPattern[selectedBayPatternIndex];
                    bFacade.bayPattern.Insert(selectedBayPatternIndex + 2, bayDesignIndex);
                    bFacade.bayPattern.RemoveAt(selectedBayPatternIndex);
                    selectedBayPatternIndex++;
                    GUI.changed = true;
                }
                EditorGUI.EndDisabledGroup();
                EditorGUILayout.EndHorizontal();
                EditorGUILayout.EndVertical();

                GUILayout.Space(10);
                EditorGUILayout.BeginVertical("box");
                bBay.name = EditorGUILayout.TextField("Name: ", bBay.name);
                bool bBayisOpening = EditorGUILayout.Toggle("Has Opening", bBay.isOpening);
                if (bBayisOpening != bBay.isOpening)
                {
                    bBay.isOpening = bBayisOpening;
                }

                bool bBayRenderBack = EditorGUILayout.Toggle("Render Back", bBay.renderBack);
                if (bBayRenderBack != bBay.renderBack)
                {
                    bBay.renderBack = bBayRenderBack;
                }

                EditorGUILayout.BeginHorizontal();
                EditorGUILayout.LabelField("Bay Model", GUILayout.Width(146));
                bBay.bayModel = (GameObject)EditorGUILayout.ObjectField(bBay.bayModel, typeof(GameObject), false);
                if (GUILayout.Button("Clear", GUILayout.Width(70)))
                {
                    bBay.bayModel = null;
                }
                EditorGUILayout.EndHorizontal();

                float bBayopeningWidth = Mathf.Max(EditorGUILayout.FloatField("Opening Width", bBay.openingWidth), 0);
                if (bBayopeningWidth != bBay.openingWidth)
                {
                    bBay.openingWidth = bBayopeningWidth;
                }
                float bBayopeningHeight = Mathf.Clamp(EditorGUILayout.FloatField("Opening Height", bBay.openingHeight), 0, data.floorHeight);
                if (bBayopeningHeight != bBay.openingHeight)
                {
                    bBay.openingHeight = bBayopeningHeight;
                }

                float bBayminimumBayWidth = Mathf.Max(EditorGUILayout.FloatField("Bay Spacing Width", bBay.minimumBayWidth), 0);
                if (bBayminimumBayWidth != bBay.minimumBayWidth)
                {
                    bBay.minimumBayWidth = bBayminimumBayWidth;
                }

                float bBayopeningWidthRatio = EditorGUILayout.Slider("Horizontal Space Ratio", bBay.openingWidthRatio, 0, 1);
                if (bBayopeningWidthRatio != bBay.openingWidthRatio)
                {
                    bBay.openingWidthRatio = bBayopeningWidthRatio;
                }
                float bBayopeningHeightRatio = EditorGUILayout.Slider("Vertical Space Ratio", bBay.openingHeightRatio, 0, 1);
                if (bBayopeningHeightRatio != bBay.openingHeightRatio)
                {
                    bBay.openingHeightRatio = bBayopeningHeightRatio;
                }

                float bBayopeningDepth = EditorGUILayout.Slider("Opening Depth", bBay.openingDepth, -depth, depth);
                if (bBayopeningDepth != bBay.openingDepth)
                {
                    bBay.openingDepth = bBayopeningDepth;
                }
                float bBaycolumnDepth = EditorGUILayout.Slider("Column depth", bBay.columnDepth, -depth, depth);
                if (bBaycolumnDepth != bBay.columnDepth)
                {
                    bBay.columnDepth = bBaycolumnDepth;
                }
                float bBayrowDepth = EditorGUILayout.Slider("Row depth", bBay.rowDepth, -depth, depth);
                if (bBayrowDepth != bBay.rowDepth)
                {
                    bBay.rowDepth = bBayrowDepth;
                }
                float bBaycrossDepth = EditorGUILayout.Slider("Cross depth", bBay.crossDepth, -depth, depth);
                if (bBaycrossDepth != bBay.crossDepth)
                {
                    bBay.crossDepth = bBaycrossDepth;
                }

                //BAY TEXTURES

                int      numberOfTextureSlots = bBay.numberOfTextures;
                string[] titles = new string[numberOfTextureSlots];
                for (int bft = 0; bft < numberOfTextureSlots; bft++)
                {
                    titles[bft] = ((BuildrBay.TextureNames)(bft)).ToString();
                }

                EditorGUILayout.BeginHorizontal();
                EditorGUILayout.LabelField("Surface:", GUILayout.Width(75));
                editTextureOnFacade = EditorGUILayout.Popup(editTextureOnFacade, titles);
                EditorGUILayout.EndHorizontal();

                EditorGUILayout.BeginHorizontal();
                EditorGUILayout.LabelField("Texture:", GUILayout.Width(75));
                bBay.textureValues[editTextureOnFacade] = EditorGUILayout.Popup(bBay.textureValues[editTextureOnFacade], textureNames);
                EditorGUILayout.EndHorizontal();
                BuildrTexture bTexture = data.textures[bBay.textureValues[editTextureOnFacade]];
                Texture2D     texture  = bTexture.texture;
                EditorGUILayout.BeginHorizontal();

                if (texture != null)
                {
                    GUILayout.Label(texture, GUILayout.Width(100), GUILayout.Height(100));
                }
                else
                {
                    EditorGUILayout.HelpBox("No texture assigned for '" + textureNames[bBay.textureValues[editTextureOnFacade]] + "', assign one in the Textures menu above", MessageType.Warning);
                }

                bFacade.flipValues[editTextureOnFacade] = EditorGUILayout.Toggle("Flip 90\u00B0", bFacade.flipValues[editTextureOnFacade]);

                EditorGUILayout.EndHorizontal();
                EditorGUILayout.EndVertical();
            }
        }
        else
        {
            editTextureOnFacade = 7;
            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("Surface:", GUILayout.Width(75));
            EditorGUILayout.LabelField("Wall");
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("Texture:", GUILayout.Width(75));
            int newFacadeTexture = EditorGUILayout.Popup(bFacade.simpleBay.textureValues[editTextureOnFacade], textureNames);
            if (newFacadeTexture != bFacade.simpleBay.textureValues[editTextureOnFacade])
            {
                bFacade.simpleBay.textureValues[editTextureOnFacade] = newFacadeTexture;
            }
            EditorGUILayout.EndHorizontal();
            BuildrTexture bTexture = data.textures[bFacade.simpleBay.textureValues[editTextureOnFacade]];
            Texture2D     texture  = bTexture.texture;
            EditorGUILayout.BeginHorizontal();

            if (texture != null)
            {
                GUILayout.Label(texture, GUILayout.Width(100), GUILayout.Height(100));
            }
            else
            {
                EditorGUILayout.HelpBox("No texture assigned for '" + textureNames[bFacade.simpleBay.textureValues[editTextureOnFacade]] + "', assign one in the Textures menu above", MessageType.Warning);
            }

            bFacade.simpleBay.flipValues[editTextureOnFacade] = EditorGUILayout.Toggle("Flip 90\u00B0", bFacade.simpleBay.flipValues[editTextureOnFacade]);

            EditorGUILayout.EndHorizontal();
        }
    }
Example #37
0
    public static void Build(DynamicMeshGenericMultiMaterialMesh _mesh, BuildrData _data)
    {
        //        timestart = Time.realtimeSinceStartup;
        data     = _data;
        mesh     = _mesh;
        textures = data.textures.ToArray();
        BuildrPlan plan = data.plan;

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

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

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

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

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

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

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

                numberOfFacades++;
            }
        }

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

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

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

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

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

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

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

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

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

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

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

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

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

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


        System.GC.Collect();
    }
Example #38
0
    public static void Build(DynamicMeshGenericMultiMaterialMesh _mesh, BuildrData _data, int volumeIndex)
    {
        data      = _data;
        mesh      = _mesh;
        mesh.name = "Interior Mesh Volume " + volumeIndex;
        textures  = data.textures.ToArray();

        if (!data.renderInteriors)
        {
            return;
        }

        float largestDepthValue = 0;//deepest value of a bay design in the building
        float tallestBay        = 0;

        foreach (BuildrBay bay in data.bays)
        {
            largestDepthValue = Mathf.Max(largestDepthValue, bay.deepestValue);//get the deepest value
            tallestBay        = Mathf.Max(tallestBay, bay.openingHeight + (data.floorHeight - bay.openingHeight) * bay.openingHeightRatio);
        }
        foreach (BuildrFacadeDesign facade in data.facades)
        {
            if (facade.type != BuildrFacadeDesign.types.simple)
            {
                continue;
            }
            largestDepthValue = Mathf.Max(largestDepthValue, facade.simpleBay.deepestValue);//get the deepest value
            if (facade.simpleBay.isOpening)
            {
                tallestBay = Mathf.Max(tallestBay, facade.simpleBay.openingHeight + (data.floorHeight - facade.simpleBay.openingHeight) * facade.simpleBay.openingHeightRatio);
            }
        }


        BuildrFacadeDesign facadeDesign = data.facades[0];
        BuildrPlan         plan         = data.plan;
        BuildrVolume       volume       = plan.volumes[volumeIndex];
        int     numberOfFloors          = volume.numberOfFloors;
        float   floorHeight             = data.floorHeight;
        Vector3 floorHeightVector       = Vector3.up * floorHeight;
        float   ceilingHeight           = tallestBay + (floorHeight - tallestBay) * data.interiorCeilingHeight;

        //Calculate the internal floor plan points
        int numberOfVolumePoints = volume.points.Count;

        Vector2z[] interiorVolumePoints = new Vector2z[numberOfVolumePoints];
        for (int i = 0; i < numberOfVolumePoints; i++)
        {
            Vector3 lastPoint = plan.points[volume.points[(i > 0) ? i - 1 : numberOfVolumePoints - 1]].vector3;
            Vector3 thisPoint = plan.points[volume.points[i]].vector3;
            Vector3 nextPoint = plan.points[volume.points[(i + 1) % numberOfVolumePoints]].vector3;
            Vector3 normalA   = Vector3.Cross(thisPoint - lastPoint, Vector3.up).normalized;
            Vector3 normalB   = Vector3.Cross(nextPoint - thisPoint, Vector3.up).normalized;

            Vector2z facadeALine = new Vector2z(thisPoint - lastPoint);
            Vector2z facadeBLine = new Vector2z(thisPoint - nextPoint);
            //Calculate facade inner origins for floors
            Vector3  facadeOriginV3A        = lastPoint + normalA * largestDepthValue;
            Vector3  facadeOriginV3B        = nextPoint + normalB * largestDepthValue;
            Vector2z facadeOriginA          = new Vector2z(facadeOriginV3A);
            Vector2z facadeOriginB          = new Vector2z(facadeOriginV3B);
            Vector2z facadeLineIntersection = BuildrUtils.FindIntersection(facadeALine, facadeOriginA, facadeBLine, facadeOriginB);

            interiorVolumePoints[i] = facadeLineIntersection;
        }
        List <Vector2z> interiorVolumePointList = new List <Vector2z>(interiorVolumePoints);
        List <Rect>     volumeCores             = new List <Rect>();
        List <int>      linkedPoints            = new List <int>();

        foreach (Rect core in plan.cores)
        {
            Vector2z coreCenter = new Vector2z(core.center);
            if (BuildrUtils.PointInsidePoly(coreCenter, interiorVolumePoints))
            {
                volumeCores.Add(core);
            }
        }
        int  numberOfVolumeCores = volumeCores.Count;
        bool print = plan.volumes.IndexOf(volume) == 3;

        for (int c = 0; c < numberOfVolumeCores; c++)
        {
            int        numberOfInteriorPoints = interiorVolumePointList.Count;
            Rect       coreBounds             = volumeCores[c];
            Vector2z   coreCenter             = new Vector2z(coreBounds.center);
            Vector2z   coreBL = new Vector2z(coreBounds.xMin, coreBounds.yMin);
            Vector2z   coreBR = new Vector2z(coreBounds.xMax, coreBounds.yMin);
            Vector2z   coreTL = new Vector2z(coreBounds.xMin, coreBounds.yMax);
            Vector2z   coreTR = new Vector2z(coreBounds.xMax, coreBounds.yMax);
            Vector2z[] corePointArray;
            corePointArray = new[] { coreBL, coreBR, coreTR, coreTL };
            //Find the nearest legal cut we can make to join the core and interior point poly
            int   connectingPoint         = -1;
            float connectingPointDistance = Mathf.Infinity;
            for (int p = 0; p < numberOfInteriorPoints; p++)
            {
                if (linkedPoints.Contains(p))
                {
                    continue;
                }
                Vector2z thisPoint         = interiorVolumePointList[p];
                float    thisPointDistance = Vector2z.SqrMag(thisPoint, coreCenter);
                if (thisPointDistance < connectingPointDistance)
                {
                    bool legalCut = true;
                    for (int pc = 0; pc < numberOfInteriorPoints; pc++)
                    {
                        Vector2z p0 = interiorVolumePointList[pc];
                        Vector2z p1 = interiorVolumePointList[(pc + 1) % numberOfInteriorPoints];
                        if (BuildrUtils.FastLineIntersection(coreCenter, thisPoint, p0, p1))//check against all lines that this new cut doesn't intersect
                        {
                            if (print)
                            {
                                Debug.Log("FLI " + pc + " " + coreCenter + " " + thisPoint + " " + p0 + " " + p1);
                            }
                            legalCut = false;
                            break;
                        }
                    }
                    if (legalCut)
                    {
                        connectingPoint         = p;
                        connectingPointDistance = thisPointDistance;
                    }
                }
            }
            if (connectingPoint == -1)
            {
                Debug.Log("Buildr Could not place core");
                continue;
            }
            Vector2z chosenPoint                 = interiorVolumePointList[connectingPoint];
            int      connectingCorePoint         = 0;
            float    connectingCorePointDistance = Mathf.Infinity; // Vector2z.SqrMag(corePointArray[0], chosenPoint);
            for (int cp = 0; cp < 4; cp++)                         //find the core point to make the cut
            {
                float thisCorePointDistance = Vector2z.SqrMag(corePointArray[cp], chosenPoint);
                if (thisCorePointDistance < connectingCorePointDistance)
                {
                    connectingCorePoint         = cp;
                    connectingCorePointDistance = thisCorePointDistance;
                }
            }
            interiorVolumePointList.Insert(connectingPoint, chosenPoint); //loop back on the floorplan to close it
            for (int acp = 0; acp < 5; acp++)                             //loop back on itself to close the core
            {
                interiorVolumePointList.Insert(connectingPoint + 1, corePointArray[(connectingCorePoint + acp) % 4]);
            }
            for (int i = 0; i < linkedPoints.Count; i++)
            {
                if (linkedPoints[i] > connectingPoint)
                {
                    linkedPoints[i] += 7;
                }
            }
            linkedPoints.AddRange(new[] { connectingPoint, connectingPoint + 1, connectingPoint + 2, connectingPoint + 3, connectingPoint + 4, connectingPoint + 5, connectingPoint + 6 });
//            linkedPoints.AddRange(new []{connectingPoint,connectingPoint+6});
        }
//        if(linkedPoints.Count > 0)
//        Debug.Log(linkedPoints.Count+" "+linkedPoints[0]);
        Vector2z[] interiorPointListCore = interiorVolumePointList.ToArray();

        for (int f = 0; f < numberOfVolumePoints; f++)
        {
            ///WALLS

            int indexAM = Mathf.Abs((f - 1) % numberOfVolumePoints);
            int indexA  = f;
            int indexB  = (f + 1) % numberOfVolumePoints;
            int indexBP = (f + 2) % numberOfVolumePoints;

            Vector3 p0m        = plan.points[volume.points[indexAM]].vector3;
            Vector3 p0         = plan.points[volume.points[indexA]].vector3;
            Vector3 p1         = plan.points[volume.points[indexB]].vector3;
            Vector3 p1p        = plan.points[volume.points[indexBP]].vector3;
            Vector3 p0interior = interiorVolumePoints[indexA].vector3;
            Vector3 p1interior = interiorVolumePoints[indexB].vector3;

            float   facadeWidth         = Vector3.Distance(p0, p1) - largestDepthValue * 2.0f;
            Vector3 facadeDirection     = (p1 - p0).normalized;
            Vector3 facadeCross         = Vector3.Cross(facadeDirection, Vector3.up);
            Vector3 lastFacadeDirection = (p0 - p0m).normalized;
            Vector3 nextFacadeDirection = (p1p - p1).normalized;

            //only bother with facade directions when facade may intersect inverted geometry
            float facadeDirDotL   = Vector3.Dot(-facadeDirection, lastFacadeDirection);
            float facadeCrossDotL = Vector3.Dot(-facadeCross, lastFacadeDirection);
            if (facadeDirDotL <= 0 || facadeCrossDotL <= 0)
            {
                lastFacadeDirection = -facadeCross;
            }

            float facadeDirDotN   = Vector3.Dot(-facadeDirection, nextFacadeDirection);
            float facadeCrossDotN = Vector3.Dot(-facadeCross, nextFacadeDirection);
            if (facadeDirDotN <= 0 || facadeCrossDotN <= 0)
            {
                nextFacadeDirection = facadeCross;
            }


            int floorBase = plan.GetFacadeFloorHeight(volumeIndex, volume.points[indexA], volume.points[indexB]);
            BuildrVolumeStylesUnit[] styleUnits = volume.styles.GetContentsByFacade(volume.points[indexA]);
            int        floorPatternSize         = 0;
            List <int> facadePatternReference   = new List <int>();  //this contains a list of all the facade style indices to refence when looking for the appropriate style per floor
            int        patternCount             = 0;
            foreach (BuildrVolumeStylesUnit styleUnit in styleUnits) //need to knw how big all the styles are together so we can loop through them
            {
                floorPatternSize += styleUnit.floors;
                for (int i = 0; i < styleUnit.floors; i++)
                {
                    facadePatternReference.Add(patternCount);
                }
                patternCount++;
            }
            facadePatternReference.Reverse();

            int rows = numberOfFloors;


            Vector2 facadeUV = Vector2.zero;

            for (int r = 0; r < rows; r++)
            {
                float   currentFloorHeight       = floorHeight * r;
                Vector3 currentFloorHeightVector = Vector3.up * (data.floorHeight * r);
                Vector3 facadeFloorBaseVector    = p0 + Vector3.up * currentFloorHeight;
                Vector3 ceilingVector            = Vector3.up * ceilingHeight;
                if (r < floorBase)
                {
                    //no facade rendered
                    //facade gap filler

                    //interior gap points
                    Vector3 i0 = p1 - facadeDirection.normalized * largestDepthValue;
                    Vector3 i1 = p0 + facadeDirection.normalized * largestDepthValue;

                    Vector3 w0  = i0 + currentFloorHeightVector;
                    Vector3 w1  = i1 + currentFloorHeightVector;
                    Vector3 w2  = w0 + facadeCross * largestDepthValue;
                    Vector3 w3  = w1 + facadeCross * largestDepthValue;
                    Vector3 w4  = w0 + ceilingVector;
                    Vector3 w5  = w1 + ceilingVector;
                    Vector3 w6  = w2 + ceilingVector;
                    Vector3 w7  = w3 + ceilingVector;
                    Vector3 w8  = p1interior + currentFloorHeightVector;
                    Vector3 w9  = p0interior + currentFloorHeightVector;
                    Vector3 w10 = w8 + ceilingVector;
                    Vector3 w11 = w9 + ceilingVector;

                    //floor
                    AddData(new[] { w0, w1, w2, w3 }, new[] { 0, 1, 2, 1, 3, 2 }, volume.FloorTexture(r), false);

                    //ceiling
                    AddData(new[] { w5, w4, w7, w6 }, new[] { 0, 1, 2, 1, 3, 2 }, volume.CeilingTexture(r), false);

                    //sides
                    int wallSubmesh = volume.WallTexture(r);
                    AddPlane(w0, w2, w4, w6, wallSubmesh, false, Vector3.zero, new Vector2(largestDepthValue, floorHeight));
                    AddPlane(w3, w1, w7, w5, wallSubmesh, false, Vector3.zero, new Vector2(largestDepthValue, floorHeight));

                    //other gaps
                    float uvWidth1 = Vector3.Distance(w2, w8);
                    AddPlane(w2, w8, w6, w10, wallSubmesh, false, Vector3.zero, new Vector2(uvWidth1, floorHeight));
                    float uvWidth2 = Vector3.Distance(w3, w9);
                    AddPlane(w9, w3, w11, w7, wallSubmesh, false, Vector3.zero, new Vector2(uvWidth2, floorHeight));

                    continue;
                }

                //Get the facade style id
                //need to loop through the facade designs floor by floor until we get to the right one
                int modFloor = ((r - floorBase) % floorPatternSize);

                facadeDesign = data.facades[styleUnits[facadePatternReference[modFloor]].styleID];

                bool isBlankWall = !facadeDesign.hasWindows;
                if (facadeDesign.type == BuildrFacadeDesign.types.patterned)
                {
                    if (data.bays.Count == 0 || facadeDesign.bayPattern.Count == 0)
                    {
                        data.illegal = true;
                        return;
                    }

                    BuildrBay firstBay = data.bays[facadeDesign.bayPattern[0]];
                    if (firstBay.openingWidth > facadeWidth)
                    {
                        isBlankWall = true;
                    }
                    if (facadeDesign.bayPattern.Count == 0)
                    {
                        isBlankWall = true;
                    }
                }
                else
                {
                    if (facadeDesign.simpleBay.openingWidth + facadeDesign.simpleBay.minimumBayWidth > facadeWidth)
                    {
                        isBlankWall = true;
                    }
                }

                if (!isBlankWall)
                {
                    float       patternSize  = 0;//the space the pattern fills, there will be a gap that will be distributed to all bay styles
                    int         numberOfBays = 0;
                    BuildrBay[] bayDesignPattern;
                    int         numberOfBayDesigns;
                    if (facadeDesign.type == BuildrFacadeDesign.types.patterned)
                    {
                        numberOfBayDesigns = facadeDesign.bayPattern.Count;
                        bayDesignPattern   = new BuildrBay[numberOfBayDesigns];
                        for (int i = 0; i < numberOfBayDesigns; i++)
                        {
                            bayDesignPattern[i] = data.bays[facadeDesign.bayPattern[i]];
                        }
                    }
                    else
                    {
                        bayDesignPattern   = new[] { facadeDesign.simpleBay };
                        numberOfBayDesigns = 1;
                    }
                    //start with first window width - we'll be adding to this until we have filled the facade width
                    int it = 100;
                    while (true)
                    {
                        int   patternModIndex = numberOfBays % numberOfBayDesigns;
                        float patternAddition = bayDesignPattern[patternModIndex].openingWidth + bayDesignPattern[patternModIndex].minimumBayWidth;
                        if (patternSize + patternAddition < facadeWidth)
                        {
                            patternSize += patternAddition;
                            numberOfBays++;
                        }
                        else
                        {
                            break;
                        }
                        it--;
                        if (it < 0)
                        {
                            break;
                        }
                    }

                    Vector3 windowBase = facadeFloorBaseVector;
                    facadeUV.x  = 0;
                    facadeUV.y += floorHeight;
                    float perBayAdditionalSpacing = (facadeWidth - patternSize) / numberOfBays;
                    for (int c = 0; c < numberOfBays; c++)
                    {
                        BuildrBay bayStyle;
                        BuildrBay lastBay;
                        BuildrBay nextBay;
                        bool      firstColumn = c == 0;
                        bool      lastColumn  = c == numberOfBays - 1;
                        if (facadeDesign.type == BuildrFacadeDesign.types.patterned)
                        {
                            int numberOfBayStyles = facadeDesign.bayPattern.Count;
                            bayStyle = bayDesignPattern[c % numberOfBayStyles];
                            int lastBayIndex = (c > 0) ? (c - 1) % numberOfBayStyles : 0;
                            lastBay = bayDesignPattern[lastBayIndex];
                            nextBay = bayDesignPattern[(c + 1) % numberOfBayStyles];
                        }
                        else
                        {
                            bayStyle = facadeDesign.simpleBay;
                            lastBay  = facadeDesign.simpleBay;
                            nextBay  = facadeDesign.simpleBay;
                        }
                        float actualWindowSpacing = bayStyle.minimumBayWidth + perBayAdditionalSpacing;
                        float leftWidth           = actualWindowSpacing * bayStyle.openingWidthRatio;
                        float rightWidth          = actualWindowSpacing - leftWidth;
                        float openingWidth        = bayStyle.openingWidth;

                        if (firstColumn)
                        {
                            leftWidth += largestDepthValue;
                        }
                        if (lastColumn)
                        {
                            rightWidth += largestDepthValue;
                        }

                        BuildrTexture columnTexture = textures[bayStyle.GetTexture(BuildrBay.TextureNames.ColumnTexture)];
                        Vector2       columnuvunits = columnTexture.tileUnitUV;
                        float         openingHeight = bayStyle.openingHeight;
                        if (columnTexture.patterned)
                        {
                            openingHeight = Mathf.Ceil(bayStyle.openingHeight / columnuvunits.y) * columnuvunits.y;
                        }
                        if (bayStyle.openingHeight == floorHeight)
                        {
                            bayStyle.openingHeight = floorHeight;
                        }

                        float rowBottomHeight = ((floorHeight - openingHeight) * bayStyle.openingHeightRatio);
                        if (columnTexture.patterned)
                        {
                            rowBottomHeight = Mathf.Ceil(rowBottomHeight / columnuvunits.y) * columnuvunits.y;
                        }

                        float rowTopHeight = (floorHeight - rowBottomHeight - openingHeight);

                        bool previousBayIdentical = bayStyle == lastBay;
                        bool nextBayIdentical     = bayStyle == nextBay;
                        if (previousBayIdentical && !firstColumn)
                        {
                            leftWidth = actualWindowSpacing;//if next design is identical - add the two parts together the reduce polycount
                        }
                        Vector3 w0, w1, w2, w3;

                        int  wallSubmesh = volume.WallTexture(r);
                        bool wallFlipped = false;
                        if (!bayStyle.isOpening)
                        {
                            float bayWidthSize = openingWidth + actualWindowSpacing;
                            if (firstColumn || lastColumn)
                            {
                                bayWidthSize += largestDepthValue;
                            }
                            Vector3 bayWidth  = facadeDirection * bayWidthSize;
                            Vector3 bayHeight = Vector3.up * floorHeight;
                            Vector3 bayDepth  = facadeCross * largestDepthValue;
                            w0 = windowBase + bayDepth;
                            w1 = windowBase + bayWidth + bayDepth;
                            w2 = windowBase + bayHeight + bayDepth;
                            w3 = windowBase + bayWidth + bayHeight + bayDepth;
                            Vector2 bayOpeningUVEnd = facadeUV + new Vector2(openingWidth + actualWindowSpacing, floorHeight);
                            AddPlane(w0, w1, w2, w3, wallSubmesh, wallFlipped, facadeUV, bayOpeningUVEnd);

                            windowBase  = windowBase + bayWidth; //move base vertor to next bay
                            facadeUV.x += openingWidth + actualWindowSpacing;
                            continue;                            //bay filled - move onto next bay
                        }

                        var verts = new Vector3[16];
                        verts[0]    = windowBase;
                        verts[1]    = verts[0] + leftWidth * facadeDirection;
                        verts[2]    = verts[1] + openingWidth * facadeDirection;
                        verts[3]    = verts[2] + rightWidth * facadeDirection;
                        windowBase  = (nextBayIdentical) ? verts[2] : verts[3];//move to next window - if next design is identical - well add the two parts together the reduce polycount
                        facadeUV.x += (nextBayIdentical) ? openingWidth : openingWidth + rightWidth;

                        Vector3 rowBottomVector = Vector3.up * rowBottomHeight;
                        verts[4] = verts[0] + rowBottomVector;
                        verts[5] = verts[1] + rowBottomVector;
                        verts[6] = verts[2] + rowBottomVector;
                        verts[7] = verts[3] + rowBottomVector;

                        Vector3 openingVector = Vector3.up * openingHeight;
                        verts[8]  = verts[4] + openingVector;
                        verts[9]  = verts[5] + openingVector;
                        verts[10] = verts[6] + openingVector;
                        verts[11] = verts[7] + openingVector;

                        Vector3 rowTopVector = Vector3.up * rowTopHeight;
                        verts[12] = verts[8] + rowTopVector;
                        verts[13] = verts[9] + rowTopVector;
                        verts[14] = verts[10] + rowTopVector;
                        verts[15] = verts[11] + rowTopVector;

                        //Realign facade end points
                        if (firstColumn)
                        {
                            verts[0]  = p0interior - facadeCross * largestDepthValue + currentFloorHeightVector;
                            verts[4]  = verts[0] + rowBottomVector;
                            verts[8]  = verts[4] + openingVector;
                            verts[12] = verts[8] + rowTopVector;
                        }

                        if (lastColumn)
                        {
                            verts[3]  = p1interior - facadeCross * largestDepthValue + currentFloorHeightVector;
                            verts[7]  = verts[3] + rowBottomVector;
                            verts[11] = verts[7] + openingVector;
                            verts[15] = verts[11] + rowTopVector;
                        }

                        Vector3 openingDepthVector = facadeCross * bayStyle.openingDepth;
                        Vector3 wallDepthVecotr    = facadeCross * largestDepthValue;

                        ///WINDOWS
                        int  windowSubmesh = bayStyle.GetTexture(BuildrBay.TextureNames.OpeningBackTexture);
                        bool windowFlipped = bayStyle.IsFlipped(BuildrBay.TextureNames.OpeningBackTexture);
                        w0 = verts[10] + openingDepthVector;
                        w1 = verts[9] + openingDepthVector;
                        w2 = verts[6] + openingDepthVector;
                        w3 = verts[5] + openingDepthVector;
                        Vector2 windowUVStart = new Vector2(0, 0);
                        Vector2 windowUVEnd   = new Vector2(openingWidth, openingHeight);
                        if (bayStyle.renderBack && !data.cullBays)
                        {
                            AddPlane(w0, w1, w2, w3, windowSubmesh, windowFlipped, windowUVStart, windowUVEnd);
                        }

                        ///COLUMNS
                        //Column Face
                        if (leftWidth > 0)//Column Face Left
                        {
                            w0 = verts[4] + wallDepthVecotr;
                            w1 = verts[5] + wallDepthVecotr;
                            w2 = verts[8] + wallDepthVecotr;
                            w3 = verts[9] + wallDepthVecotr;
                            Vector2 leftColumnUVStart = facadeUV + new Vector2(0, rowBottomHeight);
                            Vector2 leftColumnUVEnd   = leftColumnUVStart + new Vector2(leftWidth, openingHeight);
                            AddPlane(w0, w1, w2, w3, wallSubmesh, wallFlipped, leftColumnUVStart, leftColumnUVEnd);
                        }
                        if ((!nextBayIdentical || lastColumn) && rightWidth > 0)//Column Right
                        {
                            w0 = verts[6] + wallDepthVecotr;
                            w1 = verts[7] + wallDepthVecotr;
                            w2 = verts[10] + wallDepthVecotr;
                            w3 = verts[11] + wallDepthVecotr;
                            Vector2 rightColumnUVStart = facadeUV + new Vector2(leftWidth + openingWidth, rowBottomHeight);
                            Vector2 rightColumnUVEnd   = rightColumnUVStart + new Vector2(rightWidth, openingHeight);
                            AddPlane(w0, w1, w2, w3, wallSubmesh, wallFlipped, rightColumnUVStart, rightColumnUVEnd);
                        }
                        ///ROWS
                        //Row Bottom
                        if (rowBottomHeight > 0)
                        {
                            w0 = verts[1] + wallDepthVecotr;
                            w1 = verts[2] + wallDepthVecotr;
                            w2 = verts[5] + wallDepthVecotr;
                            w3 = verts[6] + wallDepthVecotr;
                            Vector2 bottomRowUVStart = facadeUV + new Vector2(leftWidth, 0);
                            Vector2 bottomRowUVEnd   = bottomRowUVStart + new Vector2(openingWidth, rowBottomHeight);
                            AddPlane(w0, w1, w2, w3, wallSubmesh, wallFlipped, bottomRowUVStart, bottomRowUVEnd);
                        }
                        //Row Top
                        if (rowTopHeight > 0)
                        {
                            w0 = verts[9] + wallDepthVecotr;
                            w1 = verts[10] + wallDepthVecotr;
                            w2 = verts[13] + wallDepthVecotr;
                            w3 = verts[14] + wallDepthVecotr;
                            Vector2 topRowUVStart = facadeUV + new Vector2(leftWidth, rowBottomHeight + openingHeight);
                            Vector2 topRowUVEnd   = topRowUVStart + new Vector2(openingWidth, rowTopHeight);
                            AddPlane(w0, w1, w2, w3, wallSubmesh, wallFlipped, topRowUVStart, topRowUVEnd);
                        }

                        //Cross Left Bottom
                        w0 = verts[0] + wallDepthVecotr;
                        w1 = verts[1] + wallDepthVecotr;
                        w2 = verts[4] + wallDepthVecotr;
                        w3 = verts[5] + wallDepthVecotr;
                        Vector2 crossLBUVStart = facadeUV + new Vector2(0, 0);
                        Vector2 crossLBUVEnd   = crossLBUVStart + new Vector2(leftWidth, rowBottomHeight);
                        AddPlane(w0, w1, w2, w3, wallSubmesh, wallFlipped, crossLBUVStart, crossLBUVEnd);

                        //Cross Left Top
                        w0 = verts[8] + wallDepthVecotr;
                        w1 = verts[9] + wallDepthVecotr;
                        w2 = verts[12] + wallDepthVecotr;
                        w3 = verts[13] + wallDepthVecotr;
                        Vector2 crossLTUVStart = facadeUV + new Vector2(0, rowBottomHeight + openingHeight);
                        Vector2 crossLTUVEnd   = crossLTUVStart + new Vector2(leftWidth, rowTopHeight);
                        AddPlane(w0, w1, w2, w3, wallSubmesh, wallFlipped, crossLTUVStart, crossLTUVEnd);

                        if ((!nextBayIdentical || lastColumn) && rightWidth > 0)
                        {
                            //Cross Right Bottom
                            w0 = verts[2] + wallDepthVecotr;
                            w1 = verts[3] + wallDepthVecotr;
                            w2 = verts[6] + wallDepthVecotr;
                            w3 = verts[7] + wallDepthVecotr;
                            Vector2 crossRBUVStart = facadeUV + new Vector2(leftWidth + openingWidth, 0);
                            Vector2 crossRBUVEnd   = crossRBUVStart + new Vector2(rightWidth, rowBottomHeight);
                            AddPlane(w0, w1, w2, w3, wallSubmesh, wallFlipped, crossRBUVStart, crossRBUVEnd);

                            //Cross Right Top
                            w0 = verts[10] + wallDepthVecotr;
                            w1 = verts[11] + wallDepthVecotr;
                            w2 = verts[14] + wallDepthVecotr;
                            w3 = verts[15] + wallDepthVecotr;
                            Vector2 crossRTUVStart = facadeUV + new Vector2(leftWidth + openingWidth, rowBottomHeight + openingHeight);
                            Vector2 crossRTUVEnd   = crossRTUVStart + new Vector2(rightWidth, rowTopHeight);
                            AddPlane(w0, w1, w2, w3, wallSubmesh, wallFlipped, crossRTUVStart, crossRTUVEnd);
                        }
                    }
                }
                else
                {
                    // windowless wall
                    Vector3 interiorStart = p0interior + currentFloorHeightVector;
                    Vector3 interiorEnd   = p1interior + currentFloorHeightVector;
                    //                        Vector3 wallVector = (facadeDirection * facadeWidth);
                    Vector3       wallHeightVector = Vector3.up * floorHeight;
                    Vector3       w0      = interiorStart;
                    Vector3       w1      = interiorEnd;
                    Vector3       w2      = interiorStart + wallHeightVector;
                    Vector3       w3      = interiorEnd + wallHeightVector;
                    BuildrTexture texture = textures[facadeDesign.simpleBay.GetTexture(BuildrBay.TextureNames.WallTexture)];
                    var           uvSize  = new Vector2(facadeWidth * (1.0f / texture.textureUnitSize.x), floorHeight * (1.0f / texture.textureUnitSize.y));
                    Vector2       uvunits = texture.tileUnitUV;
                    uvSize.x = Mathf.Ceil(uvSize.x / uvunits.x) * uvunits.x;
                    uvSize.y = Mathf.Ceil(uvSize.y / uvunits.y) * uvunits.y;
                    int     wallSubmesh = 0;
                    bool    flipped     = false;
                    Vector2 wallUVStart = facadeUV;
                    Vector2 wallUVEnd   = facadeUV + new Vector2(facadeWidth, floorHeight);
                    AddPlane(w0, w1, w2, w3, wallSubmesh, flipped, wallUVStart, wallUVEnd);
                }
            }
        }

        ///FLOORS AND CEILING
        int numberOfBasements   = volume.numberOfBasementFloors;
        int numberOfFloorPoints = interiorVolumePoints.Length;

        int[]   baseFloorPlanTriangles = EarClipper.Triangulate(interiorVolumePoints);
        int     baseFloorVectors       = interiorVolumePoints.Length;
        var     newEndVerts            = new Vector3[baseFloorVectors];
        Vector3 basementBaseDrop       = -floorHeightVector * numberOfBasements;

        for (int i = 0; i < baseFloorVectors; i++)
        {
            newEndVerts[i] = interiorVolumePoints[i].vector3 + basementBaseDrop;
        }
        var tris = new List <int>(baseFloorPlanTriangles);

        //Bottom Floor
        int floorSubmesh = volume.FloorTexture(-numberOfBasements);

        AddData(newEndVerts, baseFloorPlanTriangles, floorSubmesh, false);

        //Top Ceiling
        if (true)//Todo: add conditional for roof opening
        {
            Vector3 ceilingHeightVector = floorHeightVector * (numberOfFloors - 1 + numberOfBasements) + Vector3.up * ceilingHeight;
            for (int i = 0; i < baseFloorVectors; i++)
            {
                newEndVerts[i] += ceilingHeightVector;
            }
            tris.Reverse();
            AddData(newEndVerts, tris.ToArray(), volume.CeilingTexture(numberOfFloors - 1), false);
        }

        //inner floors
        int[] floorPlanTriangles   = EarClipper.Triangulate(interiorPointListCore);
        int   numberOfFloorVectors = interiorPointListCore.Length;

        for (int floorIndex = -numberOfBasements; floorIndex < numberOfFloors; floorIndex++)
        {
            Vector3 floorVectorHeight = floorHeightVector * floorIndex;
            newEndVerts = new Vector3[numberOfFloorVectors];
            for (int i = 0; i < numberOfFloorVectors; i++)
            {
                newEndVerts[i] = interiorPointListCore[i].vector3 + floorVectorHeight;
            }
            tris = new List <int>(floorPlanTriangles);

            //Floor
            if (floorIndex > -numberOfBasements)
            {
                AddData(newEndVerts, tris.ToArray(), volume.FloorTexture(floorIndex), false);
            }

            //Ceiling
            if (floorIndex < numberOfFloors - 1)
            {
                Vector3 ceilingHeightVector = Vector3.up * ceilingHeight;
                for (int i = 0; i < numberOfFloorVectors; i++)
                {
                    newEndVerts[i] += ceilingHeightVector;
                }
                tris.Reverse();
                AddData(newEndVerts, tris.ToArray(), volume.CeilingTexture(floorIndex), false);
            }

            //basement walls
            if (floorIndex < 0)
            {
                for (int f = 0; f < numberOfFloorPoints; f++)
                {
                    Vector3 basementVector = floorHeightVector * floorIndex;
                    int     indexA         = f;
                    int     indexB         = (f + 1) % numberOfFloorPoints;

                    Vector3 p0  = interiorVolumePoints[indexA].vector3 + basementVector;
                    Vector3 p1  = interiorVolumePoints[indexB].vector3 + basementVector;
                    Vector3 p2  = p0 + floorHeightVector;
                    Vector3 p3  = p1 + floorHeightVector;
                    Vector2 uv1 = new Vector2(Vector3.Distance(p0, p1), floorHeight);
                    AddPlane(p0, p1, p2, p3, volume.WallTexture(floorIndex), false, Vector2.zero, uv1);
                }
            }
        }

        //Core walls
        for (int c = 0; c < numberOfVolumeCores; c++)
        {
            Rect    coreBounds = volumeCores[c];
            Vector3 coreBL     = new Vector3(coreBounds.xMin, 0, coreBounds.yMin);
            Vector3 coreBR     = new Vector3(coreBounds.xMax, 0, coreBounds.yMin);
            Vector3 coreTL     = new Vector3(coreBounds.xMin, 0, coreBounds.yMax);
            Vector3 coreTR     = new Vector3(coreBounds.xMax, 0, coreBounds.yMax);

            for (int floorIndex = -numberOfBasements; floorIndex < numberOfFloors - 1; floorIndex++)
            {
                Vector3 c0        = floorHeightVector * floorIndex + Vector3.up * ceilingHeight;
                Vector3 f0        = floorHeightVector * floorIndex + Vector3.up * floorHeight;
                float   gapHeight = floorHeight - ceilingHeight;
                AddPlane(coreBL + c0, coreBR + c0, coreBL + f0, coreBR + f0, 0, false, Vector2.zero, new Vector2(coreBounds.width, gapHeight));
                AddPlane(coreBR + c0, coreTR + c0, coreBR + f0, coreTR + f0, 0, false, Vector2.zero, new Vector2(coreBounds.width, gapHeight));
                AddPlane(coreTR + c0, coreTL + c0, coreTR + f0, coreTL + f0, 0, false, Vector2.zero, new Vector2(coreBounds.width, gapHeight));
                AddPlane(coreTL + c0, coreBL + c0, coreTL + f0, coreBL + f0, 0, false, Vector2.zero, new Vector2(coreBounds.width, gapHeight));
            }
        }
    }
Example #39
0
    public static void Build(DynamicMeshGenericMultiMaterialMesh _mesh, BuildrData _data)
    {
//        timestart = Time.realtimeSinceStartup;
        data     = _data;
        mesh     = _mesh;
        textures = data.textures.ToArray();
        BuildrPlan plan = data.plan;

        int facadeIndex = 0;

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

        LogTimer("Start");

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

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

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

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

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

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

                numberOfFacades++;
            }
        }

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

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

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

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

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

        if (textureWidth > MAXIMUM_TEXTURESIZE)
        {
            packedScale = MAXIMUM_TEXTURESIZE / (float)textureWidth;
            for (int i = 0; i < numberOfRects; i++)
            {
                Rect thisRect = packedTexturePositions[i];
                thisRect.x               *= packedScale;
                thisRect.y               *= packedScale;
                thisRect.width           *= packedScale;
                thisRect.height          *= packedScale;
                packedTexturePositions[i] = thisRect;
                //Debug.Log("Rects "+roofTextures[i-+packedTexturePositions[i]);
            }
            textureWidth = Mathf.RoundToInt(packedScale * textureWidth);
        }
        else
        {
            textureWidth = (int)Mathf.Pow(2, (Mathf.FloorToInt(Mathf.Log(textureWidth - 1, 2)) + 1));//find the next power of two
        }
        //Debug.Log("Texture Width "+textureWidth);
        //TODO: maybe restrict the resize to a power of two?
        LogTimer("Packed Rect Generated");

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

        LogTimer("texture created");
        Texture2D packedTexture = new Texture2D(textureWidth, textureWidth, TextureFormat.ARGB32, true);

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

        if (data.LODTextureAtlas != null)
        {
            Object.DestroyImmediate(data.LODTextureAtlas);
        }
        data.LODTextureAtlas      = packedTexture;
        data.LODTextureAtlas.name = "Low Detail Texture";

        //build the model with new uvs

        if (data.drawUnderside)
        {
            for (int s = 0; s < numberOfVolumes; s++)
            {
                BuildrVolume volume = plan.volumes[s];
                int          numberOfVolumePoints = volume.points.Count;
                Vector3[]    newEndVerts          = new Vector3[numberOfVolumePoints];
                Vector2[]    newEndUVs            = new Vector2[numberOfVolumePoints];
                for (int i = 0; i < numberOfVolumePoints; i++)
                {
                    newEndVerts[i] = plan.points[volume.points[i]].vector3;
                    newEndUVs[i]   = Vector2.zero;
                }

                List <int> tris = new List <int>(data.plan.GetTrianglesBySectorBase(s));
                tris.Reverse();
                mesh.AddData(newEndVerts, newEndUVs, tris.ToArray(), 0);
            }
        }
        LogTimer("Floor");

        //Build facades
        for (int s = 0; s < numberOfVolumes; s++)
        {
            BuildrVolume volume = plan.volumes[s];
            int          numberOfVolumePoints = volume.points.Count;

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

                int floorBase      = plan.GetFacadeFloorHeight(s, volume.points[indexA], volume.points[indexB]);
                int numberOfFloors = volume.numberOfFloors - floorBase;
                if (numberOfFloors < 1)
                {
                    //no facade - adjacent facade is taller and covers this one
                    continue;
                }
                float floorHeight = data.floorHeight;

                Vector3 floorHeightStart = Vector3.up * (floorBase * floorHeight);
                Vector3 wallHeight       = Vector3.up * (volume.numberOfFloors * floorHeight) - floorHeightStart;

                p0 += floorHeightStart;
                p1 += floorHeightStart;

                Vector3 w0 = p0;
                Vector3 w1 = p1;
                Vector3 w2 = w0 + wallHeight;
                Vector3 w3 = w1 + wallHeight;

                Rect facadeRect = packedTexturePositions[facadeIndex];

                float   imageSize = textureWidth;
                Vector2 uvMin     = new Vector2(facadeRect.xMin / imageSize, facadeRect.yMin / imageSize);
                Vector2 uvMax     = new Vector2(facadeRect.xMax / imageSize, facadeRect.yMax / imageSize);

                mesh.AddPlane(w0, w1, w2, w3, uvMin, uvMax, 0);
                facadeIndex++;
            }
        }
        LogTimer("Facades");

        //ROOF Textures
        int         roofRectBase  = numberOfFacades;
        List <Rect> newAtlasRects = new List <Rect>();

        for (int i = roofRectBase; i < packedTexturePositions.Count; i++)
        {
            Rect uvRect = new Rect();//generate a UV based rectangle off the packed one
            uvRect.x      = packedTexturePositions[i].x / textureWidth;
            uvRect.y      = packedTexturePositions[i].y / textureWidth;
            uvRect.width  = packedTexturePositions[i].width / textureWidth;
            uvRect.height = packedTexturePositions[i].height / textureWidth;
            newAtlasRects.Add(uvRect);
        }
        dynMeshRoof.Atlas(roofTextureIndex.ToArray(), newAtlasRects.ToArray(), data.textures.ToArray());
        //Add the atlased mesh data to the main model data at submesh 0
        mesh.AddData(dynMeshRoof.vertices, dynMeshRoof.uv, dynMeshRoof.triangles, 0);

        LogTimer("Roof B");

        data     = null;
        mesh     = null;
        textures = null;
        //atlasRects = null;

        LogTimer("Done");

        System.GC.Collect();
    }
Example #40
0
    private static void Mansard(BuildrVolume volume, BuildrRoofDesign design)
    {
        BuildrPlan area = data.plan;
        int numberOfVolumePoints = volume.points.Count;
        int numberOfFloors = volume.numberOfFloors;
        float floorHeight = data.floorHeight;
        Vector3 volumeFloorHeight = Vector3.up * (numberOfFloors * floorHeight);

        //add top base of the flat roof
        Vector3[] topVerts = new Vector3[numberOfVolumePoints];
        Vector2[] topUVs = new Vector2[numberOfVolumePoints];
        int topTextureID = design.GetTexture(BuildrRoofDesign.textureNames.floorB);
        BuildrTexture texture = textures[topTextureID];

        for (int l = 0; l < numberOfVolumePoints; l++)
        {
            int indexA, indexB, indexA0, indexB0;
            Vector3 p0, p1, p00, p10;
            indexA = l;
            indexB = (l < numberOfVolumePoints - 1) ? l + 1 : 0;
            indexA0 = (l > 0) ? l - 1 : numberOfVolumePoints - 1;
            indexB0 = (l < numberOfVolumePoints - 2) ? l + 2 : l + 2 - numberOfVolumePoints;

            p0 = area.points[volume.points[indexA]].vector3;
            p1 = area.points[volume.points[indexB]].vector3;
            p00 = area.points[volume.points[indexA0]].vector3;
            p10 = area.points[volume.points[indexB0]].vector3;

            float facadeWidth = Vector3.Distance(p0, p1);
            Vector3 facadeDirection = (p1 - p0).normalized;
            Vector3 facadeDirectionLeft = (p0 - p00).normalized;
            Vector3 facadeDirectionRight = (p10 - p1).normalized;
            Vector3 facadeNormal = Vector3.Cross(facadeDirection, Vector3.up);
            Vector3 facadeNormalLeft = Vector3.Cross(facadeDirectionLeft, Vector3.up);
            Vector3 facadeNormalRight = Vector3.Cross(facadeDirectionRight, Vector3.up);

            float roofHeight = design.height;
            float baseDepth = design.floorDepth;
            float cornerLeftRad = Vector3.Angle(facadeDirection, -facadeDirectionLeft) * Mathf.Deg2Rad / 2;
            float cornerRightRad = Vector3.Angle(-facadeDirection, facadeDirectionRight) * Mathf.Deg2Rad / 2;
            float cornerDepthLeft = baseDepth / Mathf.Sin(cornerLeftRad);
            float cornerDepthRight = baseDepth / Mathf.Sin(cornerRightRad);
            float topDepth = design.depth;
            float cornerTopDepthLeft = topDepth / Mathf.Sin(cornerLeftRad);
            float cornerTopDepthRight = topDepth / Mathf.Sin(cornerRightRad);

            Vector3 pr = facadeDirection * facadeWidth;

            Vector3 leftDir = (facadeNormal + facadeNormalLeft).normalized;
            Vector3 rightDir = (facadeNormal + facadeNormalRight).normalized;

            p0 += volumeFloorHeight;
            p1 += volumeFloorHeight;

            Vector3 w0, w1, w2, w3, w4, w5;
            w0 = p0;
            w1 = p0 + pr;
            w2 = w0 + leftDir * cornerDepthLeft;
            w3 = w1 + rightDir * cornerDepthRight;
            w4 = w2 + leftDir * cornerTopDepthLeft + Vector3.up * roofHeight;
            w5 = w3 + rightDir * cornerTopDepthRight + Vector3.up * roofHeight;

            Vector3[] verts = new Vector3[6] { w0, w1, w2, w3, w4, w5 };
//            List<Vector2> uvs = new List<Vector2>();

            Vector2[] uvsFloor = BuildrProjectUVs.Project(new Vector3[4] { w0, w1, w2, w3 }, Vector2.zero, facadeNormal);
            if(baseDepth == 0)
                uvsFloor[3].x = facadeWidth;
            Vector2[] uvsMansard = BuildrProjectUVs.Project(new Vector3[3] { w2, w4, w5 }, uvsFloor[2], facadeNormal);

            Vector3[] vertsA = new Vector3[4] { verts[0], verts[1], verts[2], verts[3] };
            Vector2[] uvsA = new Vector2[4] { uvsFloor[0], uvsFloor[1], uvsFloor[2], uvsFloor[3] };
            int[] trisA = new int[6] { 1, 0, 2, 1, 2, 3 };
            int subMeshA = design.GetTexture(BuildrRoofDesign.textureNames.floor);
            mesh.AddData(vertsA, uvsA, trisA, subMeshA);

            Vector3[] vertsB = new Vector3[4] { verts[2], verts[3], verts[4], verts[5] };
            Vector2[] uvsB = new Vector2[4] { uvsFloor[2], uvsFloor[3], uvsMansard[1], uvsMansard[2] };
            int[] trisB = new int[6] { 0, 2, 1, 1, 2, 3 };
            int subMeshB = design.GetTexture(BuildrRoofDesign.textureNames.tiles);
            mesh.AddData(vertsB, uvsB, trisB, subMeshB);

            //modify point for the top geometry
            Vector2z point = area.points[volume.points[l]];
            topVerts[l] = point.vector3 + volumeFloorHeight + Vector3.up * roofHeight + leftDir * (cornerDepthLeft + cornerTopDepthLeft);
            topUVs[l] = new Vector2(topVerts[l].x / texture.textureUnitSize.x, topVerts[l].z / texture.textureUnitSize.y);
        }

        Vector2z[] topVertV2z = new Vector2z[topVerts.Length];
        for (int i = 0; i < topVerts.Length; i++)
            topVertV2z[i] = new Vector2z(topVerts[i]);
        int[] topTris = EarClipper.Triangulate(topVertV2z);
        AddData(topVerts, topUVs, topTris, topTextureID);//top
    }