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