public static Vector3[] GetIDsAndWeights(int seed, float[] triAreas, int[] triangles, Vector3[] vertices) { float randomVal = getRandomFloatFromSeed(seed * 20); int tri0 = 3 * getTri(randomVal, triAreas); int tri1 = tri0 + 1; int tri2 = tri0 + 2; tri0 = triangles[tri0]; tri1 = triangles[tri1]; tri2 = triangles[tri2]; Vector3 pos = GetRandomPointInTriangle(seed, vertices[tri0], vertices[tri1], vertices[tri2]); float a0 = HelperFunctions.AreaOfTriangle(pos, vertices[tri1], vertices[tri2]); float a1 = HelperFunctions.AreaOfTriangle(pos, vertices[tri0], vertices[tri2]); float a2 = HelperFunctions.AreaOfTriangle(pos, vertices[tri0], vertices[tri1]); float aTotal = a0 + a1 + a2; float p0 = a0 / aTotal; float p1 = a1 / aTotal; float p2 = a2 / aTotal; return(new [] { new Vector3(tri0, tri1, tri2), new Vector3(p0, p1, p2) }); }
public static float[] GetTriAreas(int[] triangles, Vector3[] vertices) { float[] triAreas = new float[triangles.Length / 3]; float totalArea = 0; for (int i = 0; i < triangles.Length / 3; i++) { int tri0 = i * 3; int tri1 = tri0 + 1; int tri2 = tri0 + 2; tri0 = triangles[tri0]; tri1 = triangles[tri1]; tri2 = triangles[tri2]; float area = HelperFunctions.AreaOfTriangle(vertices[tri0], vertices[tri1], vertices[tri2]); triAreas[i] = area; totalArea += area; } for (int i = 0; i < triAreas.Length; i++) { triAreas[i] /= totalArea; } return(triAreas); }
public static Point getVertInfo(int seed, float randomVal, float[] triAreas, int[] triValues, VertBuffer vertBuffer) { int tri0 = 3 * HelperFunctions.getTri(randomVal, triAreas); int tri1 = tri0 + 1; int tri2 = tri0 + 2; tri0 = triValues[tri0]; tri1 = triValues[tri1]; tri2 = triValues[tri2]; Vector3 pos = HelperFunctions.GetRandomPointInTriangle(seed, vertBuffer.vertices[tri0], vertBuffer.vertices[tri1], vertBuffer.vertices[tri2]); float a0 = HelperFunctions.AreaOfTriangle(pos, vertBuffer.vertices[tri1], vertBuffer.vertices[tri2]); float a1 = HelperFunctions.AreaOfTriangle(pos, vertBuffer.vertices[tri0], vertBuffer.vertices[tri2]); float a2 = HelperFunctions.AreaOfTriangle(pos, vertBuffer.vertices[tri0], vertBuffer.vertices[tri1]); float aTotal = a0 + a1 + a2; float p0 = a0 / aTotal; float p1 = a1 / aTotal; float p2 = a2 / aTotal; Vector3 nor = vertBuffer.normals[tri0] * p0 + vertBuffer.normals[tri1] * p1 + vertBuffer.normals[tri2] * p2; nor = nor.normalized; // Vector3 color = tri0.color * p0 + tri1.color * p1 + tri2.color * p2; Vector2 uv = vertBuffer.uvs[tri0] * p0 + vertBuffer.uvs[tri1] * p1 + vertBuffer.uvs[tri2] * p2; Point p = new Point(); p.uv = uv; p.nor = nor; p.triWeights = new Vector3(p0, p1, p2); p.triIDs = new Vector3(tri0, tri1, tri2); return(p); }
void CreateBuffers() { _buffer = new ComputeBuffer(fullVertCount, vertStructSize * sizeof(float)); values = new float[fullVertCount * vertStructSize]; // Used for assigning to our buffer; int index = 0; triAreas = new float[triBuffer.values.Length / 3]; float totalArea = 0; for (int i = 0; i < triBuffer.values.Length / 3; i++) { int tri0 = i * 3; int tri1 = tri0 + 1; int tri2 = tri0 + 2; tri0 = triBuffer.values[tri0]; tri1 = triBuffer.values[tri1]; tri2 = triBuffer.values[tri2]; float area = HelperFunctions.AreaOfTriangle(vertBuffer.vertices[tri0], vertBuffer.vertices[tri1], vertBuffer.vertices[tri2]); triAreas[i] = area; totalArea += area; } for (int i = 0; i < triAreas.Length; i++) { triAreas[i] /= totalArea; } for (int i = 0; i < fullVertCount; i++) { int id = i; //print( index); //print( inValues.Length ); int idInHair = id % numVertsPerHair; int hairID = (int)Mathf.Floor((float)id / (float)numVertsPerHair); // Resets using same hairID, so RandomPointInTriangle shoudl work float randomVal = HelperFunctions.getRandomFloatFromSeed(hairID * 20); int tri0 = 3 * HelperFunctions.getTri(randomVal, triAreas); int tri1 = tri0 + 1; int tri2 = tri0 + 2; tri0 = triBuffer.values[tri0]; tri1 = triBuffer.values[tri1]; tri2 = triBuffer.values[tri2]; Vector3 pos = HelperFunctions.GetRandomPointInTriangle(hairID, vertBuffer.vertices[tri0], vertBuffer.vertices[tri1], vertBuffer.vertices[tri2]); float a0 = HelperFunctions.AreaOfTriangle(pos, vertBuffer.vertices[tri1], vertBuffer.vertices[tri2]); float a1 = HelperFunctions.AreaOfTriangle(pos, vertBuffer.vertices[tri0], vertBuffer.vertices[tri2]); float a2 = HelperFunctions.AreaOfTriangle(pos, vertBuffer.vertices[tri0], vertBuffer.vertices[tri1]); float aTotal = a0 + a1 + a2; float p0 = a0 / aTotal; float p1 = a1 / aTotal; float p2 = a2 / aTotal; Vector3 nor = vertBuffer.normals[tri0] * p0 + vertBuffer.normals[tri1] * p1 + vertBuffer.normals[tri2] * p2; nor = nor.normalized; // Vector3 tan = vertBuffer.tangents[tri0] * p0 + vertBuffer.tangents[tri1] * p1 + vertBuffer.tangents[tri2] * p2; /// tan = tan.normalized; /*float3 tang = tri0.tang * p0 + tri1.tang * p1 + tri2.tang * p2; * float3 color = tri0.color * p0 + tri1.color * p1 + tri2.color * p2; * float2 uv = tri0.uv * p0 + tri1.uv * p1 + tri2.uv * p2;*/ float idVal = (float)id / (float)fullVertCount; float uvX = (float)idInHair / (float)numVertsPerHair; float uvY = (float)hairID / (float)totalHairs; int xID = hairID % 180; int zID = (int)Mathf.Floor((float)hairID / (float)180); float xPos = (float)xID / 180; float zPos = (float)zID / 180; Vector3 fPos = pos + nor * hairLength * uvX; // pos values[index++] = fPos.x; values[index++] = fPos.y; values[index++] = fPos.z; // oPos values[index++] = fPos.x; values[index++] = fPos.y; values[index++] = fPos.z; //vel values[index++] = 0; values[index++] = 0; values[index++] = 0; // nor values[index++] = nor.x; values[index++] = nor.y; values[index++] = nor.z; // uv values[index++] = uvX; values[index++] = uvY; // debug values[index++] = 1; values[index++] = 1; values[index++] = 1; // triIDs values[index++] = tri0; values[index++] = tri1; values[index++] = tri2; // triWeights values[index++] = p0; values[index++] = p1; values[index++] = p2; } _buffer.SetData(values); }
void CreateBuffers() { _buffer = new ComputeBuffer(numberMeshes, BasisStructSize * sizeof(float)); values = new float[numberMeshes * BasisStructSize]; triAreas = new float[triBuffer.triangles.Length / 3]; // Used for assigning to our buffer; int index = 0; // print( numberMeshes ); // print( values.Length ); float totalArea = 0; for (int i = 0; i < triBuffer.triangles.Length / 3; i++) { int tri0 = i * 3; int tri1 = tri0 + 1; int tri2 = tri0 + 2; tri0 = triBuffer.triangles[tri0]; tri1 = triBuffer.triangles[tri1]; tri2 = triBuffer.triangles[tri2]; float area = HelperFunctions.AreaOfTriangle(vertBuffer.vertices[tri0], vertBuffer.vertices[tri1], vertBuffer.vertices[tri2]); triAreas[i] = area; totalArea += area; } for (int i = 0; i < triAreas.Length; i++) { triAreas[i] /= totalArea; } for (int i = 0; i < numberMeshes; i++) { int id = i; float randomVal = Random.value; int tri0 = 3 * HelperFunctions.getTri(randomVal, triAreas); int tri1 = tri0 + 1; int tri2 = tri0 + 2; tri0 = triBuffer.triangles[tri0]; tri1 = triBuffer.triangles[tri1]; tri2 = triBuffer.triangles[tri2]; Vector3 pos = HelperFunctions.GetRandomPointInTriangle(id, vertBuffer.vertices[tri0], vertBuffer.vertices[tri1], vertBuffer.vertices[tri2]); float a0 = HelperFunctions.AreaOfTriangle(pos, vertBuffer.vertices[tri1], vertBuffer.vertices[tri2]); float a1 = HelperFunctions.AreaOfTriangle(pos, vertBuffer.vertices[tri0], vertBuffer.vertices[tri2]); float a2 = HelperFunctions.AreaOfTriangle(pos, vertBuffer.vertices[tri0], vertBuffer.vertices[tri1]); float aTotal = a0 + a1 + a2; float p0 = a0 / aTotal; float p1 = a1 / aTotal; float p2 = a2 / aTotal; Vector3 nor = vertBuffer.normals[tri0] * p0 + vertBuffer.normals[tri1] * p1 + vertBuffer.normals[tri2] * p2; nor = nor.normalized; // Vector3 color = tri0.color * p0 + tri1.color * p1 + tri2.color * p2; Vector2 uv = vertBuffer.uvs[tri0] * p0 + vertBuffer.uvs[tri1] * p1 + vertBuffer.uvs[tri2] * p2; Vector3 left = Vector3.Cross(nor, Vector3.up); left.Normalize(); Vector3 forward = Vector3.Cross(left, nor); // print( id ); values[index++] = id; //transform for (int j = 0; j < 16; j++) { values[index++] = 0; } // uv values[index++] = uv.x; values[index++] = uv.y; // triIDs values[index++] = tri0; values[index++] = tri1; values[index++] = tri2; // triWeights values[index++] = p0; values[index++] = p1; values[index++] = p2; // debug values[index++] = 1; values[index++] = 0; values[index++] = 0; } _buffer.SetData(values); }
// Use this for initialization void Start() { physicsKernel = physics.FindKernel("CSMain"); skinningKernel = skinning.FindKernel("CSMain"); skinningKernel = skinning.FindKernel("CSMain"); transformKernel = transform.FindKernel("CSMain"); physicsKernel = physics.FindKernel("CSMain"); constraintKernel = constraint.FindKernel("CSMain"); numberOfBonesPerLimb = boneBuffer.boneCount; numberOfPointsPerLimb = numberOfBonesPerLimb + 1; print(vertBuffer.vertCount); totalNumberBones = numberOfBonesPerLimb * numberOfLimbs; totalNumberVerts = vertBuffer.vertCount * numberOfLimbs; totalNumberPoints = (numberOfPointsPerLimb) * numberOfLimbs; print(totalNumberVerts); print(totalNumberBones); fullPointBuffer = new ComputeBuffer(totalNumberPoints, pointStructSize * sizeof(float)); fullBoneBuffer = new ComputeBuffer(totalNumberBones, boneStructSize * sizeof(float)); fullVertBuffer = new ComputeBuffer(totalNumberVerts, vertBuffer.structSize * sizeof(float)); boneValues = new float[totalNumberBones * boneStructSize]; vertValues = new float[totalNumberVerts * vertBuffer.structSize]; pointValues = new float[totalNumberPoints * pointStructSize]; int index = 0; Vector3 basePosition; Vector3 fPos; for (int i = 0; i < numberOfLimbs; i++) { // Resets using same hairID, so RandomPointInTriangle shoudl work float randomVal = HelperFunctions.getRandomFloatFromSeed(i * 20); int tri0 = (int)(randomVal * (float)(baseTriBuffer.triangles.Length / 3)) * 3; //int tri0 = (int)(randomVal * 1000 + 1000 ) * 3; int tri1 = tri0 + 1; int tri2 = tri0 + 2; tri0 = baseTriBuffer.triangles[tri0]; tri1 = baseTriBuffer.triangles[tri1]; tri2 = baseTriBuffer.triangles[tri2]; Vector3 pos = HelperFunctions.GetRandomPointInTriangle(i, baseVertBuffer.vertices[tri0], baseVertBuffer.vertices[tri1], baseVertBuffer.vertices[tri2]); float a0 = HelperFunctions.AreaOfTriangle(pos, baseVertBuffer.vertices[tri1], baseVertBuffer.vertices[tri2]); float a1 = HelperFunctions.AreaOfTriangle(pos, baseVertBuffer.vertices[tri0], baseVertBuffer.vertices[tri2]); float a2 = HelperFunctions.AreaOfTriangle(pos, baseVertBuffer.vertices[tri0], baseVertBuffer.vertices[tri1]); float aTotal = a0 + a1 + a2; float p0 = a0 / aTotal; float p1 = a1 / aTotal; float p2 = a2 / aTotal; Vector3 nor = baseVertBuffer.normals[tri0] * p0 + baseVertBuffer.normals[tri1] * p1 + baseVertBuffer.normals[tri2] * p2; nor = nor.normalized; basePosition = baseTransform.TransformPoint(pos);//new Vector3( i * .1f, 0 , 0); for (int j = 0; j < numberOfBonesPerLimb; j++) { fPos = boneBuffer.bones[j].transform.position + basePosition; pointValues[index++] = 1; pointValues[index++] = fPos.x; pointValues[index++] = fPos.y; pointValues[index++] = fPos.z; pointValues[index++] = fPos.x; pointValues[index++] = fPos.y; pointValues[index++] = fPos.z; pointValues[index++] = nor.x; pointValues[index++] = nor.y; pointValues[index++] = nor.z; pointValues[index++] = (float)i / (float)numberOfLimbs; pointValues[index++] = (float)j / (float)numberOfBonesPerLimb; pointValues[index++] = 0; pointValues[index++] = 1; pointValues[index++] = 0; } fPos = boneBuffer.bones[numberOfBonesPerLimb - 1].transform.position + basePosition + Vector3.up * .1f; pointValues[index++] = 1; pointValues[index++] = fPos.x; pointValues[index++] = fPos.y; pointValues[index++] = fPos.z; pointValues[index++] = fPos.x; pointValues[index++] = fPos.y; pointValues[index++] = fPos.z; pointValues[index++] = 0; pointValues[index++] = 1; pointValues[index++] = 0; pointValues[index++] = (float)i / (float)numberOfLimbs; pointValues[index++] = 1; pointValues[index++] = 0; pointValues[index++] = 1; pointValues[index++] = 0; } fullPointBuffer.SetData(pointValues); index = 0; for (int i = 0; i < numberOfLimbs; i++) { float rot = 360 * Random.value; for (int j = 0; j < numberOfBonesPerLimb; j++) { boneValues[index++] = i; boneValues[index++] = j; boneValues[index++] = boneBuffer.bones[j].transform.localToWorldMatrix[0, 0]; boneValues[index++] = boneBuffer.bones[j].transform.localToWorldMatrix[1, 0]; boneValues[index++] = boneBuffer.bones[j].transform.localToWorldMatrix[2, 0]; boneValues[index++] = boneBuffer.bones[j].transform.localToWorldMatrix[3, 0]; boneValues[index++] = boneBuffer.bones[j].transform.localToWorldMatrix[0, 1]; boneValues[index++] = boneBuffer.bones[j].transform.localToWorldMatrix[1, 1]; boneValues[index++] = boneBuffer.bones[j].transform.localToWorldMatrix[2, 1]; boneValues[index++] = boneBuffer.bones[j].transform.localToWorldMatrix[3, 1]; boneValues[index++] = boneBuffer.bones[j].transform.localToWorldMatrix[0, 2]; boneValues[index++] = boneBuffer.bones[j].transform.localToWorldMatrix[1, 2]; boneValues[index++] = boneBuffer.bones[j].transform.localToWorldMatrix[2, 2]; boneValues[index++] = boneBuffer.bones[j].transform.localToWorldMatrix[3, 2]; boneValues[index++] = boneBuffer.bones[j].transform.localToWorldMatrix[0, 3]; boneValues[index++] = boneBuffer.bones[j].transform.localToWorldMatrix[1, 3]; boneValues[index++] = boneBuffer.bones[j].transform.localToWorldMatrix[2, 3]; boneValues[index++] = boneBuffer.bones[j].transform.localToWorldMatrix[3, 3]; var rotation = Matrix4x4.Rotate(boneBuffer.bones[j].rotation); var quat = QuaternionFromMatrix(boneBuffer.bones[j].transform.localToWorldMatrix); //undo rotations of blender var tmpMat = Matrix4x4.Rotate(quat) * boneBuffer.bindPoses[j]; //adding random y rotation! tmpMat = Matrix4x4.Rotate(Quaternion.AngleAxis(rot, Vector3.up)) * tmpMat; boneValues[index++] = tmpMat[0, 0]; boneValues[index++] = tmpMat[1, 0]; boneValues[index++] = tmpMat[2, 0]; boneValues[index++] = tmpMat[3, 0]; boneValues[index++] = tmpMat[0, 1]; boneValues[index++] = tmpMat[1, 1]; boneValues[index++] = tmpMat[2, 1]; boneValues[index++] = tmpMat[3, 1]; boneValues[index++] = tmpMat[0, 2]; boneValues[index++] = tmpMat[1, 2]; boneValues[index++] = tmpMat[2, 2]; boneValues[index++] = tmpMat[3, 2]; boneValues[index++] = tmpMat[0, 3]; boneValues[index++] = tmpMat[1, 3]; boneValues[index++] = tmpMat[2, 3]; boneValues[index++] = tmpMat[3, 3]; } } fullBoneBuffer.SetData(boneValues); index = 0; for (int j = 0; j < numberOfLimbs; j++) { for (int i = 0; i < vertBuffer.vertCount; i++) { // used vertValues[index++] = j; // positions vertValues[index++] = vertBuffer.vertices[i].x * .99f; vertValues[index++] = vertBuffer.vertices[i].y * .99f; vertValues[index++] = vertBuffer.vertices[i].z * .99f; // vel vertValues[index++] = 0; vertValues[index++] = 0; vertValues[index++] = 0; // normals vertValues[index++] = vertBuffer.normals[i].x; vertValues[index++] = vertBuffer.normals[i].y; vertValues[index++] = vertBuffer.normals[i].z; // uvs vertValues[index++] = vertBuffer.uvs[i].x; vertValues[index++] = vertBuffer.uvs[i].y; // target pos vertValues[index++] = vertBuffer.vertices[i].x; vertValues[index++] = vertBuffer.vertices[i].y; vertValues[index++] = vertBuffer.vertices[i].z; // bindPositions vertValues[index++] = vertBuffer.vertices[i].x; vertValues[index++] = vertBuffer.vertices[i].y; vertValues[index++] = vertBuffer.vertices[i].z; // bindNor vertValues[index++] = vertBuffer.normals[i].x; vertValues[index++] = vertBuffer.normals[i].y; vertValues[index++] = vertBuffer.normals[i].z; // bone weights vertValues[index++] = vertBuffer.weights[i].weight0; vertValues[index++] = vertBuffer.weights[i].weight1; vertValues[index++] = vertBuffer.weights[i].weight2; vertValues[index++] = vertBuffer.weights[i].weight3; // bone indices vertValues[index++] = vertBuffer.weights[i].boneIndex0; vertValues[index++] = vertBuffer.weights[i].boneIndex1; vertValues[index++] = vertBuffer.weights[i].boneIndex2; vertValues[index++] = vertBuffer.weights[i].boneIndex3; // Debug vertValues[index++] = 1; vertValues[index++] = 0; vertValues[index++] = 0; } } fullVertBuffer.SetData(vertValues); transformGroups = ((totalNumberBones) + (numThreads - 1)) / numThreads; constraintGroups = ((totalNumberPoints) + (numThreads - 1)) / numThreads; skinningGroups = ((totalNumberVerts) + (numThreads - 1)) / numThreads; physicsGroups = ((totalNumberPoints) + (numThreads - 1)) / numThreads; }