private float GetLinearTimeOnCurve(float posOnCurve) { // this is necessary because the points on the curve are not evenly sampled, if they were we could just use dist / curveLength var linearTime = 0f; var points = Curve.GetCurvePoints(); var step = 1f / (points.Length - 1); for (var i = 0; i < points.Length - 1; i++) { var point = points[i]; if (posOnCurve > point.DistanceOnCurve) { var interpolation = Mathf.InverseLerp(point.DistanceOnCurve, points[i + 1].DistanceOnCurve, posOnCurve); linearTime = Mathf.Lerp(step * i, step * (i + 1), interpolation); } } return(linearTime); }
protected Mesh GetCurvedMesh() { var positionsOnCurve = _curve.GetCurvePoints(); const int wallResolution = 10; const float radius = 0.1f; //calculate how many vertices we need var numVertexColumns = wallResolution + 1; //+1 for welding var numVertexRows = positionsOnCurve.Length; //calculate sizes var numVertices = numVertexColumns * numVertexRows; var numUVs = numVertices; //always var numSideTris = wallResolution * _curve.Resolution * _curve.ControlPoints.Length * 2; //for one cap var trisArrayLength = numSideTris * 3; //3 places in the array for each tri //initialize arrays var vertices = new Vector3[numVertices]; var uvs = new Vector2[numUVs]; var tris = new int[trisArrayLength]; //precalculate increments to improve performance var angleStep = 2 * Mathf.PI / wallResolution; var uvStepH = 1.0f / wallResolution; var uvStepV = 1.0f / _curve.Resolution; for (var j = 0; j < positionsOnCurve.Length; j++) { var curvePos = positionsOnCurve[j]; for (var i = 0; i < numVertexColumns; i++) { //calculate angle for that vertex on the unit circle var angle = i * angleStep; //"fold" the sheet around as a cylinder by placing the first and last vertex of each row at the same spot if (i == numVertexColumns - 1) { angle = 0; } //position current vertex var verticalVertPos = new Vector3(radius * Mathf.Cos(angle), 0, radius * Mathf.Sin(angle)); vertices[j * numVertexColumns + i] = Quaternion.LookRotation(curvePos.Normal, curvePos.Tangent) * verticalVertPos + curvePos.Position; //calculate UVs uvs[j * numVertexColumns + i] = new Vector2(i * uvStepH, j * uvStepV); //create the tris if (j == 0 || i >= numVertexColumns - 1) { //nothing to do on the first and last "floor" on the tris, capping is done below //also nothing to do on the last column of vertices continue; } //create 2 tris below each vertex //6 seems like a magic number. For every vertex we draw 2 tris in this for-loop, therefore we need 2*3=6 indices in the Tris array //offset the base by the number of slots we need for the bottom cap tris. Those will be populated once we draw the cap int baseIndex = (j - 1) * wallResolution * 6 + i * 6; //1st tri - below and in front tris[baseIndex + 0] = j * numVertexColumns + i; tris[baseIndex + 1] = j * numVertexColumns + i + 1; tris[baseIndex + 2] = (j - 1) * numVertexColumns + i; //2nd tri - the one it doesn't touch tris[baseIndex + 3] = (j - 1) * numVertexColumns + i; tris[baseIndex + 4] = j * numVertexColumns + i + 1; tris[baseIndex + 5] = (j - 1) * numVertexColumns + i + 1; } } //assign vertices, uvs and tris var curvedMesh = new Mesh { name = "Curved Mesh", vertices = vertices, uv = uvs }; //System.Array.Reverse(tris); // flip normals curvedMesh.triangles = tris; curvedMesh.RecalculateNormals(); curvedMesh.RecalculateBounds(); CalculateMeshTangents(curvedMesh); curvedMesh.Optimize(); return(curvedMesh); }