Forráskód Böngészése

Fixing 3ds max crashes

David Catuhe 11 éve
szülő
commit
2738ea50c3

BIN
Exporters/3ds Max/Max2Babylon-0.5.0.zip


+ 2 - 7
Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.Mesh.cs

@@ -1,7 +1,6 @@
 using System;
 using System.Collections.Generic;
 using System.Linq;
-using System.Runtime.InteropServices;
 using Autodesk.Max;
 using BabylonExport.Entities;
 using MaxSharp;
@@ -98,8 +97,7 @@ namespace Max2Babylon
 
             // Mesh
             var objectState = meshNode._Node.EvalWorldState(0, false);
-            bool mustBeDeleted;
-            var triObject = objectState.Obj.GetMesh(out mustBeDeleted);
+            var triObject = objectState.Obj.GetMesh();
             var mesh = triObject != null ? triObject.Mesh : null;
             var computedMesh = meshNode.GetMesh();
 
@@ -288,10 +286,7 @@ namespace Max2Babylon
                 // Buffers - Indices
                 babylonMesh.indices = sortedIndices.ToArray();
 
-                if (mustBeDeleted)
-                {
-                    triObject.DeleteMe();
-                }
+                triObject.Dispose();
             }
 
 

+ 158 - 0
Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.Skeleton.cs

@@ -0,0 +1,158 @@
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using Autodesk.Max;
+using BabylonExport.Entities;
+using MaxSharp;
+using SharpDX;
+
+namespace Max2Babylon
+{
+    partial class BabylonExporter
+    {
+        readonly List<IISkin> skins = new List<IISkin>();
+
+        IISkin GetSkinModifier(IINode node)
+        {
+            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);                        
+                    }
+
+                    return skin;
+                }
+            }
+
+
+            return null;
+        }
+
+        float[] GetBoneMatrix(IISkin skin, IINode bone, int t, bool hasParent)
+        {
+            var maxMatrix = bone.GetWorldMatrix(t, hasParent);
+
+            //var initialMatrix = Loader.Global.Matrix3.Create();
+            //skin.GetBoneInitTM(bone, initialMatrix, false);
+
+            //initialMatrix.Invert();
+
+            //maxMatrix = maxMatrix.MultiplyBy(initialMatrix);
+
+            //if (!hasParent)
+            //{
+            //    initialMatrix = Loader.Global.Matrix3.Create();
+            //    skin.GetSkinInitTM(bone, initialMatrix, false);
+
+            //    initialMatrix.Invert();
+
+            //    maxMatrix = maxMatrix.MultiplyBy(initialMatrix);
+            //}
+
+            maxMatrix.NoScale();
+
+            var trans = maxMatrix.Trans;
+
+            var parts = Loader.Global.AffineParts.Create();
+            Loader.Global.DecompAffine(maxMatrix, parts);
+
+            var rotationQuaternion = new Quaternion(parts.Q.X, parts.Q.Z, parts.Q.Y, parts.Q.W);
+
+            var matrix = Matrix.RotationQuaternion(rotationQuaternion) * Matrix.Translation(trans.X, trans.Z, trans.Y);
+
+            return matrix.ToArray();
+        }
+
+        private void ExportSkin(IISkin skin, BabylonScene babylonScene)
+        {
+            var babylonSkeleton = new BabylonSkeleton {id = skins.IndexOf(skin)};
+            babylonSkeleton.name = "skeleton #" + babylonSkeleton.id;
+
+            RaiseMessage(babylonSkeleton.name, true);
+
+            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);
+        }
+    }
+}

+ 0 - 1
Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.cs

@@ -4,7 +4,6 @@ using System.Globalization;
 using System.IO;
 using System.Linq;
 using System.Text;
-using System.Threading;
 using System.Windows.Forms;
 using Autodesk.Max;
 using BabylonExport.Entities;

+ 3 - 20
Exporters/3ds Max/Max2Babylon/Tools/Tools.cs

@@ -17,7 +17,7 @@ namespace Max2Babylon
         {
             var obj = node.ObjectRef;
 
-            if (obj.SuperClassID != SClass_ID.GenDerivob)
+            if (obj == null || obj.SuperClassID != SClass_ID.GenDerivob)
             {
                 return;
             }
@@ -263,29 +263,12 @@ namespace Max2Babylon
             return tm.Multiply(ptm);
         }
 
-        public static IMatrix3 GetWorldMatrixComplete(this IINode node, TimeValue t, bool parent)
+        public static ITriObject GetMesh(this IObject obj)
         {
-            var tm = node.GetObjTMAfterWSM(t, Interval.Forever._IInterval);
-            var ptm = node.ParentNode.GetObjTMAfterWSM(t, Interval.Forever._IInterval);
-
-            if (!parent)
-                return tm;
-
-            ptm.Invert();
-            return tm.Multiply(ptm);
-        }
-
-        public static ITriObject GetMesh(this IObject obj, out bool mustBeDeleted)
-        {
-            mustBeDeleted = false;
             if (obj.CanConvertToType(ClassID.TriObject._IClass_ID) == 0)
                 return null;
 
-            var tri = obj.ConvertToType(0, ClassID.TriObject._IClass_ID) as ITriObject;
-
-            mustBeDeleted = (tri != obj);
-
-            return tri;
+            return obj.ConvertToType(0, ClassID.TriObject._IClass_ID) as ITriObject;
         }
 
         public static bool IsAlmostEqualTo(this IPoint4 current, IPoint4 other, float epsilon)