123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340 |
- 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>();
- //IISkin GetSkinModifier(IINode node, out IModifier skinModifier)
- //{
- // skinModifier = null;
- // var obj = node.ObjectRef;
- // if (obj.SuperClassID != SClass_ID.GenDerivob)
- // {
- // return null;
- // }
- // var derivedObject = obj as IIDerivedObject;
- // if (derivedObject == null)
- // {
- // return null;
- // }
- // for (var index = 0; index < derivedObject.NumModifiers; index++)
- // {
- // var modifier = derivedObject.GetModifier(index);
- // if (modifier.ClassID.PartA == 9815843 && modifier.ClassID.PartB == 87654) // Skin
- // {
- // var skin = modifier.GetInterface((InterfaceID)0x00010000) as IISkin;
- // if (!skins.Contains(skin))
- // {
- // skins.Add(skin);
- // }
- // skinModifier = modifier;
- // return skin;
- // }
- // }
- // return null;
- //}
- //float[] GetBoneBindPoseLocalMatrix(IISkin skin, IINode bone, bool hasParent)
- //{
- // var matrix = Loader.Global.Matrix3.Create();
- // var result = skin.GetBoneInitTM(bone, matrix, false);
- // if (!hasParent)
- // {
- // return matrix.ToArray();
- // }
- // else
- // {
- // var parentInverse = Loader.Global.Matrix3.Create();
- // result = skin.GetBoneInitTM(bone.ParentNode, matrix, false);
- // parentInverse.Invert();
- // return matrix.Multiply(parentInverse).ToArray();
- // }
- //}
- //float[] GetBoneMatrixForFrame(IINode bone, int frame, bool hasParent)
- //{
- // // var nodeTM2 = bone.GetNodeTM(frame, Tools.Forever);
- // // var parent = bone.ParentNode;
- // // if (!hasParent)
- // // {
- // // parent = bone;
- // // }
- // // else
- // // {
- // // parent = bone.ParentNode;
- // // }
- // // var inverseParentTM = parent.GetNodeTM(frame, Tools.Forever);
- // // inverseParentTM.Invert();
- // // var localTransform = nodeTM2.Multiply(inverseParentTM);
- // // var vLocalPos = localTransform.Trans;
- // // var parts = Loader.Global.AffineParts.Create();
- // // Loader.Global.DecompAffine(localTransform, parts);
- // // IPoint3 eulerAngs = Loader.Global.Point3.Create();
- // //#if MAX2015
- // // var eulerAngsPtr = eulerAngs.NativePointer;
- // //#else
- // // var eulerAngsPtr = eulerAngs.Handle;
- // //#endif
- // // //Loader.Global.QuatToEuler(parts.Q, eulerAngsPtr);
- // // return ( Matrix.RotationQuaternion(new Quaternion(parts.Q.X, parts.Q.Y, parts.Q.Z, parts.Q.W))*Matrix.Translation(vLocalPos.X, vLocalPos.Z, vLocalPos.Y)).ToArray();
- // return Matrix.Identity.ToArray();
- //}
- 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 skinInitMatrix = meshNode.GetObjectTM(0);
- var bones = new List<BabylonBone>();
- var gameBones = new List<IIGameNode>();
- var boneIds = new List<int>();
- var bindPoseInfos = new List<BonePoseInfo>();
- for (var index = 0; index < skin.TotalSkinBoneCount; index++)
- {
- var gameBone = skin.GetIGameBone(index, false);
-
- if (gameBone == null)
- {
- gameBones.Add(null);
- boneIds.Add(-2);
- bones.Add(new BabylonBone { index = index, name = "null-bone" });
- bindPoseInfos.Add(new BonePoseInfo { });
- }
- else
- {
- gameBones.Add(gameBone);
- boneIds.Add(gameBone.NodeID);
- bones.Add(new BabylonBone { index = index, name = gameBone.Name });
- //IGMatrix boneInitMatrix = Loader.Global.GMatrix.Create(Loader.Global.Matrix3.Create(true));
- //skin.GetInitBoneTM(gameBone, boneInitMatrix);
- var boneInitMatrix = gameBone.GetObjectTM(0);
- bindPoseInfos.Add(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(skinInitMatrix.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;
- }
- }
- //FixupHierarchy(Loader.Core.RootNode, skin.GetBone(0), bones);
- babylonSkeleton.bones = bones.ToArray();
- babylonScene.SkeletonsList.Add(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;
- // var currentBoneNeutralMatrix = GetBoneBindPoseLocalMatrix(skin, maxBone, hasParent);
- // bone.matrix = currentBoneNeutralMatrix;
- // // 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 = GetBoneMatrixForFrame(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);
- // }
- // //FixupHierarchy(Loader.Core.RootNode, skin.GetBone(0), bones);
- // babylonSkeleton.bones = bones.ToArray();
- // babylonScene.SkeletonsList.Add(babylonSkeleton);
- //}
- //private void FixupHierarchy(IINode sceneRoot, IINode skeletonRoot, List<BabylonBone> bones)
- //{
- // var skeletonTransforms = new NodeTransforms(skeletonRoot, 0);
- // var sceneRootTransforms = new NodeTransforms(sceneRoot, 0);
- // var skelAbs = skeletonTransforms.AbsoluteTransform;
- // var invSceneAbs = sceneRootTransforms.AbsoluteTransform;
- // invSceneAbs.Invert();
- // var skelAbsInvSceneAbs = skelAbs.Multiply(invSceneAbs);
- // var invSkelLocalTransform = skeletonTransforms.LocalTransform;
- // invSkelLocalTransform.Invert();
- // var skelAbsInvSceneAbsXinvSkelLocalTransform = skelAbsInvSceneAbs.Multiply(invSkelLocalTransform);
- // bones[0].matrix = skelAbsInvSceneAbs.ToArray();
- // var matskelAbsInvSceneAbsXinvSkelLocalTransform = new Matrix(skelAbsInvSceneAbsXinvSkelLocalTransform.ToArray());
- // foreach (var b in bones)
- // {
- // var oldTransform = new Matrix(b.matrix);
- // b.matrix = (oldTransform * matskelAbsInvSceneAbsXinvSkelLocalTransform).ToArray();
- // foreach(var frame in b.animation.keys)
- // {
- // var oldTransform2 = new Matrix(frame.values);
- // frame.values = (oldTransform2 * matskelAbsInvSceneAbsXinvSkelLocalTransform).ToArray();
- // }
- // }
- //}
- }
- }
|