예제 #1
0
파일: TreeCurve.cs 프로젝트: heyx3/TreeGen
		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;
			}
		}
예제 #2
0
		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);
		}