123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 |
- using System;
- using System.Collections.Generic;
- using Autodesk.Max;
- using BabylonExport.Entities;
- using SharpDX;
- namespace Max2Babylon
- {
- internal class BonePoseInfo
- {
- public IGMatrix AbsoluteTransform { get; set; }
- public IGMatrix LocalTransform { get; set; }
- }
- partial class BabylonExporter
- {
- readonly List<IIGameSkin> skins = new List<IIGameSkin>();
- readonly List<IIGameNode> skinnedNodes = new List<IIGameNode>();
- IGMatrix WithNoScale(IGMatrix mat)
- {
- var mat3 = mat.ExtractMatrix3();
- mat3.NoScale();
- return Loader.Global.GMatrix.Create(mat3);
- }
- private void ExportSkin( IIGameSkin skin, BabylonScene babylonScene)
- {
- var babylonSkeleton = new BabylonSkeleton { id = skins.IndexOf(skin) };
- babylonSkeleton.name = "skeleton #" + babylonSkeleton.id;
- RaiseMessage(babylonSkeleton.name, 1);
- IGMatrix skinInitMatrix = Loader.Global.GMatrix.Create(Loader.Global.Matrix3.Create(true));
- skin.GetInitSkinTM(skinInitMatrix);
- var skinIndex = skins.IndexOf(skin);
- var meshNode = skinnedNodes[skinIndex];
- var meshInitMatrix = meshNode.GetObjectTM(0);
- var boneIds = skinSortedBones[skin];
- var bones = new BabylonBone[boneIds.Count];
- var gameBones = new IIGameNode[boneIds.Count];
- var bindPoseInfos = new BonePoseInfo[boneIds.Count];
- for (var unsortedIndex = 0; unsortedIndex < skin.TotalSkinBoneCount; unsortedIndex++)
- {
- var gameBone = skin.GetIGameBone(unsortedIndex, false);
- int index = gameBone == null ? boneIds.IndexOf(-2) : boneIds.IndexOf(gameBone.NodeID);
- if (gameBone == null)
- {
- gameBones[index]=null;
- bones[index] = new BabylonBone { index = index, name = "null-bone" };
- bindPoseInfos[index] = new BonePoseInfo { };
- }
- else
- {
- gameBones[index] = gameBone;
- bones[index] = new BabylonBone { index = index, name = gameBone.Name };
- //IGMatrix boneInitMatrix = Loader.Global.GMatrix.Create(Loader.Global.Matrix3.Create(true));
- var boneInitMatrix = gameBone.GetObjectTM(0);
- bindPoseInfos[index] = new BonePoseInfo { AbsoluteTransform = boneInitMatrix };
- }
- }
- // fix hierarchy an generate animation keys
- for (var index = 0; index < skin.TotalSkinBoneCount; index++)
- {
- var gameBone = gameBones[index];
- if (gameBone == null)
- {
- var babBone = bones[index];
- bindPoseInfos[index].LocalTransform = Loader.Global.GMatrix.Create(Loader.Global.Matrix3.Create(true));
- babBone.matrix = bindPoseInfos[index].LocalTransform.ToArray();
- }
- else
- {
- var parent = gameBone.NodeParent;
- var babBone = bones[index];
- if (parent != null)
- {
- babBone.parentBoneIndex = boneIds.IndexOf(parent.NodeID);
- }
- if (babBone.parentBoneIndex == -1)
- {
- bindPoseInfos[index].LocalTransform = bindPoseInfos[index].AbsoluteTransform.Multiply(meshInitMatrix.Inverse);
- }
- else
- {
- var parentBindPoseInfos = bindPoseInfos[babBone.parentBoneIndex];
- bindPoseInfos[index].LocalTransform = bindPoseInfos[index].AbsoluteTransform.Multiply(parentBindPoseInfos.AbsoluteTransform.Inverse);
- }
- babBone.matrix = bindPoseInfos[index].LocalTransform.ToArray();
- var babylonAnimation = new BabylonAnimation
- {
- name = gameBone.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 objectTM = gameBone.GetObjectTM(key);
- var parentNode = gameBone.NodeParent;
- IGMatrix mat;
- if (parentNode == null || babBone.parentBoneIndex == -1)
- {
- mat = objectTM.Multiply(meshNode.GetObjectTM(key).Inverse);
- }
- else
- {
- mat = objectTM.Multiply(parentNode.GetObjectTM(key).Inverse);
- }
- var current = mat.ToArray();
- if (key == start || key == end || !(previous.IsEqualTo(current)))
- {
- keys.Add(new BabylonAnimationKey
- {
- frame = key / Ticks,
- values = current
- });
- }
- previous = current;
- }
- babylonAnimation.keys = keys.ToArray();
- babBone.animation = babylonAnimation;
- }
- }
- babylonSkeleton.bones = bones;
- babylonScene.SkeletonsList.Add(babylonSkeleton);
- }
- }
- }
|