BabylonExporter.Skeleton.cs 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. using System;
  2. using System.Collections.Generic;
  3. using Autodesk.Max;
  4. using BabylonExport.Entities;
  5. using SharpDX;
  6. namespace Max2Babylon
  7. {
  8. internal class BonePoseInfo
  9. {
  10. public IGMatrix AbsoluteTransform { get; set; }
  11. public IGMatrix LocalTransform { get; set; }
  12. }
  13. partial class BabylonExporter
  14. {
  15. readonly List<IIGameSkin> skins = new List<IIGameSkin>();
  16. readonly List<IIGameNode> skinnedNodes = new List<IIGameNode>();
  17. private void ExportSkin(IIGameSkin skin, BabylonScene babylonScene)
  18. {
  19. var babylonSkeleton = new BabylonSkeleton { id = skins.IndexOf(skin) };
  20. babylonSkeleton.name = "skeleton #" + babylonSkeleton.id;
  21. RaiseMessage(babylonSkeleton.name, 1);
  22. var skinIndex = skins.IndexOf(skin);
  23. var bones = new List<BabylonBone>();
  24. var gameBones = new List<IIGameNode>();
  25. var boneIds = new List<int>();
  26. var bindPoseInfos = new List<BonePoseInfo>();
  27. for(int i = 0; i < skin.TotalSkinBoneCount; ++i)
  28. {
  29. bones.Add(null);
  30. gameBones.Add(null);
  31. boneIds.Add(-1);
  32. bindPoseInfos.Add(null);
  33. }
  34. for (var index = 0; index < skin.TotalSkinBoneCount; index++)
  35. {
  36. var gameBone = skin.GetIGameBone(index, false);
  37. var sortedIndex = skinSortedBones[skin].IndexOf(gameBone.NodeID);
  38. gameBones[sortedIndex] = (gameBone);
  39. boneIds[sortedIndex] =(gameBone.NodeID);
  40. bones[sortedIndex]=(new BabylonBone { index = sortedIndex, name = gameBone.Name });
  41. var boneInitMatrix = gameBone.GetObjectTM(0);
  42. bindPoseInfos[sortedIndex] = (new BonePoseInfo { AbsoluteTransform = boneInitMatrix });
  43. }
  44. // fix hierarchy and generate animation keys
  45. for (var index = 0; index < skin.TotalSkinBoneCount; index++)
  46. {
  47. var gameBone = gameBones[index];
  48. var parent = gameBone.NodeParent;
  49. var babBone = bones[index];
  50. if (parent != null)
  51. {
  52. babBone.parentBoneIndex = boneIds.IndexOf(parent.NodeID);
  53. }
  54. if (babBone.parentBoneIndex == -1)
  55. {
  56. bindPoseInfos[index].LocalTransform = bindPoseInfos[index].AbsoluteTransform;
  57. }
  58. else
  59. {
  60. var parentBindPoseInfos = bindPoseInfos[babBone.parentBoneIndex];
  61. bindPoseInfos[index].LocalTransform = bindPoseInfos[index].AbsoluteTransform.Multiply(parentBindPoseInfos.AbsoluteTransform.Inverse);
  62. }
  63. babBone.matrix = bindPoseInfos[index].LocalTransform.ToArray();
  64. var babylonAnimation = ExportMatrixAnimation("_matrix", key =>
  65. {
  66. var objectTM = gameBone.GetObjectTM(key);
  67. var parentNode = gameBone.NodeParent;
  68. IGMatrix mat;
  69. if (parentNode == null || babBone.parentBoneIndex == -1)
  70. {
  71. mat = objectTM;
  72. }
  73. else
  74. {
  75. mat = objectTM.Multiply(parentNode.GetObjectTM(key).Inverse);
  76. }
  77. return mat.ToArray();
  78. },
  79. false); // Do not remove linear animation keys for bones
  80. if (babylonAnimation != null)
  81. {
  82. babylonAnimation.name = gameBone.Name + "Animation"; // override default animation name
  83. babBone.animation = babylonAnimation;
  84. }
  85. }
  86. babylonSkeleton.needInitialSkinMatrix = true;
  87. babylonSkeleton.bones = bones.ToArray();
  88. babylonScene.SkeletonsList.Add(babylonSkeleton);
  89. }
  90. }
  91. }