public Mesh BuildMesh(float length, float radiusA, float radiusB, float roundnessA, float roundnessB, float angleA, float angleB, int heightSegments, int radialSegments) { MeshBuilder meshBuilder = new MeshBuilder(); // Test proportions here and log any debug or error messages if (length < radiusA || length < radiusB) { Debug.LogWarning("Warning: Bad body segment proportions. Length should be greater than minimum radius."); } // Determine cap segments based on height segments and relative lengths int capSegments = (int)Mathf.RoundToInt(((radiusA + radiusB) / (2 * length)) * heightSegments); // Define all curve points as 3D Vectors with 0 in z direction Vector3 A = new Vector3(0.0f, -roundnessA * radiusA, 0.0f); Vector3 B = new Vector3(radiusA, 0.0f, 0.0f); Vector3 C = new Vector3(radiusB, length, 0.0f); Vector3 D = new Vector3(0.0f, length + roundnessB * radiusB, 0.0f); // Distances between vectors float d1 = Vector3.Distance(A, B); float d2 = Vector3.Distance(B, C); float d3 = Vector3.Distance(C, D); Vector3 midAB1 = A + new Vector3(d1 / 3.0f, 0.0f, 0.0f); Vector3 midAB2 = B + new Vector3((d1 / 3.0f) * Mathf.Cos(Mathf.Deg2Rad * (angleA - 90)), (d1 / 3.0f) * Mathf.Sin(Mathf.Deg2Rad * (angleA - 90)), 0.0f); Vector3 midBC1 = B + new Vector3((d2 / 3.0f) * Mathf.Cos(Mathf.Deg2Rad * (angleA + 90)), (d2 / 3.0f) * Mathf.Sin(Mathf.Deg2Rad * (angleA + 90)), 0.0f); Vector3 midBC2 = C + new Vector3((d2 / 3.0f) * Mathf.Cos(Mathf.Deg2Rad * (angleB - 90)), (d2 / 3.0f) * Mathf.Sin(Mathf.Deg2Rad * (angleB - 90)), 0.0f); Vector3 midCD1 = C + new Vector3((d3 / 3.0f) * Mathf.Cos(Mathf.Deg2Rad * (angleB + 90)), (d3 / 3.0f) * Mathf.Sin(Mathf.Deg2Rad * (angleB + 90)), 0.0f); Vector3 midCD2 = D + new Vector3(d3 / 3.0f, 0.0f, 0.0f); // Define the 3 bezier curves to use Bezier3D capCurveA = new Bezier3D(A, midAB1, midAB2, B); Bezier3D mainCurve = new Bezier3D(B, midBC1, midBC2, C); Bezier3D capCurveB = new Bezier3D(C, midCD1, midCD2, D); // Loop along curve to define geometry for (int t = 0; t <= capSegments; t++) { Vector3 radiusVec = capCurveA.Point((float)t / (float)capSegments); float v = (float)t / (float)capSegments; BuildRing(meshBuilder, new Vector3(0.0f, radiusVec.y, 0.0f), radiusVec.x, radialSegments, v, t != 0); } for (int t = 1; t <= heightSegments; t++) { Vector3 radiusVec = mainCurve.Point((float)t / (float)heightSegments); float v = (float)t / (float)heightSegments; BuildRing(meshBuilder, new Vector3(0.0f, radiusVec.y, 0.0f), radiusVec.x, radialSegments, v, true); } for (int t = 1; t <= capSegments; t++) { Vector3 radiusVec = capCurveB.Point((float)t / (float)capSegments); float v = (float)t / (float)heightSegments; BuildRing(meshBuilder, new Vector3(0.0f, radiusVec.y, 0.0f), radiusVec.x, radialSegments, v, true); } return(meshBuilder.CreateMesh()); }
// Update is called once per frame void Update() { m_builder = new MeshBuilder(); List <BranchPoint> branchList = new List <BranchPoint>(); branchList.Add(new BranchPoint()); float branchLength = m_branchLength; // For as many branches are wanted for (int b = 0; b < m_branchNum; b++) { // For each branch... List <BranchPoint> newBranchList = new List <BranchPoint>(); foreach (BranchPoint branch in branchList) { // Build branches Vector3 finalPosition = Vector3.zero; Quaternion finalRotation = Quaternion.identity; for (int n = 0; n < 2; n++) { for (int i = 0; i < 8; i++) { Vector3 branchStart = branch.point; Quaternion branchRotation = Quaternion.FromToRotation(Vector3.up, branch.rotation * Quaternion.AngleAxis((2 * n - 1) * 45.0f + m_branchRotation, Vector3.forward) * Vector3.up); Vector3 branchEnd = branchStart + branchRotation * Vector3.up * branchLength; Vector3 branchMid1 = (branchEnd - branchStart) * 0.33f; Vector3 branchMid2 = (branchEnd - branchStart) * 0.67f; Bezier3D branchCurve = new Bezier3D(branchStart, branchMid1, branchMid2, branchEnd); float t = i / (8.0f - 1.0f); Vector3 ringPosition = branchCurve.Point(t); Quaternion rotation = Quaternion.FromToRotation(Vector3.up, branchCurve.Tangent(t)); BuildRing(m_builder, 8, ringPosition, m_startWidth, t, i != 0, rotation, Vector3.zero); finalPosition = ringPosition; finalRotation = rotation; } newBranchList.Add(new BranchPoint(finalPosition, finalRotation)); } } branchList.Clear(); branchList = newBranchList; branchLength *= m_branchLengthFalloff; } Mesh newMesh = m_builder.CreateMesh(); newMesh.RecalculateNormals(); MeshFilter filter = GetComponent <MeshFilter>(); filter.sharedMesh = newMesh; }
public Mesh BuildMesh(float length, float upper_width, float lower_width, int heightSegments, int radialSegments) { MeshBuilder meshBuilder = new MeshBuilder(); // Define bezier curve Vector3 start = Vector3.zero; Vector3 end = Vector3.up * length; Vector3 mid1 = start + Vector3.right * lower_width; Vector3 mid2 = end + Vector3.right * upper_width; for (int t = 0; t <= heightSegments; t++) { Bezier3D curve = new Bezier3D(start, mid1, mid2, end); Vector3 radiusVec = curve.Point((float)(t) / (float)heightSegments); //Vector3 radiusVec = Bezier(start,mid1,mid2,end,(float)(t)/(float)heightSegments); //if(radiusVec.x > maxRadius) {maxRadius = radiusVec.x;} //Debug.Log("radiusVec = " + radiusVec); float v = (float)t / (float)heightSegments; BuildRing(meshBuilder, /*offset+*/ new Vector3(0.0f, radiusVec.y, 0.0f), radiusVec.x, radialSegments, v, t != 0); } /* * start = end; * end = Vector3.up*height; * mid1 = start+Vector3.up*Random.Range(0.05f,0.5f)*height; * mid2 = end + Vector3.right*Random.Range(radiusGuide*0.25f,radiusGuide)+Vector3.up*Random.Range(-0.25f,0.25f)*height; * * for(int t = 1; t <= heightSegments/2; t++) { * Vector3 radiusVec = Bezier(start,mid1,mid2,end,(float)(t*2)/(float)heightSegments); * if(radiusVec.x > maxRadius) {maxRadius = radiusVec.x;} * //Debug.Log("radiusVec = " + radiusVec); * float v = (float)t/(float)heightSegments+0.5f; * BuildRing(meshBuilder,offset+new Vector3(0.0f,radiusVec.y,0.0f),radiusVec.x,radialSegments,v,true); * } */ return(meshBuilder.CreateMesh()); }