MB3_CopyBoneWeights.cs 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. using UnityEngine;
  2. using System;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. namespace DigitalOpus.MB.Core {
  6. public class MB3_CopyBoneWeights {
  7. public static void CopyBoneWeightsFromSeamMeshToOtherMeshes(float radius, Mesh seamMesh, Mesh[] targetMeshes) {
  8. //Todo make sure meshes are assets
  9. List<int> seamVerts = new List<int> ();
  10. if (seamMesh == null) {
  11. Debug.LogError(string.Format("The SeamMesh cannot be null"));
  12. return;
  13. }
  14. if (seamMesh.vertexCount == 0){
  15. Debug.LogError("The seam mesh has no vertices. Check that the Asset Importer for the seam mesh does not have 'Optimize Mesh' checked.");
  16. return;
  17. }
  18. Vector3[] srcVerts = seamMesh.vertices;
  19. BoneWeight[] srcBW = seamMesh.boneWeights;
  20. Vector3[] srcNormal = seamMesh.normals;
  21. Vector4[] srcTangent = seamMesh.tangents;
  22. Vector2[] srcUVs = seamMesh.uv;
  23. if (srcUVs.Length != srcVerts.Length) {
  24. Debug.LogError("The seam mesh needs uvs to identify which vertices are part of the seam. Vertices with UV > .5 are part of the seam. Vertices with UV < .5 are not part of the seam.");
  25. return;
  26. }
  27. for (int i = 0; i < srcUVs.Length; i++) {
  28. if (srcUVs[i].x > .5f && srcUVs[i].y > .5f){
  29. seamVerts.Add (i);
  30. }
  31. }
  32. Debug.Log (string.Format("The seam mesh has {0} vertices of which {1} are seam vertices.", seamMesh.vertices.Length, seamVerts.Count));
  33. if (seamVerts.Count == 0) {
  34. Debug.LogError("None of the vertices in the Seam Mesh were marked as seam vertices. To mark a vertex as a seam vertex the UV" +
  35. " must be greater than (.5,.5). Vertices with UV less than (.5,.5) are excluded.");
  36. return;
  37. }
  38. //validate
  39. bool failed = false;
  40. for (int meshIdx = 0; meshIdx < targetMeshes.Length; meshIdx++) {
  41. if (targetMeshes[meshIdx] == null) {
  42. Debug.LogError(string.Format("Mesh {0} was null", meshIdx));
  43. failed = true;
  44. }
  45. if (radius < 0f) {
  46. Debug.LogError("radius must be zero or positive.");
  47. }
  48. }
  49. if (failed) {
  50. return;
  51. }
  52. for (int meshIdx = 0; meshIdx < targetMeshes.Length; meshIdx++) {
  53. Mesh tm = targetMeshes[meshIdx];
  54. Vector3[] otherVerts = tm.vertices;
  55. BoneWeight[] otherBWs = tm.boneWeights;
  56. Vector3[] otherNormals = tm.normals;
  57. Vector4[] otherTangents = tm.tangents;
  58. int numMatches = 0;
  59. for (int i = 0; i < otherVerts.Length; i++) {
  60. for (int sIdx = 0; sIdx < seamVerts.Count; sIdx++) {
  61. int j = seamVerts[sIdx];
  62. if (Vector3.Distance(otherVerts[i], srcVerts[j]) <= radius) {
  63. numMatches++;
  64. otherBWs[i] = srcBW[j];
  65. otherVerts[i] = srcVerts[j];
  66. if (otherNormals.Length == otherVerts.Length && srcNormal.Length == srcNormal.Length)
  67. {
  68. otherNormals[i] = srcNormal[j];
  69. }
  70. if (otherTangents.Length == otherVerts.Length && srcTangent.Length == srcVerts.Length)
  71. {
  72. otherTangents[i] = srcTangent[j];
  73. }
  74. }
  75. }
  76. }
  77. if (numMatches > 0) {
  78. targetMeshes[meshIdx].vertices = otherVerts;
  79. targetMeshes[meshIdx].boneWeights = otherBWs;
  80. targetMeshes[meshIdx].normals = otherNormals;
  81. targetMeshes[meshIdx].tangents = otherTangents;
  82. }
  83. Debug.Log(string.Format("Copied boneweights for {1} vertices in mesh {0} that matched positions in the seam mesh.", targetMeshes[meshIdx].name, numMatches));
  84. }
  85. }
  86. }
  87. }