Beispiel #1
0
        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;
            }
        }
Beispiel #2
0
		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;
			}
		}
Beispiel #3
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);
		}
Beispiel #4
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);
        }