private BabylonSkeleton ConvertUnitySkeletonToBabylon(Transform[] bones, Matrix4x4[] bindPoses, Transform transform, GameObject gameObject, float progress) { ExporterWindow.ReportProgress(progress, "Exporting skeleton: " + gameObject.name); BabylonSkeleton babylonSkeleton = new BabylonSkeleton(); babylonSkeleton.name = gameObject.name; babylonSkeleton.id = Math.Abs(GetID(transform.gameObject).GetHashCode()); babylonSkeleton.needInitialSkinMatrix = false; // Prefilled to keep order and track parents. int index = 0; var transformToBoneMap = new Dictionary<Transform, BabylonBone>(); foreach (Transform unityBone in bones) { var babylonBone = new BabylonBone(); babylonBone.name = unityBone.name; babylonBone.index = index; transformToBoneMap.Add(unityBone, babylonBone); index++; } // Attaches Matrix and parent. index = 0; foreach (Transform unityBone in bones) { var babylonBone = transformToBoneMap[unityBone]; Matrix4x4 localTransform; // Unity BindPose is already inverse so take the inverse again :-) if (transformToBoneMap.ContainsKey(unityBone.parent)) { var babylonParentBone = transformToBoneMap[unityBone.parent]; babylonBone.parentBoneIndex = babylonParentBone.index; localTransform = bindPoses[babylonBone.parentBoneIndex] * bindPoses[index].inverse; } else { babylonBone.parentBoneIndex = -1; localTransform = bindPoses[index].inverse; } transformToBoneMap[unityBone].matrix = new[] { localTransform[0, 0], localTransform[1, 0], localTransform[2, 0], localTransform[3, 0], localTransform[0, 1], localTransform[1, 1], localTransform[2, 1], localTransform[3, 1], localTransform[0, 2], localTransform[1, 2], localTransform[2, 2], localTransform[3, 2], localTransform[0, 3], localTransform[1, 3], localTransform[2, 3], localTransform[3, 3] }; index++; } // Reorder and attach the skeleton. babylonSkeleton.bones = transformToBoneMap.Values.OrderBy(b => b.index).ToArray(); babylonScene.SkeletonsList.Add(babylonSkeleton); return babylonSkeleton; }
private void ExportSkin(IISkin skin, BabylonScene babylonScene) { var babylonSkeleton = new BabylonSkeleton {id = skins.IndexOf(skin)}; babylonSkeleton.name = "skeleton #" + babylonSkeleton.id; RaiseMessage(babylonSkeleton.name, 1); var bones = new List<BabylonBone>(); for (var index = 0; index < skin.NumBones; index++) { var bone = new BabylonBone {name = skin.GetBoneName(index), index = index}; var maxBone = skin.GetBone(index); var parentNode = maxBone.ParentNode; if (parentNode != null) { for (var recurseIndex = 0; recurseIndex < index; recurseIndex++) { if (skin.GetBone(recurseIndex).GetGuid() == parentNode.GetGuid()) { bone.parentBoneIndex = recurseIndex; break; } } } var hasParent = bone.parentBoneIndex != -1; bone.matrix = GetBoneMatrix(skin, maxBone, 0, hasParent); // Animation var babylonAnimation = new BabylonAnimation { name = bone.name + "Animation", property = "_matrix", dataType = BabylonAnimation.DataType.Matrix, loopBehavior = BabylonAnimation.LoopBehavior.Cycle, framePerSecond = Loader.Global.FrameRate }; var start = Loader.Core.AnimRange.Start; var end = Loader.Core.AnimRange.End; float[] previous = null; var keys = new List<BabylonAnimationKey>(); for (var key = start; key <= end; key += Ticks) { var current = GetBoneMatrix(skin, maxBone, key, hasParent); if (key == start || key == end || !(previous.IsEqualTo(current))) { keys.Add(new BabylonAnimationKey { frame = key / Ticks, values = current }); } previous = current; } babylonAnimation.keys = keys.ToArray(); bone.animation = babylonAnimation; bones.Add(bone); } babylonSkeleton.bones = bones.ToArray(); babylonScene.SkeletonsList.Add(babylonSkeleton); }