BabylonExporter.Skeleton.cs 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. using System.Collections.Generic;
  2. using Autodesk.Max;
  3. using BabylonExport.Entities;
  4. using SharpDX;
  5. namespace Max2Babylon
  6. {
  7. partial class BabylonExporter
  8. {
  9. readonly List<IISkin> skins = new List<IISkin>();
  10. IISkin GetSkinModifier(IINode node)
  11. {
  12. var obj = node.ObjectRef;
  13. if (obj.SuperClassID != SClass_ID.GenDerivob)
  14. {
  15. return null;
  16. }
  17. var derivedObject = obj as IIDerivedObject;
  18. if (derivedObject == null)
  19. {
  20. return null;
  21. }
  22. for (var index = 0; index < derivedObject.NumModifiers; index++)
  23. {
  24. var modifier = derivedObject.GetModifier(index);
  25. if (modifier.ClassID.PartA == 9815843 && modifier.ClassID.PartB == 87654) // Skin
  26. {
  27. var skin = modifier.GetInterface((InterfaceID)0x00010000) as IISkin;
  28. if (!skins.Contains(skin))
  29. {
  30. skins.Add(skin);
  31. }
  32. return skin;
  33. }
  34. }
  35. return null;
  36. }
  37. float[] GetBoneMatrix(IISkin skin, IINode bone, int t, bool hasParent)
  38. {
  39. var maxMatrix = bone.GetWorldMatrix(t, hasParent);
  40. //var initialMatrix = Loader.Global.Matrix3.Create();
  41. //skin.GetBoneInitTM(bone, initialMatrix, false);
  42. //initialMatrix.Invert();
  43. //maxMatrix = maxMatrix.MultiplyBy(initialMatrix);
  44. //if (!hasParent)
  45. //{
  46. // initialMatrix = Loader.Global.Matrix3.Create();
  47. // skin.GetSkinInitTM(bone, initialMatrix, false);
  48. // initialMatrix.Invert();
  49. // maxMatrix = maxMatrix.MultiplyBy(initialMatrix);
  50. //}
  51. maxMatrix.NoScale();
  52. var trans = maxMatrix.Trans;
  53. var parts = Loader.Global.AffineParts.Create();
  54. Loader.Global.DecompAffine(maxMatrix, parts);
  55. var rotationQuaternion = new Quaternion(parts.Q.X, parts.Q.Z, parts.Q.Y, parts.Q.W);
  56. var matrix = Matrix.RotationQuaternion(rotationQuaternion) * Matrix.Translation(trans.X, trans.Z, trans.Y);
  57. return matrix.ToArray();
  58. }
  59. private void ExportSkin(IISkin skin, BabylonScene babylonScene)
  60. {
  61. var babylonSkeleton = new BabylonSkeleton {id = skins.IndexOf(skin)};
  62. babylonSkeleton.name = "skeleton #" + babylonSkeleton.id;
  63. RaiseMessage(babylonSkeleton.name, 1);
  64. var bones = new List<BabylonBone>();
  65. for (var index = 0; index < skin.NumBones; index++)
  66. {
  67. var bone = new BabylonBone {name = skin.GetBoneName(index), index = index};
  68. var maxBone = skin.GetBone(index);
  69. var parentNode = maxBone.ParentNode;
  70. if (parentNode != null)
  71. {
  72. for (var recurseIndex = 0; recurseIndex < index; recurseIndex++)
  73. {
  74. if (skin.GetBone(recurseIndex).GetGuid() == parentNode.GetGuid())
  75. {
  76. bone.parentBoneIndex = recurseIndex;
  77. break;
  78. }
  79. }
  80. }
  81. var hasParent = bone.parentBoneIndex != -1;
  82. bone.matrix = GetBoneMatrix(skin, maxBone, 0, hasParent);
  83. // Animation
  84. var babylonAnimation = new BabylonAnimation
  85. {
  86. name = bone.name + "Animation",
  87. property = "_matrix",
  88. dataType = BabylonAnimation.DataType.Matrix,
  89. loopBehavior = BabylonAnimation.LoopBehavior.Cycle,
  90. framePerSecond = Loader.Global.FrameRate
  91. };
  92. var start = Loader.Core.AnimRange.Start;
  93. var end = Loader.Core.AnimRange.End;
  94. float[] previous = null;
  95. var keys = new List<BabylonAnimationKey>();
  96. for (var key = start; key <= end; key += Ticks)
  97. {
  98. var current = GetBoneMatrix(skin, maxBone, key, hasParent);
  99. if (key == start || key == end || !(previous.IsEqualTo(current)))
  100. {
  101. keys.Add(new BabylonAnimationKey
  102. {
  103. frame = key / Ticks,
  104. values = current
  105. });
  106. }
  107. previous = current;
  108. }
  109. babylonAnimation.keys = keys.ToArray();
  110. bone.animation = babylonAnimation;
  111. bones.Add(bone);
  112. }
  113. babylonSkeleton.bones = bones.ToArray();
  114. babylonScene.SkeletonsList.Add(babylonSkeleton);
  115. }
  116. }
  117. }