Beispiel #1
0
        public Modelled3DFloorTile(OBJ model, string textureName)
        {
            TextureName = textureName;
            var indices  = model.FacesByObjgroup.First(x => x.Value.Count > 0).Value;
            var outVerts = new List <TerrainParallaxVertex>();
            var outInds  = new List <int>();
            var dict     = new Dictionary <Tuple <int, int, int>, int>();

            var off = new Vector3(0.5f, 0, 0.5f);

            foreach (var ind in indices)
            {
                var tup = new Tuple <int, int, int>(ind[0], ind[1], ind[2]);
                int targ;
                if (!dict.TryGetValue(tup, out targ))
                {
                    //add a vertex
                    targ = outVerts.Count;
                    var tc = model.TextureCoords[ind[1] - 1];
                    tc.Y = 1 - tc.Y;
                    var vert = new TerrainParallaxVertex(model.Vertices[ind[0] - 1] + off, Vector4.One, tc, 0, model.Normals[ind[2] - 1]);
                    outVerts.Add(vert);
                    dict[tup] = targ;
                }
                outInds.Add(targ);
            }

            //todo: process using projector? (to cut at diagonals)

            Vertices = outVerts.ToArray();
            Indices  = outInds.ToArray();
        }
Beispiel #2
0
        public TerrainParallaxVertex[] GetVertices(GraphicsDevice gd)
        {
            if (VertexBuffer == null)
            {
                RegenTerrain(gd, Bp);
            }
            var dat = new TerrainParallaxVertex[VertexBuffer.VertexCount];

            VertexBuffer.GetData <TerrainParallaxVertex>(dat);
            return(dat);
        }
Beispiel #3
0
        public void RegenTerrain(GraphicsDevice device, Blueprint blueprint)
        {
            if (GrassState == null)
            {
                TerrainDirty = true; //yikes! try again to see if we have it next frame
                return;
            }
            TerrainDirty = false;
            if (VertexBuffer != null)
            {
                IndexBuffer.Dispose();
                BladeIndexBuffer.Dispose();
                VertexBuffer.Dispose();
                GridIndexBuffer?.Dispose();
                TGridIndexBuffer?.Dispose();
            }

            /** Convert rectangle to world units **/
            var quads = Size.Width;

            var quadWidth  = WorldSpace.GetWorldFromTile((float)Size.Width / (float)quads);
            var quadHeight = WorldSpace.GetWorldFromTile((float)Size.Height / (float)quads);
            var numQuads   = quads * quads;
            var archSize   = quads;

            TerrainParallaxVertex[] Geom = new TerrainParallaxVertex[numQuads * 4];
            int[] Indexes      = new int[numQuads * 6];
            int[] BladeIndexes = new int[numQuads * 6];
            NumPrimitives = (numQuads * 2);

            int geomOffset   = 0;
            int indexOffset  = 0;
            int bindexOffset = 0;

            var offsetX = WorldSpace.GetWorldFromTile(Size.X);
            var offsetY = WorldSpace.GetWorldFromTile(Size.Y);

            for (var y = 0; y < quads; y++)
            {
                for (var x = 0; x < quads; x++)
                {
                    var tl = new Vector3(offsetX + (x * quadWidth), 0.0f, offsetY + (y * quadHeight));
                    var tr = new Vector3(tl.X + quadWidth, 0.0f, tl.Z);
                    var bl = new Vector3(tl.X, 0.0f, tl.Z + quadHeight);
                    var br = new Vector3(tl.X + quadWidth, 0.0f, tl.Z + quadHeight);

                    tl.Y = GetElevationPoint(x, y);
                    tr.Y = GetElevationPoint(x + 1, y);
                    bl.Y = GetElevationPoint(x, y + 1);
                    br.Y = GetElevationPoint(x + 1, y + 1);

                    Indexes[indexOffset++] = geomOffset;
                    Indexes[indexOffset++] = (geomOffset + 1);
                    Indexes[indexOffset++] = (geomOffset + 2);

                    Indexes[indexOffset++] = (geomOffset + 2);
                    Indexes[indexOffset++] = (geomOffset + 3);
                    Indexes[indexOffset++] = geomOffset;

                    short tx = (short)x, ty = (short)y;

                    if (blueprint.GetFloor(tx, ty, 1).Pattern == 0 &&
                        (blueprint.GetWall(tx, ty, 1).Segments & (WallSegments.HorizontalDiag | WallSegments.VerticalDiag)) == 0)
                    {
                        BladeIndexes[bindexOffset++] = geomOffset;
                        BladeIndexes[bindexOffset++] = (geomOffset + 1);
                        BladeIndexes[bindexOffset++] = (geomOffset + 2);

                        BladeIndexes[bindexOffset++] = (geomOffset + 2);
                        BladeIndexes[bindexOffset++] = (geomOffset + 3);
                        BladeIndexes[bindexOffset++] = geomOffset;
                    }

                    Color tlCol = Color.Lerp(LightGreen, LightBrown, GetGrassState(x, y));
                    Color trCol = Color.Lerp(LightGreen, LightBrown, GetGrassState(x + 1, y));
                    Color blCol = Color.Lerp(LightGreen, LightBrown, GetGrassState(x, y + 1));
                    Color brCol = Color.Lerp(LightGreen, LightBrown, GetGrassState(x + 1, y + 1));

                    Geom[geomOffset++] = new TerrainParallaxVertex(tl, tlCol.ToVector4(), new Vector2(((x - y) + 1) * 0.5f, (x + y) * 0.5f), GetGrassState(x, y), GetNormalAt(x, y));
                    Geom[geomOffset++] = new TerrainParallaxVertex(tr, trCol.ToVector4(), new Vector2(((x - y) + 2) * 0.5f, (x + 1 + y) * 0.5f), GetGrassState(x + 1, y), GetNormalAt(x + 1, y));
                    Geom[geomOffset++] = new TerrainParallaxVertex(br, brCol.ToVector4(), new Vector2(((x - y) + 1) * 0.5f, (x + y + 2) * 0.5f), GetGrassState(x + 1, y + 1), GetNormalAt(x + 1, y + 1));
                    Geom[geomOffset++] = new TerrainParallaxVertex(bl, blCol.ToVector4(), new Vector2((x - y) * 0.5f, (x + y + 1) * 0.5f), GetGrassState(x, y + 1), GetNormalAt(x, y + 1));
                }
            }

            var GridIndices  = (Bp.FineArea != null) ? GetGridIndicesForFine(Bp.FineArea, quads) : GetGridIndicesForArea(Bp.BuildableArea, quads);
            var TGridIndices = GetGridIndicesForArea(Bp.TargetBuildableArea, quads);

            VertexBuffer = new VertexBuffer(device, typeof(TerrainParallaxVertex), Geom.Length, BufferUsage.None);
            VertexBuffer.SetData(Geom);

            IndexBuffer = new IndexBuffer(device, IndexElementSize.ThirtyTwoBits, sizeof(int) * Indexes.Length, BufferUsage.None);
            IndexBuffer.SetData(Indexes);

            BladePrimitives = (bindexOffset / 3);

            BladeIndexBuffer = new IndexBuffer(device, IndexElementSize.ThirtyTwoBits, sizeof(int) * Indexes.Length, BufferUsage.None);
            BladeIndexBuffer.SetData(BladeIndexes);
            GeomLength = Geom.Length;

            var primLength = (GridAsTexture) ? 3 : 2;

            if (GridIndices.Length > 0)
            {
                GridIndexBuffer = new IndexBuffer(device, IndexElementSize.ThirtyTwoBits, sizeof(int) * GridIndices.Length, BufferUsage.None);
                GridIndexBuffer.SetData(GridIndices);
                GridPrimitives = GridIndices.Length / primLength;
            }

            if (TGridIndices.Length > 0)
            {
                TGridIndexBuffer = new IndexBuffer(device, IndexElementSize.ThirtyTwoBits, sizeof(int) * TGridIndices.Length, BufferUsage.None);
                TGridIndexBuffer.SetData(TGridIndices);
                TGridPrimitives = TGridIndices.Length / primLength;
            }

            if (GridTex == null)
            {
                using (var strm = File.Open($"Content/Textures/lot/tile_dashed.png", FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    GridTex = GenMips(device, Texture2D.FromStream(device, strm));
                }
            }
        }
Beispiel #4
0
        public RoofData MeshRectData(int level)
        {
            var rects = RoofRects[level - 2];

            if (rects == null)
            {
                return(null);
            }
            var advRoof = true;

            var numQuads = rects.Count * 4; //4 sides for each roof rectangle

            TerrainParallaxVertex[] Vertices = new TerrainParallaxVertex[numQuads * 4];
            int[] Indices = new int[numQuads * 6];

            TerrainParallaxVertex[] AdvVertices = null;
            int[] AdvIndices       = null;
            int   advNumPrimitives = 0;

            if (advRoof)
            {
                //advanced roof: add down facing edges at each side,
                //and edge guards
                var advQuads = numQuads * (1 + 3); //1 quad for the rim, then 3 for the edge
                advQuads        += rects.Count;    //bottom
                AdvVertices      = new TerrainParallaxVertex[advQuads * 4];
                AdvIndices       = new int[advQuads * 6];
                advNumPrimitives = advQuads * 2;
            }

            var numPrimitives = (numQuads * 2);
            int geomOffset    = 0;
            int indexOffset   = 0;

            int advGeomOffset  = 0;
            int advIndexOffset = 0;

            var mat3 = Matrix.CreateRotationZ((float)(Math.PI / -2f));                                                 //good
            var mat1 = Matrix.CreateRotationZ((float)(Math.PI / -2f));
            var mat4 = Matrix.CreateRotationX((float)(Math.PI / 2f)) * Matrix.CreateRotationZ((float)(Math.PI / -2f)); //good
            var mat2 = Matrix.CreateRotationX((float)(Math.PI / 2f)) * Matrix.CreateRotationZ((float)(Math.PI / 2f));

            var edgeT = 0.7f;
            var edgeO = new Vector3(0, 0.005f, 0);

            var advCol = RoofAvgColor.ToVector4();

            foreach (var rect in rects)
            {
                //determine roof height of the smallest edge. This height will be used on all edges
                var height = Math.Min(rect.x2 - rect.x1, rect.y2 - rect.y1) / 2;
                //    /    \
                //   /      \
                //  /________\  Draw 4 segments like this. two segments will have the top middle section so short it will not appear.

                var heightMod = 0;// height / 400f;
                var pitch     = RoofPitch;
                var tl        = ToWorldPos(rect.x1, rect.y1, 0, level, pitch) + new Vector3(0, heightMod, 0);
                var tr        = ToWorldPos(rect.x2, rect.y1, 0, level, pitch) + new Vector3(0, heightMod, 0);
                var bl        = ToWorldPos(rect.x1, rect.y2, 0, level, pitch) + new Vector3(0, heightMod, 0);
                var br        = ToWorldPos(rect.x2, rect.y2, 0, level, pitch) + new Vector3(0, heightMod, 0);

                var m_tl = ToWorldPos(rect.x1 + height, rect.y1 + height, height, level, pitch) + new Vector3(0, heightMod, 0);
                var m_tr = ToWorldPos(rect.x2 - height, rect.y1 + height, height, level, pitch) + new Vector3(0, heightMod, 0);
                var m_bl = ToWorldPos(rect.x1 + height, rect.y2 - height, height, level, pitch) + new Vector3(0, heightMod, 0);
                var m_br = ToWorldPos(rect.x2 - height, rect.y2 - height, height, level, pitch) + new Vector3(0, heightMod, 0);

                var thickness = new Vector3(0, -0.5f, 0);

                var b_tl = tl + thickness;
                var b_tr = tr + thickness;
                var b_bl = bl + thickness;
                var b_br = br + thickness;

                Color   topCol   = Color.White; //Color.Lerp(Color.White, new Color(175, 175, 175), pitch);
                Color   rightCol = Color.White; //Color.White;
                Color   btmCol   = Color.White; //Color.Lerp(Color.White, new Color(200, 200, 200), pitch);
                Color   leftCol  = Color.White; //Color.Lerp(Color.White, new Color(150, 150, 150), pitch);
                Vector4 darken   = new Vector4(0.8f, 0.8f, 0.8f, 1.0f);

                //quad as two tris
                for (int j = 0; j < 16; j += 4)
                {
                    Indices[indexOffset++] = (geomOffset + 2) + j;
                    Indices[indexOffset++] = (geomOffset + 1) + j;
                    Indices[indexOffset++] = geomOffset + j;

                    Indices[indexOffset++] = geomOffset + j;
                    Indices[indexOffset++] = (geomOffset + 3) + j;
                    Indices[indexOffset++] = (geomOffset + 2) + j;
                }

                var     n1       = -Vector3.Normalize(Vector3.Cross(tl - tr, tr - m_tr));
                Vector2 texScale = new Vector2(2 / 3f, 1f) * TexRescale;
                Vertices[geomOffset++] = new TerrainParallaxVertex(tl, topCol.ToVector4(), new Vector2(tl.X, tl.Z * -1) * texScale, 0, n1, mat1, true);
                Vertices[geomOffset++] = new TerrainParallaxVertex(tr, topCol.ToVector4(), new Vector2(tr.X, tr.Z * -1) * texScale, 0, n1, mat1, true);
                Vertices[geomOffset++] = new TerrainParallaxVertex(m_tr, topCol.ToVector4() * 1.25f, new Vector2(m_tr.X, m_tr.Z * -1) * texScale, 0, n1, mat1, true);
                Vertices[geomOffset++] = new TerrainParallaxVertex(m_tl, topCol.ToVector4() * 1.25f, new Vector2(m_tl.X, m_tl.Z * -1) * texScale, 0, n1, mat1, true);

                var n2 = -Vector3.Normalize(Vector3.Cross(tr - br, br - m_br));
                Vertices[geomOffset++] = new TerrainParallaxVertex(tr, rightCol.ToVector4(), new Vector2(tr.Z, tr.X) * texScale, 0, n2, mat2, true);
                Vertices[geomOffset++] = new TerrainParallaxVertex(br, rightCol.ToVector4(), new Vector2(br.Z, br.X) * texScale, 0, n2, mat2, true);
                Vertices[geomOffset++] = new TerrainParallaxVertex(m_br, rightCol.ToVector4() * 1.25f, new Vector2(m_br.Z, m_br.X) * texScale, 0, n2, mat2, true);
                Vertices[geomOffset++] = new TerrainParallaxVertex(m_tr, rightCol.ToVector4() * 1.25f, new Vector2(m_tr.Z, m_tr.X) * texScale, 0, n2, mat2, true);

                var n3 = -Vector3.Normalize(Vector3.Cross(br - bl, bl - m_bl));
                Vertices[geomOffset++] = new TerrainParallaxVertex(br, btmCol.ToVector4(), new Vector2(br.X, br.Z) * texScale, 0, n3, mat3, false);
                Vertices[geomOffset++] = new TerrainParallaxVertex(bl, btmCol.ToVector4(), new Vector2(bl.X, bl.Z) * texScale, 0, n3, mat3, false);
                Vertices[geomOffset++] = new TerrainParallaxVertex(m_bl, btmCol.ToVector4() * 1.25f, new Vector2(m_bl.X, m_bl.Z) * texScale, 0, n3, mat3, false);
                Vertices[geomOffset++] = new TerrainParallaxVertex(m_br, btmCol.ToVector4() * 1.25f, new Vector2(m_br.X, m_br.Z) * texScale, 0, n3, mat3, false);

                var n4 = -Vector3.Normalize(Vector3.Cross(bl - tl, tl - m_tl));
                Vertices[geomOffset++] = new TerrainParallaxVertex(bl, leftCol.ToVector4(), new Vector2(bl.Z, bl.X * -1) * texScale, 0, n4, mat4, false);
                Vertices[geomOffset++] = new TerrainParallaxVertex(tl, leftCol.ToVector4(), new Vector2(tl.Z, tl.X * -1) * texScale, 0, n4, mat4, false);
                Vertices[geomOffset++] = new TerrainParallaxVertex(m_tl, leftCol.ToVector4() * 1.25f, new Vector2(m_tl.Z, m_tl.X * -1) * texScale, 0, n4, mat4, false);
                Vertices[geomOffset++] = new TerrainParallaxVertex(m_bl, leftCol.ToVector4() * 1.25f, new Vector2(m_bl.Z, m_bl.X * -1) * texScale, 0, n4, mat4, false);

                if (advRoof)
                {
                    for (int j = 0; j < 20; j += 4)
                    {
                        AdvIndices[advIndexOffset++] = (advGeomOffset + 2) + j;
                        AdvIndices[advIndexOffset++] = (advGeomOffset + 1) + j;
                        AdvIndices[advIndexOffset++] = advGeomOffset + j;

                        AdvIndices[advIndexOffset++] = advGeomOffset + j;
                        AdvIndices[advIndexOffset++] = (advGeomOffset + 3) + j;
                        AdvIndices[advIndexOffset++] = (advGeomOffset + 2) + j;
                    }

                    //thickness
                    var n5 = Vector3.Normalize(Vector3.Cross(tl - tr, tr - b_tr));
                    AdvVertices[advGeomOffset++] = new TerrainParallaxVertex(b_tr, advCol, PosToTexCRim(b_tr, 0.73f), 0, n5, mat1, true);
                    AdvVertices[advGeomOffset++] = new TerrainParallaxVertex(tr, advCol, PosToTexCRim(tr, 0.4f), 0, n5, mat1, true);
                    AdvVertices[advGeomOffset++] = new TerrainParallaxVertex(tl, advCol, PosToTexCRim(tl, 0.4f), 0, n5, mat1, true);
                    AdvVertices[advGeomOffset++] = new TerrainParallaxVertex(b_tl, advCol, PosToTexCRim(b_tl, 0.73f), 0, n5, mat1, true);

                    n5 = Vector3.Normalize(Vector3.Cross(tr - br, br - b_br));
                    AdvVertices[advGeomOffset++] = new TerrainParallaxVertex(b_br, advCol, PosToTexCRim(b_br, 0.73f), 0, n5, mat2, true);
                    AdvVertices[advGeomOffset++] = new TerrainParallaxVertex(br, advCol, PosToTexCRim(br, 0.4f), 0, n5, mat2, true);
                    AdvVertices[advGeomOffset++] = new TerrainParallaxVertex(tr, advCol, PosToTexCRim(tr, 0.4f), 0, n5, mat2, true);
                    AdvVertices[advGeomOffset++] = new TerrainParallaxVertex(b_tr, advCol, PosToTexCRim(b_tr, 0.73f), 0, n5, mat2, true);

                    n5 = Vector3.Normalize(Vector3.Cross(br - bl, bl - b_bl));
                    AdvVertices[advGeomOffset++] = new TerrainParallaxVertex(b_bl, advCol, PosToTexCRim(b_bl, 0.73f), 0, n5, mat3, false);
                    AdvVertices[advGeomOffset++] = new TerrainParallaxVertex(bl, advCol, PosToTexCRim(bl, 0.4f), 0, n5, mat3, false);
                    AdvVertices[advGeomOffset++] = new TerrainParallaxVertex(br, advCol, PosToTexCRim(br, 0.4f), 0, n5, mat3, false);
                    AdvVertices[advGeomOffset++] = new TerrainParallaxVertex(b_br, advCol, PosToTexCRim(b_br, 0.73f), 0, n5, mat3, false);

                    n5 = Vector3.Normalize(Vector3.Cross(bl - tl, tl - b_tl));
                    AdvVertices[advGeomOffset++] = new TerrainParallaxVertex(b_tl, advCol, PosToTexCRim(b_tl, 0.73f), 0, n5, mat4, false);
                    AdvVertices[advGeomOffset++] = new TerrainParallaxVertex(tl, advCol, PosToTexCRim(tl, 0.4f), 0, n5, mat4, false);
                    AdvVertices[advGeomOffset++] = new TerrainParallaxVertex(bl, advCol, PosToTexCRim(bl, 0.4f), 0, n5, mat4, false);
                    AdvVertices[advGeomOffset++] = new TerrainParallaxVertex(b_bl, advCol, PosToTexCRim(b_bl, 0.73f), 0, n5, mat4, false);

                    //bottom (solid black)

                    n5 = Vector3.Normalize(Vector3.Cross(b_tl - b_br, b_br - b_bl));
                    AdvVertices[advGeomOffset++] = new TerrainParallaxVertex(b_bl, advCol, new Vector2(0, 0.4f + 0.33f), 0, n5, mat4, false);
                    AdvVertices[advGeomOffset++] = new TerrainParallaxVertex(b_br, advCol, new Vector2(0, 0.4f + 0.33f), 0, n5, mat4, false);
                    AdvVertices[advGeomOffset++] = new TerrainParallaxVertex(b_tr, advCol, new Vector2(0, 0.4f + 0.33f), 0, n5, mat4, false);
                    AdvVertices[advGeomOffset++] = new TerrainParallaxVertex(b_tl, advCol, new Vector2(0, 0.4f + 0.33f), 0, n5, mat4, false);

                    //outer edge: 3 quads for top, left and right edges (on each side!)

                    Action <Vector3, Vector3, Vector3, Vector3, Vector3, Matrix, bool> addEdge = (l, r, m_l, m_r, normal, mat, flip) =>
                    {
                        var lToR = r - l;
                        lToR.Normalize();
                        var lInner = l + lToR * edgeT;
                        var rInner = r - lToR * edgeT;

                        var mlToL      = l - m_l;
                        var diagLength = mlToL.Length();
                        mlToL.Normalize();
                        var mlInner         = m_l + (mlToL + lToR) * edgeT;
                        var innerDiagLength = (mlInner - lInner).Length();

                        var mrToR = r - m_r;
                        mrToR.Normalize();
                        var mrInner = m_r + (mrToR - lToR) * edgeT;

                        for (int j = 0; j < 12; j += 4)
                        {
                            AdvIndices[advIndexOffset++] = (advGeomOffset + 2) + j;
                            AdvIndices[advIndexOffset++] = (advGeomOffset + 1) + j;
                            AdvIndices[advIndexOffset++] = advGeomOffset + j;

                            AdvIndices[advIndexOffset++] = advGeomOffset + j;
                            AdvIndices[advIndexOffset++] = (advGeomOffset + 3) + j;
                            AdvIndices[advIndexOffset++] = (advGeomOffset + 2) + j;
                        }

                        var idOff = (diagLength - innerDiagLength) * 0.1f;
                        var hmul  = 0.5f;
                        AdvVertices[advGeomOffset++] = new TerrainParallaxVertex(mlInner + edgeO, advCol, new Vector2(-idOff * hmul, 0.33f), 0, normal, mat, flip);
                        AdvVertices[advGeomOffset++] = new TerrainParallaxVertex(m_l + edgeO, advCol, new Vector2(0, 0), 0, normal, mat, flip);
                        AdvVertices[advGeomOffset++] = new TerrainParallaxVertex(l + edgeO, advCol, new Vector2(diagLength * -hmul, 0), 0, normal, mat, flip);
                        AdvVertices[advGeomOffset++] = new TerrainParallaxVertex(lInner + edgeO, advCol, new Vector2((idOff + innerDiagLength) * -hmul, 0.33f), 0, normal, mat, flip);

                        var topLength      = (m_r - m_l).Length();
                        var innerTopLength = (mrInner - mlInner).Length();
                        var itOff          = (topLength - innerTopLength) / 2;

                        AdvVertices[advGeomOffset++] = new TerrainParallaxVertex(mrInner + edgeO, advCol, new Vector2((itOff + innerTopLength) * hmul, 0.33f), 0, normal, mat, flip);
                        AdvVertices[advGeomOffset++] = new TerrainParallaxVertex(m_r + edgeO, advCol, new Vector2(topLength * hmul, 0), 0, normal, mat, flip);
                        AdvVertices[advGeomOffset++] = new TerrainParallaxVertex(m_l + edgeO, advCol, new Vector2(0, 0), 0, normal, mat, flip);
                        AdvVertices[advGeomOffset++] = new TerrainParallaxVertex(mlInner + edgeO, advCol, new Vector2(itOff * hmul, 0.33f), 0, normal, mat, flip);

                        AdvVertices[advGeomOffset++] = new TerrainParallaxVertex(mrInner + edgeO, advCol, new Vector2((topLength + idOff) * hmul, 0.33f), 0, normal, mat, flip);
                        AdvVertices[advGeomOffset++] = new TerrainParallaxVertex(rInner + edgeO, advCol, new Vector2((topLength + idOff + innerDiagLength) * hmul, 0.33f), 0, normal, mat, flip);
                        AdvVertices[advGeomOffset++] = new TerrainParallaxVertex(r + edgeO, advCol, new Vector2((topLength + diagLength) * hmul, 0f), 0, normal, mat, flip);
                        AdvVertices[advGeomOffset++] = new TerrainParallaxVertex(m_r + edgeO, advCol, new Vector2(topLength * hmul, 0f), 0, normal, mat, flip);
                    };

                    addEdge(tl, tr, m_tl, m_tr, n1, mat1, true);
                    addEdge(tr, br, m_tr, m_br, n2, mat2, true);
                    addEdge(br, bl, m_br, m_bl, n3, mat3, false);
                    addEdge(bl, tl, m_bl, m_tl, n4, mat4, false);
                }
            }

            var result = new RoofData()
            {
                Vertices      = Vertices,
                Indices       = Indices,
                NumPrimitives = numPrimitives,

                AdvVertices      = AdvVertices,
                AdvIndices       = AdvIndices,
                AdvNumPrimitives = advNumPrimitives
            };

            return(result);
        }