public BoneInfo Init() { materialProperties = transform.GetComponent <RASCALPhysMaterialProperties>(); return(this); }
internal Skinfo Init() { bakedMesh = new Mesh(); materialProperties = skinnedMesh.GetComponent <RASCALPhysMaterialProperties>(); if (skinnedMesh.bones.Length == 0) { noBones = true; BoneInfo tBone = new BoneInfo() { srcSkin = skinnedMesh, transform = skinnedMesh.transform, host = host, parentSkinfo = this }.Init(); for (int v = 0; v < skinnedMesh.sharedMesh.vertexCount; v++) { tBone.affectedVerts.Add(v); } bones = new List <BoneInfo>() { tBone }; } else { List <BoneInfo> tBones = skinnedMesh.bones.Select(x => new BoneInfo() { srcSkin = skinnedMesh, transform = x, host = host, parentSkinfo = this }.Init()).ToList(); BoneWeight[] weights = skinnedMesh.sharedMesh.boneWeights; //v is vertex index in the mesh for (int v = 0; v < weights.Length; v++) { var weight = weights[v]; Weight wInfo = new Weight[] { new Weight() { weight = weight.weight0, boneIndex = weight.boneIndex0 }, new Weight() { weight = weight.weight1, boneIndex = weight.boneIndex1 }, new Weight() { weight = weight.weight2, boneIndex = weight.boneIndex2 }, new Weight() { weight = weight.weight3, boneIndex = weight.boneIndex3 }, }.OrderBy(x => x.weight).Last(); tBones[wInfo.boneIndex].affectedVerts.Add(v); } bones = tBones.Where(b => b.affectedVerts.Count > 0 && !host.excludedBones.Contains(b.transform)).ToList(); } List <int> skinTriList; int subMeshIdx = 0; int subMeshCount = skinnedMesh.sharedMesh.subMeshCount; boneStart: if (host.splitCollisionMeshesByMaterial) { skinTriList = skinnedMesh.sharedMesh.GetTriangles(subMeshIdx).ToList(); } else { skinTriList = skinnedMesh.sharedMesh.triangles.ToList(); } if (!host.excludedMaterials.Contains(skinnedMesh.sharedMaterials[subMeshIdx])) { foreach (BoneInfo boneInfo in bones) { List <int> listTris = new List <int>(); for (int t = 0; t < skinTriList.Count;) { int[] triSet = new int[] { skinTriList[t++], skinTriList[t++], skinTriList[t++] }; if (boneInfo.affectedVerts.Contains(triSet[0]) || boneInfo.affectedVerts.Contains(triSet[1]) || boneInfo.affectedVerts.Contains(triSet[2])) { if (host.onlyUniqueTriangles) { t -= 3; skinTriList.RemoveRange(t, 3); } listTris.AddRange(triSet); } } if (listTris.Count == 0) { continue; } int polyCount = listTris.Count / 3; BoneMeshColl boneMesh = new BoneMeshColl() { parentBone = boneInfo, host = host, skinnedMeshMaterialIndex = subMeshIdx }.Init(); boneInfo.boneMeshes.Add(boneMesh); if (polyCount > host.maxColliderTriangles) { int meshGroups = Mathf.CeilToInt((float)polyCount / host.maxColliderTriangles); boneMesh.SetTris(listTris.Take(host.maxColliderTriangles * 3)); for (int i = 1; i < meshGroups; i++) { BoneMeshColl tBoneMesh = new BoneMeshColl() { parentBone = boneInfo, host = host }.Init(); tBoneMesh.SetTris(listTris.Skip(i * host.maxColliderTriangles * 3).Take(host.maxColliderTriangles * 3)); boneInfo.boneMeshes.Add(tBoneMesh); } } else { boneMesh.SetTris(listTris); } } } if (host.splitCollisionMeshesByMaterial && subMeshIdx < subMeshCount - 1) { subMeshIdx++; goto boneStart; } bones.RemoveAll(b => b.boneMeshes.Count == 0); foreach (BoneInfo bone in bones) { bone.affectedVerts = null; } return(this); }