public void Run(HairAsset asset) { asset.GetRawDataCopy(out float3[] originalVertices, out HairStrand[] originalStrands, out uint[] originalMovability); List <float3> newVertices = new List <float3>(); List <HairStrand> newStrands = new List <HairStrand>(); BitArray movability = new BitArray(originalVertices.Length * (newHairPerHair + 1)); for (int i = 0; i < originalMovability.Length; i++) { for (int j = 0; j < 32; j++) { movability[(i * 32) + j] = HairMovability.IsMovable((i * 32) + j, originalMovability); } } for (int i = 0; i < originalStrands.Length; i++) { float rLeft = UnityEngine.Random.value * maxOffsetRadius, rUp = UnityEngine.Random.value * maxOffsetRadius; var origStrand = originalStrands[i]; if (origStrand.lastVertex - origStrand.firstVertex < 2) { continue; } for (int j = 0; j < newHairPerHair; j++) { int firstVertex = newVertices.Count + originalVertices.Length; for (int k = origStrand.firstVertex; k <= origStrand.lastVertex; k++) { Quaternion orientation = k == origStrand.lastVertex ? Quaternion.LookRotation(originalVertices[k] - originalVertices[k - 1]) : Quaternion.LookRotation(originalVertices[k + 1] - originalVertices[k]); Vector3 left = orientation * Vector3.left; Vector3 up = orientation * Vector3.up; float3 offset = (rLeft * left) + (rUp * up); movability[originalVertices.Length + newVertices.Count] = movability[k]; newVertices.Add(originalVertices[k] + offset); } newStrands.Add(new HairStrand() { firstVertex = firstVertex, lastVertex = newVertices.Count + originalVertices.Length - 1 }); } } uint[] _movability = new uint[Mathf.CeilToInt(movability.Length / 32f)]; for (int i = 0; i < movability.Length; i++) { HairMovability.SetMovable(i, movability[i], _movability); } asset.InitializeVertices(originalVertices.Concat(newVertices).ToArray()); asset.InitializeMovability(_movability); asset.InitializeStrands(originalStrands.Concat(newStrands).ToArray()); }
public void Run(HairAsset asset) { uint[] movability = HairMovability.CreateData(asset.vertexCount); HairStrand[] strands = asset.GetStrandData(); for (int i = 0; i < strands.Length; i++) { HairStrand strand = strands[i]; HairMovability.SetMovable(strand.firstVertex, false, movability); int cnt = (strand.lastVertex - strand.firstVertex) + 1; for (int j = 1; j < cnt; j++) { HairMovability.SetMovable(strand.firstVertex + j, true, movability); } } asset.InitializeMovability(movability); }
public void Run(HairAsset asset) { List <bool> movability = new List <bool>(); List <float3> vertices = new List <float3>(); List <HairStrand> strands = new List <HairStrand>(); foreach (var mf in targetObject.GetComponentsInChildren <MeshFilter>()) { var t = mf.transform; var mesh = mf.sharedMesh; if (mesh == null) { continue; } var meshTriangles = mesh.triangles; var meshVertices = mesh.vertices; var meshNormals = mesh.normals; for (int i = 0; i < meshTriangles.Length; i += 3) { int i1 = meshTriangles[i], i2 = meshTriangles[i + 1], i3 = meshTriangles[i + 2]; Vector3 p1 = meshVertices[i1], p2 = meshVertices[i2], p3 = meshVertices[i3]; Vector3 n1 = t.TransformDirection(meshNormals[i1]), n2 = t.TransformDirection(meshNormals[i2]), n3 = t.TransformDirection(meshNormals[i3]); var faceNormal = (n1 + n2 + n3) / 3f; if (Vector3.Dot(faceNormal, growingDirection) >= growingDirMinAngle) { float triangleSurfaceArea = Vector3.Cross(p2 - p1, p3 - p1).magnitude; int stalks = Mathf.FloorToInt(triangleSurfaceArea * stalksPerSquareUnit); for (int k = 0; k < stalks; k++) { float r1 = UnityEngine.Random.value, r2 = UnityEngine.Random.value; var p = (1f - Mathf.Sqrt(r1)) * p1 + (Mathf.Sqrt(r1) * (1f - r2)) * p2 + (r2 * Mathf.Sqrt(r1)) * p3; int startIdx = vertices.Count; movability.Add(false); vertices.Add(p); float height = UnityEngine.Random.Range(heightMin, heightMax); float heightPerVertex = height / (verticesPerStalk - 1); for (int j = 1; j < verticesPerStalk; j++) { movability.Add(true); vertices.Add(p + (faceNormal * (heightPerVertex * (float)j))); } strands.Add(new HairStrand() { firstVertex = startIdx, lastVertex = vertices.Count - 1 }); } } } } asset.InitializeStrands(strands.ToArray()); asset.InitializeVertices(vertices.ToArray()); uint[] u_movability = new uint[Mathf.CeilToInt(movability.Count / 32f)]; for (int i = 0; i < movability.Count; i++) { HairMovability.SetMovable(i, movability[i], u_movability); } asset.InitializeMovability(u_movability); }