DQ skinning for Unity
Dual Quaternion skinning implementation with bulging compensation
AssetPostProcessorReorderBones.cs
1 using UnityEngine;
2 using UnityEditor;
3 using System.Collections.Generic;
4 using System.Linq;
5 
6 #if UNITY_EDITOR
7 
12 public class AssetPostProcessorReorderBones : AssetPostprocessor
13 {
14  void OnPostprocessModel(GameObject g)
15  {
16  this.Process(g);
17  }
18 
19  void Process(GameObject g)
20  {
21  SkinnedMeshRenderer smr = g.GetComponentInChildren<SkinnedMeshRenderer>();
22  if (smr == null)
23  {
24  Debug.LogWarning("Unable to find Renderer" + smr.name);
25  return;
26  }
27 
28  //list of bones
29  List<Transform> boneTransforms = smr.bones.ToList();
30 
31  //sort based on hierarchy
32  boneTransforms.Sort(CompareTransform);
33 
34  //record bone index mappings (richardf advice)
35  //build a Dictionary<int, int> that records the old bone index => new bone index mappings,
36  //then run through every vertex and just do boneIndexN = dict[boneIndexN] for each weight on each vertex.
37  var remap = new Dictionary<int, int>();
38  for (int i = 0; i < smr.bones.Length; i++)
39  {
40  remap[i] = boneTransforms.IndexOf(smr.bones[i]);
41  }
42 
43  //remap bone weight indexes
44  BoneWeight[] bw = smr.sharedMesh.boneWeights;
45  for (int i = 0; i < bw.Length; i++)
46  {
47  bw[i].boneIndex0 = remap[bw[i].boneIndex0];
48  bw[i].boneIndex1 = remap[bw[i].boneIndex1];
49  bw[i].boneIndex2 = remap[bw[i].boneIndex2];
50  bw[i].boneIndex3 = remap[bw[i].boneIndex3];
51  }
52 
53  //remap bindposes
54  var bp = new Matrix4x4[smr.sharedMesh.bindposes.Length];
55  for (int i = 0; i < bp.Length; i++)
56  {
57  bp[remap[i]] = smr.sharedMesh.bindposes[i];
58  }
59 
60  //assign new data
61  smr.bones = boneTransforms.ToArray();
62  smr.sharedMesh.boneWeights = bw;
63  smr.sharedMesh.bindposes = bp;
64  }
65 
66  private static int CompareTransform(Transform A, Transform B)
67  {
68  if (B.IsChildOf(A))
69  {
70  return -1;
71  }
72 
73  if (A.IsChildOf(B))
74  {
75  return -1;
76  }
77 
78  return 0;
79  }
80 }
81 
82 #endif
AssetPostProcessorReorderBones
Sorts bone indexes in imported meshes. SkinnedMeshRenderer requires bone indexes to be sorted based ...
Definition: AssetPostProcessorReorderBones.cs:13