public override bool BuildOnMesh(DMesh3Builder meshBuilder) { Vector3d v00 = Origin, v01 = Origin, v10 = Origin; v01.y += Height; v10 += AlongWidthDirection * Width; Vector3d v11 = v10; v11.y += Height; var vInfo = new NewVertexInfo { bHaveN = true, n = new Vector3f(FrontNormal), }; int i00 = AppentVertex(meshBuilder, vInfo, v00); int i01 = AppentVertex(meshBuilder, vInfo, v01); int i10 = AppentVertex(meshBuilder, vInfo, v10); int i11 = AppentVertex(meshBuilder, vInfo, v11); meshBuilder.AppendTriangle(i00, i11, i01); meshBuilder.AppendTriangle(i00, i10, i11); return(true); }
public static (int, int) FillBetweenEdges(DMesh3Builder meshBuilder, Edge a, Edge b, Vector3f normal) { //var sideA = a.EndVertex - a.BeginVertex; //var sideB = b.EndVertex - b.BeginVertex; //var normal = var a0 = meshBuilder.AppendVertex(new NewVertexInfo(a.BeginVertex, normal)); var a1 = meshBuilder.AppendVertex(new NewVertexInfo(a.EndVertex, normal)); var b0 = meshBuilder.AppendVertex(new NewVertexInfo(b.BeginVertex, normal)); var b1 = meshBuilder.AppendVertex(new NewVertexInfo(b.EndVertex, normal)); return(meshBuilder.AppendTriangle(a0, b1, b0), meshBuilder.AppendTriangle(a0, a1, b1)); }
void Start() { if (model != null) { mesh = model.sharedMesh; meshVertices = mesh.vertices; meshTriangles = mesh.triangles; for (int i = 0; i < meshVertices.Length; i++) { meshVertices[i] = model.transform.TransformPoint(meshVertices[i]); } binarySpacePartition = new BSP(mesh, 14); #if G3_USING_UNITY DMesh3Builder dMeshBuilder = new DMesh3Builder(); dMeshBuilder.AppendNewMesh(false, false, false, false); foreach (Vector3 vertex in meshVertices) { dMeshBuilder.AppendVertex(vertex.x, vertex.y, vertex.z); } for (int i = 0; i < meshTriangles.Length; i += 3) { dMeshBuilder.AppendTriangle(meshTriangles[i], meshTriangles[i + 1], meshTriangles[i + 2]); } g3MeshTree = new DMeshAABBTree3(dMeshBuilder.Meshes[0]); g3MeshTree.Build(); #endif } }
void Start() { if (model != null) { mesh = model.sharedMesh; meshVertices = mesh.vertices; meshTriangles = mesh.triangles; for (int i = 0; i < meshVertices.Length; i++) { meshVertices[i] = model.transform.TransformPoint(meshVertices[i]); } binarySpacePartition = new BSP(mesh, 14); if (diskMaterial) { int numDisksToDraw = Mathf.Min(binarySpacePartition.splittingDisks.Length, 15); diskMatrices = new Matrix4x4[numDisksToDraw]; for (int i = 0; i < numDisksToDraw; i++) { diskMatrices[i] = Matrix4x4.TRS( binarySpacePartition.splittingDisks[i].average, Quaternion.LookRotation(binarySpacePartition.splittingDisks[i].plane), new Vector3(1f, 1f, 0.0001f) * Mathf.Sqrt(binarySpacePartition.splittingDisks[i].sqRadius)); } } #if G3_USING_UNITY DMesh3Builder dMeshBuilder = new DMesh3Builder(); dMeshBuilder.AppendNewMesh(false, false, false, false); foreach (Vector3 vertex in meshVertices) { dMeshBuilder.AppendVertex(vertex.x, vertex.y, vertex.z); } for (int i = 0; i < meshTriangles.Length; i += 3) { dMeshBuilder.AppendTriangle(meshTriangles[i], meshTriangles[i + 1], meshTriangles[i + 2]); } g3MeshTree = new DMeshAABBTree3(dMeshBuilder.Meshes[0]); g3MeshTree.Build(); #endif } }
public override bool BuildOnMesh(DMesh3Builder meshBuilder) { var intrude = double.MaxValue; for (int p = 0; p < BaseShape.Count; ++p) { var nextP = (p + 1) % BaseShape.Count; for (int otherP = 0; otherP < BaseShape.Count; ++otherP) { if (otherP == p || otherP == nextP) { continue; } intrude = Math.Min(intrude, Geometry.PointSqrDistanceToSegment( Tuple.Create(BaseShape[p], BaseShape[nextP]), BaseShape[otherP])); } intrude = Math.Min(intrude, (BaseShape[nextP] - BaseShape[p]).LengthSquared); } if (intrude < 0.0) { throw new Exception("Invalid intrude"); } //intrude /= BaseShape.Count; intrude = Math.Sqrt(intrude) / 5; // scale up base shape and connect to base var newBasePolygon = CompressAndOffsetPolygon(BaseShape, -intrude / 2, Vector3d.Zero); FillBetweenPolygons(meshBuilder, BaseShape, newBasePolygon); // elevale big shape a bit up and connect to big shape var elevation = Vector3d.AxisY * RoofHeight * 0.15; var topOuterPolygon = newBasePolygon.Select(p => p + elevation).ToList(); for (int p = 0; p < newBasePolygon.Count; ++p) { var nextP = ((p + 1) + newBasePolygon.Count) % newBasePolygon.Count; var side = newBasePolygon[nextP] - newBasePolygon[p]; var normal = new Vector3f(side.UnitCross(Vector3d.AxisY)); MeshUtility.FillBetweenEdges(meshBuilder, new MeshUtility.Edge(newBasePolygon[p], newBasePolygon[nextP]), new MeshUtility.Edge(topOuterPolygon[p], topOuterPolygon[nextP]), normal); } // find small polygons on top var topPolygon = CompressAndOffsetPolygon(BaseShape, intrude, Vector3d.AxisY * RoofHeight * 0.85); var brokenSelfIntersections = Geometry.BreakPolygonSelfIntersection(topPolygon); //brokenSelfIntersections = Geometry.BreakPolygonSelfIntersection(brokenSelfIntersections); //brokenSelfIntersections = Geometry.BreakPolygonSelfIntersection(brokenSelfIntersections); // fill some edges of base and top for (int p = 0; p < brokenSelfIntersections.Count; ++p) { var nextP = ((p + 1) + topOuterPolygon.Count) % topOuterPolygon.Count; var sideBase = topPolygon[nextP] - topPolygon[p]; var sideTop = brokenSelfIntersections[nextP].First() - brokenSelfIntersections[p].Last(); var normal = new Vector3f(sideTop.UnitCross(sideBase)); MeshUtility.FillBetweenEdges(meshBuilder, new MeshUtility.Edge(topOuterPolygon[p], topOuterPolygon[nextP]), new MeshUtility.Edge(brokenSelfIntersections[p].Last(), brokenSelfIntersections[nextP].First()), normal); } //return true; // fill triangle fan for multi-point and top var subTopPolygon = new List <Vector3d>(); int firstMultiPoint = Enumerable.Range(0, brokenSelfIntersections.Count) .FirstOrDefault(p => brokenSelfIntersections[p].Count >= 2); for (int pU = firstMultiPoint; pU < brokenSelfIntersections.Count + firstMultiPoint + 1; ++pU) { int p = pU % brokenSelfIntersections.Count; subTopPolygon.Add(brokenSelfIntersections[p].First()); if (brokenSelfIntersections[p].Count > 1) { MeshUtility.FillPolygon(meshBuilder, subTopPolygon, Vector3f.AxisY); subTopPolygon.Clear(); var firstP = topOuterPolygon[p]; var limit = brokenSelfIntersections[p].Count; for (int i = 0; i < limit - 1; ++i) { var curP = brokenSelfIntersections[p][i]; var nextP = brokenSelfIntersections[p][(i + 1) % limit]; var normal = (Vector3f)(firstP - curP).UnitCross(nextP - curP); var firstV = meshBuilder.AppendVertex(new NewVertexInfo { v = firstP, n = normal, }); var curV = meshBuilder.AppendVertex(new NewVertexInfo { v = curP, n = normal, }); var nextV = meshBuilder.AppendVertex(new NewVertexInfo { v = nextP, n = normal, }); meshBuilder.AppendTriangle(firstV, nextV, curV); } subTopPolygon.Add(brokenSelfIntersections[p].Last()); } } subTopPolygon.Add(brokenSelfIntersections[0].First()); MeshUtility.FillPolygon(meshBuilder, subTopPolygon, Vector3f.AxisY); return(true); }