فهرست منبع

Adding instance exportation support for 3DSMax exporter

David Catuhe 11 سال پیش
والد
کامیت
215e70fda7

+ 17 - 0
Babylon/Tools/babylon.sceneSerializer.js

@@ -605,6 +605,23 @@
             }
         }
 
+        // Instances
+        serializationObject.instances = [];
+        for (var index = 0; index < mesh.instances.length; index++) {
+            var instance = mesh.instances[index];
+            var serializationInstance = {
+                name: instance.name,
+                position: instance.position,
+                rotation: instance.rotation,
+                rotationQuaternion: instance.rotationQuaternion,
+                scaling: instance.scaling
+            };
+            serializationObject.instances.push(serializationInstance);
+
+            // Animations
+            appendAnimations(instance, serializationInstance);
+        }
+
         // Animations
         appendAnimations(mesh, serializationObject);
 

+ 17 - 0
Babylon/Tools/babylon.sceneSerializer.ts

@@ -614,6 +614,23 @@
             }
         }
 
+        // Instances
+        serializationObject.instances = [];
+        for (var index = 0; index < mesh.instances.length; index++) {
+            var instance = mesh.instances[index];
+            var serializationInstance = {
+                name: instance.name,
+                position: instance.position,
+                rotation: instance.rotation,
+                rotationQuaternion: instance.rotationQuaternion,
+                scaling: instance.scaling
+            };
+            serializationObject.instances.push(serializationInstance);
+
+            // Animations
+            appendAnimations(instance, serializationInstance);
+        }
+
         // Animations
         appendAnimations(mesh, serializationObject);
 

+ 33 - 0
Exporters/3ds Max/BabylonExport.Entities/BabylonAbstractMesh.cs

@@ -0,0 +1,33 @@
+using System.Runtime.Serialization;
+
+namespace BabylonExport.Entities
+{
+    [DataContract]
+    public class BabylonAbstractMesh
+    {
+        [DataMember]
+        public string name { get; set; }
+        
+        [DataMember]
+        public float[] position { get; set; }
+
+        [DataMember]
+        public float[] rotation { get; set; }
+
+        [DataMember]
+        public float[] scaling { get; set; }
+
+        [DataMember]
+        public float[] rotationQuaternion { get; set; }
+
+        [DataMember]
+        public BabylonAnimation[] animations { get; set; }
+
+        public BabylonAbstractMesh()
+        {
+            position = new[] { 0f, 0f, 0f };
+            rotation = new[] { 0f, 0f, 0f };
+            scaling = new[] { 1f, 1f, 1f };
+        }
+    }
+}

+ 2 - 1
Exporters/3ds Max/BabylonExport.Entities/BabylonExport.Entities.csproj

@@ -36,7 +36,7 @@
   </PropertyGroup>
   <ItemGroup>
     <Reference Include="SharpDX">
-      <HintPath>..\Max2Babylon\Refs\SharpDX.dll</HintPath>
+      <HintPath>..\BabylonExport.Core\Refs\SharpDX.dll</HintPath>
     </Reference>
     <Reference Include="System" />
     <Reference Include="System.Core" />
@@ -56,6 +56,7 @@
     <Compile Include="BabylonLensFlareSystem.cs" />
     <Compile Include="BabylonLight.cs" />
     <Compile Include="BabylonMaterial.cs" />
+    <Compile Include="BabylonAbstractMesh.cs" />
     <Compile Include="BabylonMesh.cs" />
     <Compile Include="BabylonMultiMaterial.cs" />
     <Compile Include="BabylonParticleSystem.cs" />

+ 4 - 18
Exporters/3ds Max/BabylonExport.Entities/BabylonMesh.cs

@@ -3,10 +3,8 @@
 namespace BabylonExport.Entities
 {
     [DataContract]
-    public class BabylonMesh
+    public class BabylonMesh: BabylonAbstractMesh
     {
-        [DataMember]
-        public string name { get; set; }
 
         [DataMember]
         public string id { get; set; }
@@ -27,18 +25,6 @@ namespace BabylonExport.Entities
         public bool pickable { get; set; }
 
         [DataMember]
-        public float[] position { get; set; }
-
-        [DataMember]
-        public float[] rotation { get; set; }
-
-        [DataMember]
-        public float[] scaling { get; set; }
-
-        [DataMember]
-        public float[] rotationQuaternion { get; set; }
-
-        [DataMember]
         public float[] pivotMatrix { get; set; }
 
         [DataMember]
@@ -84,6 +70,9 @@ namespace BabylonExport.Entities
         public BabylonSubMesh[] subMeshes { get; set; }
 
         [DataMember]
+        public BabylonAbstractMesh[] instances { get; set; }
+
+        [DataMember]
         public int skeletonId { get; set; }
 
         [DataMember]
@@ -99,9 +88,6 @@ namespace BabylonExport.Entities
         public bool autoAnimateLoop { get; set; }
 
         [DataMember]
-        public BabylonAnimation[] animations { get; set; }
-
-        [DataMember]
         public bool showBoundingBox { get; set; }
 
         [DataMember]

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


+ 9 - 9
Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.Animation.cs

@@ -9,7 +9,7 @@ namespace Max2Babylon
     {
         const int Ticks = 160;
 
-        private BabylonAnimationKey GenerateFloatFunc(int index, IIKeyControl keyControl)
+        private static BabylonAnimationKey GenerateFloatFunc(int index, IIKeyControl keyControl)
         {
             var key = Loader.Global.ILinFloatKey.Create();
             keyControl.GetKey(index, key);
@@ -21,12 +21,12 @@ namespace Max2Babylon
             };
         }
 
-        private bool ExportFloatController(IControl control, string property, List<BabylonAnimation> animations)
+        private static bool ExportFloatController(IControl control, string property, List<BabylonAnimation> animations)
         {
             return ExportController(control, property, animations, 0x2001, BabylonAnimation.DataType.Float, GenerateFloatFunc);
         }
 
-        private bool ExportQuaternionController(IControl control, string property, List<BabylonAnimation> animations)
+        private static bool ExportQuaternionController(IControl control, string property, List<BabylonAnimation> animations)
         {
             IQuat previousQuat = null;
 
@@ -52,7 +52,7 @@ namespace Max2Babylon
                 });
         }
 
-        private bool ExportVector3Controller(IControl control, string property, List<BabylonAnimation> animations)
+        private static bool ExportVector3Controller(IControl control, string property, List<BabylonAnimation> animations)
         {
             var result = false;
 
@@ -100,7 +100,7 @@ namespace Max2Babylon
                 });
         }
 
-        private bool ExportController(IControl control, string property, List<BabylonAnimation> animations, uint classId, BabylonAnimation.DataType dataType, Func<int, IIKeyControl, BabylonAnimationKey> generateFunc)
+        private static bool ExportController(IControl control, string property, List<BabylonAnimation> animations, uint classId, BabylonAnimation.DataType dataType, Func<int, IIKeyControl, BabylonAnimationKey> generateFunc)
         {
             if (control == null)
             {
@@ -167,25 +167,25 @@ namespace Max2Babylon
             return true;
         }
 
-        private void ExportVector3Animation(string property, List<BabylonAnimation> animations,
+        private static void ExportVector3Animation(string property, List<BabylonAnimation> animations,
             Func<int, float[]> extractValueFunc)
         {
             ExportAnimation(property, animations, extractValueFunc, BabylonAnimation.DataType.Vector3);
         }
 
-        private void ExportQuaternionAnimation(string property, List<BabylonAnimation> animations,
+        private static void ExportQuaternionAnimation(string property, List<BabylonAnimation> animations,
             Func<int, float[]> extractValueFunc)
         {
             ExportAnimation(property, animations, extractValueFunc, BabylonAnimation.DataType.Quaternion);
         }
 
-        private void ExportFloatAnimation(string property, List<BabylonAnimation> animations,
+        private static void ExportFloatAnimation(string property, List<BabylonAnimation> animations,
             Func<int, float[]> extractValueFunc)
         {
             ExportAnimation(property, animations, extractValueFunc, BabylonAnimation.DataType.Float);
         }
 
-        private void ExportAnimation(string property, List<BabylonAnimation> animations, Func<int, float[]> extractValueFunc, BabylonAnimation.DataType dataType)
+        private static void ExportAnimation(string property, List<BabylonAnimation> animations, Func<int, float[]> extractValueFunc, BabylonAnimation.DataType dataType)
         {
             var start = Loader.Core.AnimRange.Start;
             var end = Loader.Core.AnimRange.End;

+ 58 - 49
Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.Mesh.cs

@@ -12,6 +12,11 @@ namespace Max2Babylon
         private int bonesCount;
         private void ExportMesh(IINode meshNode, BabylonScene babylonScene)
         {
+            if (meshNode.IsInstance())
+            {
+                return;
+            }
+
             if (meshNode.GetBoolProperty("babylonjs_noexport"))
             {
                 return;
@@ -52,38 +57,7 @@ namespace Max2Babylon
             }
 
             // Position / rotation / scaling
-            var wm = meshNode.GetWorldMatrix(0, meshNode.HasParent());
-            babylonMesh.position = wm.Trans.ToArraySwitched();
-
-            var parts = Loader.Global.AffineParts.Create();
-            Loader.Global.DecompAffine(wm, parts);
-
-            if (exportQuaternionsInsteadOfEulers)
-            {
-                babylonMesh.rotationQuaternion = parts.Q.ToArray();
-            }
-            else
-            {
-                var rotate = new float[3];
-
-                IntPtr xPtr = Marshal.AllocHGlobal(sizeof(float));
-                IntPtr yPtr = Marshal.AllocHGlobal(sizeof(float));
-                IntPtr zPtr = Marshal.AllocHGlobal(sizeof(float));
-                parts.Q.GetEuler(xPtr, yPtr, zPtr);
-
-                Marshal.Copy(xPtr, rotate, 0, 1);
-                Marshal.Copy(yPtr, rotate, 1, 1);
-                Marshal.Copy(zPtr, rotate, 2, 1);
-
-                var temp = rotate[1];
-                rotate[0] = -rotate[0] * parts.F;
-                rotate[1] = -rotate[2] * parts.F;
-                rotate[2] = -temp * parts.F;
-
-                babylonMesh.rotation = rotate;                
-            }
-
-            babylonMesh.scaling = parts.K.ToArraySwitched();
+            var wm = Tools.ExtractCoordinates(meshNode, babylonMesh, exportQuaternionsInsteadOfEulers);
 
             if (wm.Parity)
             {
@@ -294,10 +268,62 @@ namespace Max2Babylon
                 triObject.Dispose();
             }
 
+            // Instances
+            var tabs = Loader.Global.NodeTab.Create();
+            Loader.Global.IInstanceMgr.InstanceMgr.GetInstances(meshNode, tabs);
+            var instances = new List<BabylonAbstractMesh>();
+
+            for (var index = 0; index < tabs.Count; index++)
+            {
+                var indexer = new IntPtr(index);
+                var tab = tabs[indexer];
+
+                Marshal.FreeHGlobal(indexer);
+
+                if (meshNode.GetGuid() == tab.GetGuid())
+                {
+                    continue;
+                }
+
+                tab.MarkAsInstance();
+
+                var instance = new BabylonAbstractMesh {name = tab.Name};
+
+                Tools.ExtractCoordinates(tab, instance, exportQuaternionsInsteadOfEulers);
+                var instanceAnimations = new List<BabylonAnimation>();
+                GenerateCoordinatesAnimations(tab, instanceAnimations);
+                instance.animations = instanceAnimations.ToArray();
+
+                instances.Add(instance);
+            }
+
+            babylonMesh.instances = instances.ToArray();
 
             // Animations
             var animations = new List<BabylonAnimation>();
+            GenerateCoordinatesAnimations(meshNode, animations);
+            
+
+            if (!ExportFloatController(meshNode.VisController, "visibility", animations))
+            {
+                ExportFloatAnimation("visibility", animations, key => new[] { meshNode.GetVisibility(key, Tools.Forever) });
+            }
+
+            babylonMesh.animations = animations.ToArray();
+
+            if (meshNode.GetBoolProperty("babylonjs_autoanimate", 1))
+            {
+                babylonMesh.autoAnimate = true;
+                babylonMesh.autoAnimateFrom = (int)meshNode.GetFloatProperty("babylonjs_autoanimate_from");
+                babylonMesh.autoAnimateTo = (int)meshNode.GetFloatProperty("babylonjs_autoanimate_to", 100);
+                babylonMesh.autoAnimateLoop = meshNode.GetBoolProperty("babylonjs_autoanimateloop", 1);
+            }
+
+            babylonScene.MeshesList.Add(babylonMesh);
+        }
 
+        public static void GenerateCoordinatesAnimations(IINode meshNode, List<BabylonAnimation> animations)
+        {
             if (!ExportVector3Controller(meshNode.TMController.PositionController, "position", animations))
             {
                 ExportVector3Animation("position", animations, key =>
@@ -332,23 +358,6 @@ namespace Max2Babylon
                     return affineParts.K.ToArraySwitched();
                 });
             }
-
-            if (!ExportFloatController(meshNode.VisController, "visibility", animations))
-            {
-                ExportFloatAnimation("visibility", animations, key => new[] { meshNode.GetVisibility(key, Tools.Forever) });
-            }
-
-            babylonMesh.animations = animations.ToArray();
-
-            if (meshNode.GetBoolProperty("babylonjs_autoanimate", 1))
-            {
-                babylonMesh.autoAnimate = true;
-                babylonMesh.autoAnimateFrom = (int)meshNode.GetFloatProperty("babylonjs_autoanimate_from");
-                babylonMesh.autoAnimateTo = (int)meshNode.GetFloatProperty("babylonjs_autoanimate_to", 100);
-                babylonMesh.autoAnimateLoop = meshNode.GetBoolProperty("babylonjs_autoanimateloop", 1);
-            }
-
-            babylonScene.MeshesList.Add(babylonMesh);
         }
 
         int CreateGlobalVertex(IMesh mesh, int face, int facePart, List<GlobalVertex> vertices, bool hasUV, bool hasUV2, VNormal[] vnorms, List<GlobalVertex>[] verticesAlreadyExported, IISkinContextData skinContextData)

+ 57 - 0
Exporters/3ds Max/Max2Babylon/Tools/Tools.cs

@@ -2,8 +2,10 @@
 using System.Collections.Generic;
 using System.IO;
 using System.Linq;
+using System.Runtime.InteropServices;
 using System.Windows.Forms;
 using Autodesk.Max;
+using BabylonExport.Entities;
 using SharpDX;
 
 namespace Max2Babylon
@@ -248,6 +250,23 @@ namespace Max2Babylon
             return node.ParentNode != null && node.ParentNode.ObjectRef != null;
         }
 
+        public static bool IsInstance(this IAnimatable node)
+        {
+            var data = node.GetAppDataChunk(Loader.Class_ID, SClass_ID.Basenode, 1);
+
+            if (data != null)
+            {
+                return data.Data[0] != 0;
+            }
+
+            return false;
+        }
+
+        public static void MarkAsInstance(this IAnimatable node)
+        {
+            node.AddAppDataChunk(Loader.Class_ID, SClass_ID.Basenode, 1, new byte[] { 1 });
+        }
+
         public static Guid GetGuid(this IAnimatable node)
         {
             var uidData = node.GetAppDataChunk(Loader.Class_ID, SClass_ID.Basenode, 0);
@@ -568,5 +587,43 @@ namespace Max2Babylon
                 UpdateVector3Control(vector3Control, node, propertyName);
             }
         }
+
+        public static IMatrix3 ExtractCoordinates(IINode meshNode, BabylonAbstractMesh babylonMesh, bool exportQuaternionsInsteadOfEulers)
+        {
+            var wm = meshNode.GetWorldMatrix(0, meshNode.HasParent());
+            babylonMesh.position = wm.Trans.ToArraySwitched();
+
+            var parts = Loader.Global.AffineParts.Create();
+            Loader.Global.DecompAffine(wm, parts);
+
+            if (exportQuaternionsInsteadOfEulers)
+            {
+                babylonMesh.rotationQuaternion = parts.Q.ToArray();
+            }
+            else
+            {
+                var rotate = new float[3];
+
+                IntPtr xPtr = Marshal.AllocHGlobal(sizeof(float));
+                IntPtr yPtr = Marshal.AllocHGlobal(sizeof(float));
+                IntPtr zPtr = Marshal.AllocHGlobal(sizeof(float));
+                parts.Q.GetEuler(xPtr, yPtr, zPtr);
+
+                Marshal.Copy(xPtr, rotate, 0, 1);
+                Marshal.Copy(yPtr, rotate, 1, 1);
+                Marshal.Copy(zPtr, rotate, 2, 1);
+
+                var temp = rotate[1];
+                rotate[0] = -rotate[0] * parts.F;
+                rotate[1] = -rotate[2] * parts.F;
+                rotate[2] = -temp * parts.F;
+
+                babylonMesh.rotation = rotate;
+            }
+
+            babylonMesh.scaling = parts.K.ToArraySwitched();
+
+            return wm;
+        }
     }
 }

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 1 - 1
babylon.1.14-beta-debug.js


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 2 - 2
babylon.1.14-beta.js