static void Main(string[] args)
        {
            Stopwatch w = new Stopwatch();

            w.Start();

            var ssk = StraightSkeleton.Generate(new Vector2[] {
                new Vector2(-10, 10),
                new Vector2(-1, 10),
                new Vector2(0, 11),
                new Vector2(1, 10),
                new Vector2(10, 10),
                new Vector2(10, -2),
                new Vector2(5, 0),
                new Vector2(7, -10),
                new Vector2(-7, -10),
                new Vector2(-5, 0),
                new Vector2(-10, -2),
            }, new Vector2[][] {
                new Vector2[] {
                    new Vector2(2, 2),
                    new Vector2(2, -2),
                    new Vector2(-2, -2),
                    new Vector2(-2, 2)
                }
            });

            w.Stop();

            Stopwatch w2 = new Stopwatch();

            w2.Start();

            //Extract data from result
            var builder = new SvgBuilder(30);

            //Draw outline
            foreach (var edge in ssk.Borders)
            {
                builder.Circle(edge.Start.Position, 0.2f, "blue");
                builder.Circle(edge.End.Position, 0.2f, "blue");
                builder.Line(edge.Start.Position, edge.End.Position, 2, "blue");
            }

            //Draw offsets
            for (var i = 1; i < 10; i++)
            {
                var offset = ssk.Offset(i / 2f);
                foreach (var polygon in offset)
                {
                    builder.Outline(polygon, "green");
                }
            }

            //Draw spokes
            foreach (var edge in ssk.Spokes)
            {
                builder.Line(edge.Start.Position, edge.End.Position, 4, "lime");
            }

            //Draw straight skeleton
            foreach (var edge in ssk.Skeleton)
            {
                builder.Circle(edge.Start.Position, 0.2f, "hotpink");
                builder.Circle(edge.End.Position, 0.2f, "hotpink");
                builder.Line(edge.Start.Position, edge.End.Position, 2, "hotpink");
            }

            Console.WriteLine(builder);
            Console.Title = string.Format("Elapsed: {0}ms {1}ms", w.ElapsedMilliseconds, w2.ElapsedMilliseconds);
            Console.ReadLine();
        }
Beispiel #2
0
    private static void Hipped(BuildrVolume volume, BuildrRoofDesign design)
    {
        BuildrPlan area = data.plan;
        int numberOfFloors = volume.numberOfFloors;
        float baseHeight = data.floorHeight * numberOfFloors;
        float roofHeight = design.height;
        int numberOfVolumePoints = volume.points.Count;
        int subMesh = design.GetTexture(BuildrRoofDesign.textureNames.tiles);

        Vector2[] volumePoints = new Vector2[numberOfVolumePoints];
        for(int i = 0; i < numberOfVolumePoints; i++)
        {
            volumePoints[i] = area.points[volume.points[i]].vector2;
        }

        Vector2[][] meshData = StraightSkeleton.Calculate(volumePoints);
        Vector2[] triData = meshData[0];
        List<Vector2> interiorPoints = new List<Vector2>(meshData[1]);
        int numberOfVerts = triData.Length;
        Vector3[] verts = new Vector3[numberOfVerts];
        Vector2[] uvs = new Vector2[numberOfVerts];
        int[] tris = new int[numberOfVerts];
        for(int i = 0; i < triData.Length; i+=3)
        {
            Vector2 pa = triData[i];
            Vector2 pb = triData[i+1];
            Vector2 pc = triData[i+2];

            float ah = baseHeight + (interiorPoints.Contains(pa) ? roofHeight : 0);
            float bh = baseHeight + (interiorPoints.Contains(pb) ? roofHeight : 0);
            float ch = baseHeight + (interiorPoints.Contains(pc) ? roofHeight : 0);

            Vector3 v0 = new Vector3(pa.x, ah, pa.y);
            Vector3 v1 = new Vector3(pb.x, bh, pb.y);
            Vector3 v2 = new Vector3(pc.x, ch, pc.y);

            verts[i] = v0;
            verts[i+1] = v1;
            verts[i+2] = v2;

            Vector3 roofBaseDir = (interiorPoints.Contains(pc)) ? v1 - v0 : v2 - v1;
            Vector3 roofBaseNormal = Vector3.Cross(roofBaseDir, Vector3.up);
            Vector2[] uvsMansard = BuildrProjectUVs.Project(new Vector3[3] { v0, v1, v2 }, Vector2.zero, roofBaseNormal);

            uvs[i] = uvsMansard[0];
            uvs[i + 1] = uvsMansard[1];
            uvs[i + 2] = uvsMansard[2];

            tris[i] = i;
            tris[i + 1] = i+2;
            tris[i + 2] = i+1;
        }

        AddData(verts,uvs,tris,subMesh);

        /*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;
        Vector3 ridgeDirection = (r1 - r0);
        float roofLength = Vector3.Distance(r0, r1);
        float ridgeLengthA = Vector3.Distance(basePoints[0], basePoints[1]);
        if (ridgeLengthA > roofLength)
            ridgeLengthA = roofLength;
        float ridgeLengthB = Vector3.Distance(basePoints[2], basePoints[3]);
        if (ridgeLengthB > roofLength)
            ridgeLengthB = roofLength;
        r0 += ridgeDirection.normalized * ridgeLengthA / 2;
        r1 += -ridgeDirection.normalized * ridgeLengthB / 2;

        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;
        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);*/
    }