void OnDrawGizmos() { Matrix4x4 toWorld = transform.localToWorldMatrix; Gizmos.color = GizmoColor; List <Vector3> transformedPoses = Curve.Points.Select(v => toWorld.MultiplyPoint(v)).ToList(); Curve curve = new Curve(transformedPoses); //Draw the control points. for (int i = 0; i < curve.Points.Count; ++i) { Gizmos.DrawSphere(curve.Points[i], GizmoSphereRadius); if (i > 0) { Gizmos.color = new Color(GizmoColor.r, GizmoColor.g, GizmoColor.b, GizmoColor.a * 0.25f); Gizmos.DrawLine(curve.Points[i - 1], curve.Points[i]); Gizmos.color = GizmoColor; } } if (!DrawCurveGizmo) { return; } //Draw the curve. Vector3[] precalcValues = curve.PreCalculateValues(); Vector3 prev = curve.Points[0]; float increment = 1.0f / (float)GizmoCurveSegments; for (int i = 0; i < GizmoCurveSegments; ++i) { float t = increment * (float)(i + 1); var valAndDer = curve.GetValueAndDerivative(t, precalcValues); Gizmos.DrawLine(prev, valAndDer.Value); Vector3 midpoint = (prev + valAndDer.Value) / 2.0f; Gizmos.DrawLine(midpoint, midpoint + (valAndDer.Perpendicular * GizmoLinePerpScale)); Gizmos.DrawLine(midpoint, midpoint + (valAndDer.Derivative * GizmoLinePerpScale)); prev = valAndDer.Value; } }
void OnDrawGizmos() { Matrix4x4 toWorld = transform.localToWorldMatrix; Gizmos.color = GizmoColor; List<Vector3> transformedPoses = Curve.Points.Select(v => toWorld.MultiplyPoint(v)).ToList(); Curve curve = new Curve(transformedPoses); //Draw the control points. for (int i = 0; i < curve.Points.Count; ++i) { Gizmos.DrawSphere(curve.Points[i], GizmoSphereRadius); if (i > 0) { Gizmos.color = new Color(GizmoColor.r, GizmoColor.g, GizmoColor.b, GizmoColor.a * 0.25f); Gizmos.DrawLine(curve.Points[i - 1], curve.Points[i]); Gizmos.color = GizmoColor; } } if (!DrawCurveGizmo) return; //Draw the curve. Vector3[] precalcValues = curve.PreCalculateValues(); Vector3 prev = curve.Points[0]; float increment = 1.0f / (float)GizmoCurveSegments; for (int i = 0; i < GizmoCurveSegments; ++i) { float t = increment * (float)(i + 1); var valAndDer = curve.GetValueAndDerivative(t, precalcValues); Gizmos.DrawLine(prev, valAndDer.Value); Vector3 midpoint = (prev + valAndDer.Value) / 2.0f; Gizmos.DrawLine(midpoint, midpoint + (valAndDer.Perpendicular * GizmoLinePerpScale)); Gizmos.DrawLine(midpoint, midpoint + (valAndDer.Derivative * GizmoLinePerpScale)); prev = valAndDer.Value; } }
public static void GenerateMesh(Mesh m, Curve c, float radiusScale, AnimationCurve radiusAlongCurve, AnimationCurve radiusAroundCurve, AnimationCurve radiusVariance, int seed, int divisionsAlong = 20, int divisionsAround = 5) { Rand.seed = seed; Vector3[] cV = c.PreCalculateValues(); //First generate the positions/UV's along the curve. Vector3[] meshPoses = new Vector3[(divisionsAlong * divisionsAround) + 2]; Vector2[] meshUVs = new Vector2[(divisionsAlong * divisionsAround) + 2]; //Add a vertex at the beginning and end of the curve. meshPoses[meshPoses.Length - 2] = c.GetValue(0.0f, cV); meshPoses[meshPoses.Length - 1] = c.GetValue(1.0f, cV); meshUVs[meshUVs.Length - 2] = new Vector2(0.5f, 1.0f); meshUVs[meshUVs.Length - 1] = new Vector2(0.5f, 0.0f); //At each division along the curve, generate a ring of vertices. float rotateIncrement = 360.0f / divisionsAround; float moveIncrement = 1.0f / (float)(divisionsAlong - 1); for (int i = 0; i < divisionsAlong; ++i) { float t = moveIncrement * (float)i; var valAndDerivative = c.GetValueAndDerivative(t, cV); valAndDerivative.Derivative.Normalize(); Vector3 perp = valAndDerivative.Perpendicular.normalized; Quaternion rot = Quaternion.AngleAxis(rotateIncrement, valAndDerivative.Derivative); float variance = radiusVariance.Evaluate(t), radiusBase = radiusAlongCurve.Evaluate(t); for (int j = 0; j < divisionsAround; ++j) { float jLerp = (float)j / (float)(divisionsAround - 1); float radius = radiusAroundCurve.Evaluate(jLerp) * radiusScale * (radiusBase + Rand.Range(-variance, variance)); int index = j + (i * divisionsAround); meshPoses[index] = valAndDerivative.Value + (perp * radius); meshUVs[index] = new Vector2((float)j / (float)(divisionsAround + 1), (float)i / (float)divisionsAlong); perp = rot * perp; } } //Next, generate indices. int indicesPerRing = divisionsAround * 2 * 3, indicesPerCap = divisionsAround * 3; int[] meshTris = new int[(indicesPerRing * (divisionsAlong - 1)) + (indicesPerCap * 2)]; //Generate indices along the curve. int triIndex = 0; for (int i = 1; i < divisionsAlong; ++i) { int prevStartVertex = (i - 1) * divisionsAround, startVertex = i * divisionsAround; for (int j = 0; j < divisionsAround; ++j) { int nextJ = (j + 1) % divisionsAround; meshTris[triIndex] = prevStartVertex + j; meshTris[triIndex + 1] = startVertex + nextJ; meshTris[triIndex + 2] = startVertex + j; meshTris[triIndex + 3] = prevStartVertex + j; meshTris[triIndex + 4] = prevStartVertex + nextJ; meshTris[triIndex + 5] = startVertex + nextJ; triIndex += 6; } } //Generate indices for the end caps of the curve. int topStartVert = (divisionsAlong - 1) * divisionsAround; for (int i = 0; i < divisionsAround; ++i) { int nextI = (i + 1) % divisionsAround; meshTris[triIndex] = nextI; meshTris[triIndex + 1] = i; meshTris[triIndex + 2] = meshPoses.Length - 2; meshTris[triIndex + indicesPerCap] = topStartVert + i; meshTris[triIndex + indicesPerCap + 1] = topStartVert + nextI; meshTris[triIndex + indicesPerCap + 2] = meshPoses.Length - 1; triIndex += 3; } //Finally, generate and return the mesh object. m.Clear(); m.vertices = meshPoses; m.uv = meshUVs; m.triangles = meshTris; m.RecalculateBounds(); m.RecalculateNormals(); CalculateMeshTangents(m); m.UploadMeshData(true); }