private static void ToMesh(ref BuildRMesh mesh, Vector2[] points, float height, int submesh, Surface surface) { int vertCount = points.Length; Vector3[] verts = new Vector3[vertCount]; for (int i = 0; i < vertCount; i++) { verts[i] = new Vector3(points[i].x, height, points[i].y); } Vector2[] uvs = new Vector2[vertCount]; Vector3[] normals = new Vector3[vertCount]; Vector4[] tangents = new Vector4[vertCount]; Vector4 tangent = BuildRMesh.CalculateTangent(Vector3.right); for (int v = 0; v < vertCount; v++) { if (surface != null) { uvs[v] = surface.CalculateUV(points[v]); } normals[v] = Vector3.up; tangents[v] = tangent; } // int[] topTris = EarClipper.Triangulate(points); int[] topTris = Poly2TriWrapper.Triangulate(points); for (int t = 0; t < topTris.Length; t += 3) { int ia = topTris[t]; int ib = topTris[t + 1]; int ic = topTris[t + 2]; Debug.DrawLine(verts[topTris[ia]], verts[topTris[ib]]); Debug.DrawLine(verts[topTris[ib]], verts[topTris[ic]]); Debug.DrawLine(verts[topTris[ic]], verts[topTris[ia]]); } mesh.AddData(verts, uvs, topTris, normals, tangents, submesh); }
private static void ToMesh(ref BuildRMesh mesh, Shape shape, bool[] gabled, float roofBaseHeight, float meshHeight, int submesh, Surface surface) { List <Edge> edges = new List <Edge>(shape.edges); List <Edge> baseEdges = new List <Edge>(shape.baseEdges); float shapeHeight = shape.HeighestPoint(); float designHeight = meshHeight; float heightScale = designHeight / shapeHeight; Dictionary <Node, int> shapeConnectionCount = new Dictionary <Node, int>(); Dictionary <Node, List <Node> > shapeConnections = new Dictionary <Node, List <Node> >(); int edgeCount = edges.Count; for (int e = 0; e < edgeCount; e++) { Edge edge = edges[e]; // Node nodeA = edge.nodeA; // Node nodeB = edge.nodeB; // Vector3 na = new Vector3(nodeA.position.x, roofBaseHeight * 1.5f, nodeA.position.y); // Vector3 nb = new Vector3(nodeB.position.x, roofBaseHeight * 1.5f, nodeB.position.y); // Debug.DrawLine(na, nb, Color.blue); if (edge.length < Mathf.Epsilon) { continue; } if (!shapeConnectionCount.ContainsKey(edge.nodeA)) { shapeConnectionCount.Add(edge.nodeA, 0);//start at zero - we need two edges to make a shape... shapeConnections.Add(edge.nodeA, new List <Node> { edge.nodeB }); } else { shapeConnectionCount[edge.nodeA]++; if (!shapeConnections[edge.nodeA].Contains(edge.nodeB)) { shapeConnections[edge.nodeA].Add(edge.nodeB); } } if (!shapeConnectionCount.ContainsKey(edge.nodeB)) { shapeConnectionCount.Add(edge.nodeB, 0);//start at zero - we need two edges to make a shape... shapeConnections.Add(edge.nodeB, new List <Node> { edge.nodeA }); } else { shapeConnectionCount[edge.nodeB]++; if (!shapeConnections[edge.nodeB].Contains(edge.nodeA)) { shapeConnections[edge.nodeB].Add(edge.nodeA); } } // Vector3 na = new Vector3(edge.nodeA.position.x + 75, roofBaseHeight * 2 + edge.nodeA.height, edge.nodeA.position.y); // Vector3 nb = new Vector3(edge.nodeB.position.x + 75, roofBaseHeight * 2 + edge.nodeB.height, edge.nodeB.position.y); // Debug.DrawLine(na, nb, new Color(1,0,1,0.24f)); // // GizmoLabel.Label(edge.nodeA.ToString(), na); // GizmoLabel.Label(edge.nodeB.ToString(), nb); } int baseEdgeCount = baseEdges.Count; for (int b = 0; b < baseEdgeCount; b++) { Edge baseEdge = baseEdges[b]; Node nodeA = baseEdge.nodeA; Node nodeB = baseEdge.nodeB; // Color col = new Color(Random.value, Random.value, Random.value, 0.5f); // Vector3 na = new Vector3(nodeA.position.x + 75, roofBaseHeight * 2, nodeA.position.y); // Vector3 nb = new Vector3(nodeB.position.x + 75, roofBaseHeight * 2, nodeB.position.y); // Debug.DrawLine(na, nb, col);//base edge Node currentNode = nodeA; Node lastNode = nodeB; int itMax = 50; List <Node> edgeShape = new List <Node>() { nodeA }; while (currentNode != nodeB) { List <Node> nodeConnections = shapeConnections[currentNode]; int nodeConnectionCount = nodeConnections.Count; float minAngle = Mathf.Infinity; Node nextNode = null; Vector2 currentDirection = (currentNode.position - lastNode.position).normalized; for (int n = 0; n < nodeConnectionCount; n++) { Node connectingNode = nodeConnections[n]; if (connectingNode == lastNode) { continue; } Vector2 nextDirection = (connectingNode.position - currentNode.position).normalized; float nodeAngle = JMath.SignAngleDirection(currentDirection, nextDirection); if (nodeAngle < minAngle) { minAngle = nodeAngle; nextNode = connectingNode; } } if (nextNode != null) { edgeShape.Add(nextNode); lastNode = currentNode; currentNode = nextNode; } itMax--; if (itMax < 0) { break; } // if(edgeShape.Count == 3) break; } int edgeShapeCount = edgeShape.Count; Vector3[] verts = new Vector3[edgeShapeCount]; Vector2[] uvs = new Vector2[edgeShapeCount]; Vector3 baseShapeDirection = Utils.ToV3(nodeB.position - nodeA.position).normalized; float uvAngle = JMath.SignAngle(new Vector2(baseShapeDirection.x, baseShapeDirection.z).normalized) - 90; Vector2[] faceShape = new Vector2[edgeShapeCount]; Vector3[] normals = new Vector3[edgeShapeCount]; Vector4[] tangents = new Vector4[edgeShapeCount]; // Vector3 normal = Vector3.up;//BuildRMesh.CalculateNormal(); TODO Vector4 tangent = BuildRMesh.CalculateTangent(baseShapeDirection); for (int i = 0; i < edgeShapeCount; i++) { float testHAdd = 0;//5 + b; Vector3 newVert = new Vector3(edgeShape[i].position.x, edgeShape[i].height * heightScale + roofBaseHeight + testHAdd, edgeShape[i].position.y); verts[i] = newVert; Vector2 baseUV = (i == 0) ? Vector2.zero : new Vector2(newVert.x - verts[0].x, newVert.z - verts[0].z); Vector2 newUV = JMath.Rotate(baseUV, uvAngle); float faceHeight = edgeShape[i].height * heightScale; newUV.y = Mathf.Sqrt((newUV.y * newUV.y) + (faceHeight * faceHeight)); if (surface != null) { newUV = surface.CalculateUV(newUV); } uvs[i] = newUV; faceShape[i] = edgeShape[i].position;//used for triangulation // normals[i] = normal; tangents[i] = tangent; } // int[] tris = EarClipper.Triangulate(faceShape, 0, -1); int[] tris = Poly2TriWrapper.Triangulate(faceShape); int triCount = tris.Length; Vector3 normal = BuildRMesh.CalculateNormal(verts[tris[0]], verts[tris[1]], verts[tris[2]]); // Vector3[] normCal = new Vector3[edgeShapeCount]; // for (int t = 0; t < triCount; t += 3) // { // int[] triIndicies = {tris[t], tris[t + 1], tris[t + 2]}; // Vector3 newNormal = BuildRMesh.CalculateNormal(verts[triIndicies[0]], verts[triIndicies[1]], verts[triIndicies[2]]); // for(int i = 0; i < 3; i++) // normCal[triIndicies[i]] = newNormal; // } for (int i = 0; i < edgeShapeCount; i++) { normals[i] = normal;//normCal[i].normalized; } mesh.AddData(verts, uvs, tris, normals, tangents, submesh); if (gabled[b]) { for (int t = 0; t < triCount; t += 3) { if (tris[t] == 0 || tris[t + 1] == 0 || tris[t + 2] == 0) { int beB = edgeShapeCount - 1; if (tris[t] == beB || tris[t + 1] == beB || tris[t + 2] == beB) { Vector3 b0 = verts[0]; Vector3 b1 = verts[beB]; int topIndex = 0; for (int tx = 0; tx < 3; tx++) { if (tris[t + tx] != 0 && tris[t + tx] != beB) { topIndex = tris[t + tx]; } } Vector3 b2 = verts[topIndex]; Vector3 baseV = b1 - b0; Vector3 dir = baseV.normalized; Vector3 face = Vector3.Cross(Vector3.up, dir); // float length = baseV.magnitude; Vector3 center = Vector3.Lerp(b0, b1, 0.5f); Vector3 up = Vector3.Project(b2 - b0, Vector3.up); Vector3 b3 = center + up; mesh.AddTri(b0, b2, b3, face, submesh); //left mesh.AddTri(b1, b3, b2, -face, submesh); //right mesh.AddTri(b0, b3, b1, dir, submesh); //face //clear triangle tris[t] = 0; tris[t + 1] = 0; tris[t + 2] = 0; } } } } // for (int i = 0; i < edgeShapeCount; i++) // { // Node nodeAS = edgeShape[i]; // Node nodeBS = edgeShape[(i + 1) % edgeShapeCount]; // Vector3 nas = new Vector3(nodeAS.position.x + 75, roofBaseHeight * 5 + b, nodeAS.position.y); // Vector3 nbs = new Vector3(nodeBS.position.x + 75, roofBaseHeight * 5 + b, nodeBS.position.y); // Debug.DrawLine(nas, nbs + Vector3.up, col);//Color.yellow); // } } //Assumption - each based edge is a single shape //There are no shapes without a base edge //Enumerate through the base edges //Build the shape //use angle to find shape clockwise or something //triangulate the shape and add to mesh //node data will provide height information //??? //profit // int itMax = 5000; // while(unmappedNodes.Count > 0) // { // Node currentNode = unmappedNodes[0]; // unmappedNodes.RemoveAt(0); // // // itMax--; // if(itMax < 0) // return; // } }