private Vector3 BoneInitTransVec(_SkeletonData skl, _BoneData bone, Vector4 vec) { // 先将顶点通过T-POSE对应的骨骼矩阵转到骨骼空间,因为顶点的位置相对于骨骼位置是固定的,再乘以GetInitGlobalTransMatrix转到绑定效果的世界坐标位置 vec.w = 1; // 這裏要注意 Vector3 ret = bone.GetInitGlobalTransMatrix(skl) * bone.bindPose * vec; return(ret); }
// 自定義Asset private static void ExportSklAsset(SkinnedMeshRenderer skl, string fileName) { if (skl == null) { return; } var bones = skl.bones; if (bones != null && bones.Length > 0) { #if UNITY_EDITOR var mesh = skl.sharedMesh; if (mesh == null) { return; } var bindposes = mesh.bindposes; if (bindposes == null || bindposes.Length <= 0) { return; } // 先遍历InstanceID对应INDEX Dictionary <int, int> boneInstanceIDToIndexMap = new Dictionary <int, int>(); for (int i = 0; i < bones.Length; ++i) { var bone = bones[i]; boneInstanceIDToIndexMap[bone.GetInstanceID()] = i; } _SkeletonData sklData = ScriptableObject.CreateInstance <_SkeletonData>(); sklData.m_BoneDatas = new _BoneData[bones.Length]; for (int i = 0; i < bones.Length; ++i) { var bone = bones[i]; _BoneData boneData = new _BoneData(); boneData.initOffset = bone.localPosition; boneData.initScale = bone.localScale; boneData.initRot = bone.localRotation; boneData.bindPose = mesh.bindposes[i]; boneData.name = bone.name; if (bone.parent == null) { boneData.parentBone = -1; sklData.m_RootBoneIndex = i; } else { int parentBoneIdx; if (!boneInstanceIDToIndexMap.TryGetValue(bone.parent.GetInstanceID(), out parentBoneIdx)) { parentBoneIdx = -2; sklData.m_RootBoneIndex = i; Debug.LogErrorFormat("bone: {0} parent: {1} not found", bone.name, bone.parent.name); } boneData.parentBone = parentBoneIdx; } sklData.m_BoneDatas[i] = boneData; sklData.m_StartBoneUV = m_LastExportBoneUVStart; } for (int i = 0; i < sklData.m_BoneDatas.Length; ++i) { sklData.m_BoneDatas[i].InitGlobalMatrix(sklData); } if (skl.sharedMesh != null && skl.sharedMesh.isReadable) { if (skl.sharedMesh.vertexCount > 0) { var boneWeights = skl.sharedMesh.boneWeights; if (boneWeights != null && boneWeights.Length > 0) { sklData.m_VertexBoneData = new _VertexBoneData[boneWeights.Length]; for (int i = 0; i < boneWeights.Length; ++i) { var vBoneData = new _VertexBoneData(); vBoneData.boneIndex1 = boneWeights[i].boneIndex0; vBoneData.boneIndex2 = boneWeights[i].boneIndex1; vBoneData.boneIndex3 = boneWeights[i].boneIndex2; vBoneData.boneIndex4 = boneWeights[i].boneIndex3; vBoneData.boneWeight1 = boneWeights[i].weight0; vBoneData.boneWeight2 = boneWeights[i].weight1; vBoneData.boneWeight3 = boneWeights[i].weight2; sklData.m_VertexBoneData[i] = vBoneData; } } } } else { Debug.LogError("SkinedMesh is not isReadable~! so _vertexBoneData not export"); } AssetDatabase.CreateAsset(sklData, fileName); #endif } }