Procházet zdrojové kódy

Merge branch 'master' of https://github.com/BabylonJS/Babylon.js

Conflicts:
	Babylon/Loading/Plugins/babylon.babylonFileLoader.js
	Babylon/Loading/Plugins/babylon.babylonFileLoader.ts
	Babylon/Tools/babylon.tools.ts
	babylon.2.0-alpha.debug.js
	babylon.2.0-alpha.js
David Catuhe před 10 roky
rodič
revize
0132ad49cb

+ 1 - 0
Babylon/babylon.node.ts

@@ -15,6 +15,7 @@
         public _currentRenderId = -1;
 
         public _waitingParentId: string;
+        public _waitingActions: any;
 
         private _scene: Scene;
         public _cache;

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

@@ -3,7 +3,7 @@
 namespace BabylonExport.Entities
 {
     [DataContract]
-    public class BabylonMesh: BabylonAbstractMesh
+    public class BabylonMesh : BabylonAbstractMesh
     {
 
         [DataMember]
@@ -58,11 +58,11 @@ namespace BabylonExport.Entities
         public bool checkCollisions { get; set; }
 
         [DataMember]
-        public bool receiveShadows { get; set; }    
-    
+        public bool receiveShadows { get; set; }
+
         [DataMember]
         public bool infiniteDistance { get; set; }
-        
+
         [DataMember]
         public int billboardMode { get; set; }
 
@@ -102,6 +102,18 @@ namespace BabylonExport.Entities
         [DataMember]
         public int alphaIndex { get; set; }
 
+        [DataMember]
+        public int physicsImpostor { get; set; }
+
+        [DataMember]
+        public float physicsMass { get; set; }
+
+        [DataMember]
+        public float physicsFriction { get; set; }
+
+        [DataMember]
+        public float physicsRestitution { get; set; }
+
         public BabylonMesh()
         {
             isEnabled = true;

binární
Exporters/3ds Max/Max2Babylon-0.15.zip


binární
Exporters/3ds Max/Max2Babylon-0.16.zip


+ 8 - 8
Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.Light.cs

@@ -73,13 +73,13 @@ namespace Max2Babylon
             // Shadows 
             if (maxLight.ShadowMethod == 1)
             {
-                if (lightState.Type == LightType.DirectLgt)
+                if (lightState.Type == LightType.DirectLgt || lightState.Type == LightType.SpotLgt)
                 {
                     ExportShadowGenerator(lightNode.MaxNode, babylonScene);
                 }
                 else
                 {
-                    RaiseWarning("Shadows maps are only supported for directional lights", 2);
+                    RaiseWarning("Shadows maps are only supported for directional and spot lights", 2);
                 }
             }
 
@@ -91,7 +91,7 @@ namespace Max2Babylon
                 wm.MultiplyBy(parentWorld.Inverse);
             }
             var position = wm.Translation;
-            babylonLight.position = new float[] { position.X, position.Y, position.Z };
+            babylonLight.position = new[] { position.X, position.Y, position.Z };
 
             // Direction
             var target = gameLight.LightTarget;
@@ -101,13 +101,13 @@ namespace Max2Babylon
                 var targetPosition = targetWm.Translation;
 
                 var direction = targetPosition.Subtract(position).Normalize;
-                babylonLight.direction = new float[] { direction.X, direction.Y, direction.Z };
+                babylonLight.direction = new[] { direction.X, direction.Y, direction.Z };
             }
             else
             {
                 var vDir = Loader.Global.Point3.Create(0, -1, 0);
                 vDir = wm.ExtractMatrix3().VectorTransform(vDir).Normalize;
-                babylonLight.direction = new float[] { vDir.X, vDir.Y, vDir.Z };
+                babylonLight.direction = new[] { vDir.X, vDir.Y, vDir.Z };
             }
 
             var maxScene = Loader.Core.RootNode;
@@ -171,7 +171,7 @@ namespace Max2Babylon
                     mat.MultiplyBy(parentWorld.Inverse);
                 }
                 var pos = mat.Translation;
-                return new float[] { pos.X, pos.Y, pos.Z };
+                return new[] { pos.X, pos.Y, pos.Z };
             });
 
             ExportVector3Animation("direction", animations, key =>
@@ -190,13 +190,13 @@ namespace Max2Babylon
                     var targetPosition = targetWm.Translation;
 
                     var direction = targetPosition.Subtract(positionLight).Normalize;
-                    return new float[] { direction.X, direction.Y, direction.Z };
+                    return new[] { direction.X, direction.Y, direction.Z };
                 }
                 else
                 {
                     var vDir = Loader.Global.Point3.Create(0, -1, 0);
                     vDir = wmLight.ExtractMatrix3().VectorTransform(vDir).Normalize;
-                    return new float[] { vDir.X, vDir.Y, vDir.Z };
+                    return new[] { vDir.X, vDir.Y, vDir.Z };
                 }
             });
 

+ 48 - 25
Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.Mesh.cs

@@ -124,7 +124,7 @@ namespace Max2Babylon
             // Collisions
             babylonMesh.checkCollisions = meshNode.MaxNode.GetBoolProperty("babylonjs_checkcollisions");
 
-            bool isSkinned = gameMesh.IsObjectSkinned;
+            var isSkinned = gameMesh.IsObjectSkinned;
             var skin = gameMesh.IGameSkin;
             var unskinnedMesh = gameMesh;
             IGMatrix skinInitPoseMatrix = Loader.Global.GMatrix.Create(Loader.Global.Matrix3.Create(true));
@@ -142,22 +142,20 @@ namespace Max2Babylon
             }
 
             // Position / rotation / scaling
+            var localTM = meshNode.GetObjectTM(0);
+            if (meshNode.NodeParent != null)
             {
-                var localTM = meshNode.GetObjectTM(0);
-                if (meshNode.NodeParent != null)
-                {
-                    var parentWorld = meshNode.NodeParent.GetObjectTM(0);
-                    localTM.MultiplyBy(parentWorld.Inverse);
-                }
-
-                var meshTrans = localTM.Translation;
-                var meshRotation = localTM.Rotation;
-                var meshScale = localTM.Scaling;
-                babylonMesh.position = new[] { meshTrans.X, meshTrans.Y, meshTrans.Z };
-                babylonMesh.rotationQuaternion = new[] { meshRotation.X, meshRotation.Y, meshRotation.Z, -meshRotation.W };
-                babylonMesh.scaling = new[] { meshScale.X, meshScale.Y, meshScale.Z };
+                var parentWorld = meshNode.NodeParent.GetObjectTM(0);
+                localTM.MultiplyBy(parentWorld.Inverse);
             }
 
+            var meshTrans = localTM.Translation;
+            var meshRotation = localTM.Rotation;
+            var meshScale = localTM.Scaling;
+            babylonMesh.position = new[] { meshTrans.X, meshTrans.Y, meshTrans.Z };
+            babylonMesh.rotationQuaternion = new[] { meshRotation.X, meshRotation.Y, meshRotation.Z, -meshRotation.W };
+            babylonMesh.scaling = new[] { meshScale.X, meshScale.Y, meshScale.Z };
+
             // Mesh
             RaiseMessage(meshNode.Name, 1);
 
@@ -178,6 +176,32 @@ namespace Max2Babylon
                     RaiseWarning(string.Format("Mesh {0} has tmore than 65536 vertices which means that it will require specific WebGL extension to be rendered. This may impact portability of your scene on low end devices.", babylonMesh.name), 2);
                 }
 
+                // Physics
+                var impostorText = meshNode.MaxNode.GetStringProperty("babylonjs_impostor", "None");
+
+                if (impostorText != "None")
+                {
+                    switch (impostorText)
+                    {
+                        case "Sphere":
+                            babylonMesh.physicsImpostor = 1;
+                            break;
+                        case "Box":
+                            babylonMesh.physicsImpostor = 2;
+                            break;
+                        case "Plane":
+                            babylonMesh.physicsImpostor = 3;
+                            break;
+                        default:
+                            babylonMesh.physicsImpostor = 0;
+                            break;
+                    }
+
+                    babylonMesh.physicsMass = meshNode.MaxNode.GetFloatProperty("babylonjs_mass");
+                    babylonMesh.physicsFriction = meshNode.MaxNode.GetFloatProperty("babylonjs_friction", 0.2f);
+                    babylonMesh.physicsRestitution = meshNode.MaxNode.GetFloatProperty("babylonjs_restitution", 0.2f);
+                }
+
                 // Material
                 var mtl = meshNode.NodeMaterial;
                 var multiMatsCount = 1;
@@ -342,20 +366,19 @@ namespace Max2Babylon
 
                 var instance = new BabylonAbstractMesh { name = tab.Name };
                 {
+                    var instanceLocalTM = meshNode.GetObjectTM(0);
 
-                    var localTM = meshNode.GetObjectTM(0);
-
-                    var meshTrans = localTM.Translation;
-                    var meshRotation = localTM.Rotation;
-                    var meshScale = localTM.Scaling;
-                    instance.position = new[] { meshTrans.X, meshTrans.Y, meshTrans.Z };
+                    var instanceTrans = instanceLocalTM.Translation;
+                    var instanceRotation = instanceLocalTM.Rotation;
+                    var instanceScale = instanceLocalTM.Scaling;
+                    instance.position = new[] { instanceTrans.X, instanceTrans.Y, instanceTrans.Z };
                     float rotx = 0, roty = 0, rotz = 0;
                     unsafe
                     {
-                        meshRotation.GetEuler(new IntPtr(&rotx), new IntPtr(&roty), new IntPtr(&rotz));
+                        instanceRotation.GetEuler(new IntPtr(&rotx), new IntPtr(&roty), new IntPtr(&rotz));
                     }
                     instance.rotation = new[] { rotx, roty, rotz };
-                    instance.scaling = new[] { meshScale.X, meshScale.Y, meshScale.Z };
+                    instance.scaling = new[] { instanceScale.X, instanceScale.Y, instanceScale.Z };
                 }
                 var instanceAnimations = new List<BabylonAnimation>();
                 GenerateCoordinatesAnimations(meshNode, instanceAnimations);
@@ -449,7 +472,7 @@ namespace Max2Babylon
                         worldMatrix.MultiplyBy(parentWorld.Inverse);
                     }
                     var trans = worldMatrix.Translation;
-                    return new[] {trans.X, trans.Y, trans.Z};
+                    return new[] { trans.X, trans.Y, trans.Z };
                 });
             }
 
@@ -469,7 +492,7 @@ namespace Max2Babylon
 
 
                     var rot = worldMatrix.Rotation;
-                    return new[] {rot.X, rot.Y, rot.Z, -rot.W};
+                    return new[] { rot.X, rot.Y, rot.Z, -rot.W };
                 });
             }
 
@@ -485,7 +508,7 @@ namespace Max2Babylon
                     }
                     var scale = worldMatrix.Scaling;
 
-                    return new[] {scale.X, scale.Y, scale.Z};
+                    return new[] { scale.X, scale.Y, scale.Z };
                 });
             }
         }

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

@@ -112,6 +112,8 @@ namespace Max2Babylon
 
             if (AutoSave3dsMaxFile)
             {
+                var forceSave = Loader.Core.FileSave;
+
                 if (callerForm != null)
                 {
                     callerForm.BringToFront();

+ 157 - 21
Exporters/3ds Max/Max2Babylon/Forms/ObjectPropertiesForm.Designer.cs

@@ -33,6 +33,8 @@
             this.butCancel = new System.Windows.Forms.Button();
             this.butOK = new System.Windows.Forms.Button();
             this.groupBox2 = new System.Windows.Forms.GroupBox();
+            this.nupAlphaIndex = new System.Windows.Forms.NumericUpDown();
+            this.label3 = new System.Windows.Forms.Label();
             this.chkNoExport = new System.Windows.Forms.CheckBox();
             this.chkShowSubMeshesBoundingBox = new System.Windows.Forms.CheckBox();
             this.chkShowBoundingBox = new System.Windows.Forms.CheckBox();
@@ -46,15 +48,26 @@
             this.nupFrom = new System.Windows.Forms.NumericUpDown();
             this.label1 = new System.Windows.Forms.Label();
             this.chkAutoAnimate = new System.Windows.Forms.CheckBox();
-            this.nupAlphaIndex = new System.Windows.Forms.NumericUpDown();
-            this.label3 = new System.Windows.Forms.Label();
+            this.groupBox4 = new System.Windows.Forms.GroupBox();
+            this.label6 = new System.Windows.Forms.Label();
+            this.cbImpostor = new System.Windows.Forms.ComboBox();
+            this.nupMass = new System.Windows.Forms.NumericUpDown();
+            this.label4 = new System.Windows.Forms.Label();
+            this.nupFriction = new System.Windows.Forms.NumericUpDown();
+            this.label5 = new System.Windows.Forms.Label();
+            this.nupRestitution = new System.Windows.Forms.NumericUpDown();
+            this.label7 = new System.Windows.Forms.Label();
             this.groupBox1.SuspendLayout();
             this.groupBox2.SuspendLayout();
+            ((System.ComponentModel.ISupportInitialize)(this.nupAlphaIndex)).BeginInit();
             this.groupBox3.SuspendLayout();
             this.grpAutoAnimate.SuspendLayout();
             ((System.ComponentModel.ISupportInitialize)(this.nupTo)).BeginInit();
             ((System.ComponentModel.ISupportInitialize)(this.nupFrom)).BeginInit();
-            ((System.ComponentModel.ISupportInitialize)(this.nupAlphaIndex)).BeginInit();
+            this.groupBox4.SuspendLayout();
+            ((System.ComponentModel.ISupportInitialize)(this.nupMass)).BeginInit();
+            ((System.ComponentModel.ISupportInitialize)(this.nupFriction)).BeginInit();
+            ((System.ComponentModel.ISupportInitialize)(this.nupRestitution)).BeginInit();
             this.SuspendLayout();
             // 
             // groupBox1
@@ -85,7 +98,7 @@
             this.butCancel.Anchor = System.Windows.Forms.AnchorStyles.Bottom;
             this.butCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
             this.butCancel.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
-            this.butCancel.Location = new System.Drawing.Point(174, 430);
+            this.butCancel.Location = new System.Drawing.Point(174, 599);
             this.butCancel.Name = "butCancel";
             this.butCancel.Size = new System.Drawing.Size(75, 23);
             this.butCancel.TabIndex = 6;
@@ -97,7 +110,7 @@
             this.butOK.Anchor = System.Windows.Forms.AnchorStyles.Bottom;
             this.butOK.DialogResult = System.Windows.Forms.DialogResult.OK;
             this.butOK.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
-            this.butOK.Location = new System.Drawing.Point(93, 430);
+            this.butOK.Location = new System.Drawing.Point(93, 599);
             this.butOK.Name = "butOK";
             this.butOK.Size = new System.Drawing.Size(75, 23);
             this.butOK.TabIndex = 5;
@@ -122,6 +135,27 @@
             this.groupBox2.TabStop = false;
             this.groupBox2.Text = "Misc.";
             // 
+            // nupAlphaIndex
+            // 
+            this.nupAlphaIndex.Location = new System.Drawing.Point(89, 143);
+            this.nupAlphaIndex.Maximum = new decimal(new int[] {
+            1000,
+            0,
+            0,
+            0});
+            this.nupAlphaIndex.Name = "nupAlphaIndex";
+            this.nupAlphaIndex.Size = new System.Drawing.Size(120, 20);
+            this.nupAlphaIndex.TabIndex = 5;
+            // 
+            // label3
+            // 
+            this.label3.AutoSize = true;
+            this.label3.Location = new System.Drawing.Point(18, 145);
+            this.label3.Name = "label3";
+            this.label3.Size = new System.Drawing.Size(65, 13);
+            this.label3.TabIndex = 6;
+            this.label3.Text = "Alpha index:";
+            // 
             // chkNoExport
             // 
             this.chkNoExport.AutoSize = true;
@@ -275,26 +309,113 @@
             this.chkAutoAnimate.UseVisualStyleBackColor = true;
             this.chkAutoAnimate.CheckedChanged += new System.EventHandler(this.chkAutoAnimate_CheckedChanged);
             // 
-            // nupAlphaIndex
-            // 
-            this.nupAlphaIndex.Location = new System.Drawing.Point(89, 143);
-            this.nupAlphaIndex.Maximum = new decimal(new int[] {
+            // groupBox4
+            // 
+            this.groupBox4.Controls.Add(this.nupRestitution);
+            this.groupBox4.Controls.Add(this.label7);
+            this.groupBox4.Controls.Add(this.nupFriction);
+            this.groupBox4.Controls.Add(this.label5);
+            this.groupBox4.Controls.Add(this.label6);
+            this.groupBox4.Controls.Add(this.cbImpostor);
+            this.groupBox4.Controls.Add(this.nupMass);
+            this.groupBox4.Controls.Add(this.label4);
+            this.groupBox4.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
+            this.groupBox4.Location = new System.Drawing.Point(12, 424);
+            this.groupBox4.Name = "groupBox4";
+            this.groupBox4.Size = new System.Drawing.Size(319, 155);
+            this.groupBox4.TabIndex = 7;
+            this.groupBox4.TabStop = false;
+            this.groupBox4.Text = "Physics";
+            // 
+            // label6
+            // 
+            this.label6.AutoSize = true;
+            this.label6.Location = new System.Drawing.Point(18, 27);
+            this.label6.Name = "label6";
+            this.label6.Size = new System.Drawing.Size(50, 13);
+            this.label6.TabIndex = 8;
+            this.label6.Text = "Impostor:";
+            // 
+            // cbImpostor
+            // 
+            this.cbImpostor.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+            this.cbImpostor.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
+            this.cbImpostor.FormattingEnabled = true;
+            this.cbImpostor.Items.AddRange(new object[] {
+            "None",
+            "Sphere",
+            "Box",
+            "Plane"});
+            this.cbImpostor.Location = new System.Drawing.Point(25, 43);
+            this.cbImpostor.Name = "cbImpostor";
+            this.cbImpostor.Size = new System.Drawing.Size(290, 21);
+            this.cbImpostor.TabIndex = 7;
+            // 
+            // nupMass
+            // 
+            this.nupMass.DecimalPlaces = 2;
+            this.nupMass.Location = new System.Drawing.Point(89, 70);
+            this.nupMass.Maximum = new decimal(new int[] {
             1000,
             0,
             0,
             0});
-            this.nupAlphaIndex.Name = "nupAlphaIndex";
-            this.nupAlphaIndex.Size = new System.Drawing.Size(120, 20);
-            this.nupAlphaIndex.TabIndex = 5;
+            this.nupMass.Name = "nupMass";
+            this.nupMass.Size = new System.Drawing.Size(120, 20);
+            this.nupMass.TabIndex = 5;
             // 
-            // label3
+            // label4
             // 
-            this.label3.AutoSize = true;
-            this.label3.Location = new System.Drawing.Point(18, 145);
-            this.label3.Name = "label3";
-            this.label3.Size = new System.Drawing.Size(65, 13);
-            this.label3.TabIndex = 6;
-            this.label3.Text = "Alpha index:";
+            this.label4.AutoSize = true;
+            this.label4.Location = new System.Drawing.Point(18, 70);
+            this.label4.Name = "label4";
+            this.label4.Size = new System.Drawing.Size(35, 13);
+            this.label4.TabIndex = 6;
+            this.label4.Text = "Mass:";
+            // 
+            // nupFriction
+            // 
+            this.nupFriction.DecimalPlaces = 2;
+            this.nupFriction.Location = new System.Drawing.Point(89, 96);
+            this.nupFriction.Maximum = new decimal(new int[] {
+            1,
+            0,
+            0,
+            0});
+            this.nupFriction.Name = "nupFriction";
+            this.nupFriction.Size = new System.Drawing.Size(120, 20);
+            this.nupFriction.TabIndex = 9;
+            // 
+            // label5
+            // 
+            this.label5.AutoSize = true;
+            this.label5.Location = new System.Drawing.Point(18, 96);
+            this.label5.Name = "label5";
+            this.label5.Size = new System.Drawing.Size(44, 13);
+            this.label5.TabIndex = 10;
+            this.label5.Text = "Friction:";
+            // 
+            // nupRestitution
+            // 
+            this.nupRestitution.DecimalPlaces = 2;
+            this.nupRestitution.Location = new System.Drawing.Point(89, 122);
+            this.nupRestitution.Maximum = new decimal(new int[] {
+            1,
+            0,
+            0,
+            0});
+            this.nupRestitution.Name = "nupRestitution";
+            this.nupRestitution.Size = new System.Drawing.Size(120, 20);
+            this.nupRestitution.TabIndex = 11;
+            // 
+            // label7
+            // 
+            this.label7.AutoSize = true;
+            this.label7.Location = new System.Drawing.Point(18, 122);
+            this.label7.Name = "label7";
+            this.label7.Size = new System.Drawing.Size(60, 13);
+            this.label7.TabIndex = 12;
+            this.label7.Text = "Restitution:";
             // 
             // ObjectPropertiesForm
             // 
@@ -302,7 +423,8 @@
             this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
             this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
             this.CancelButton = this.butCancel;
-            this.ClientSize = new System.Drawing.Size(343, 465);
+            this.ClientSize = new System.Drawing.Size(343, 634);
+            this.Controls.Add(this.groupBox4);
             this.Controls.Add(this.groupBox3);
             this.Controls.Add(this.groupBox2);
             this.Controls.Add(this.butCancel);
@@ -317,13 +439,18 @@
             this.groupBox1.PerformLayout();
             this.groupBox2.ResumeLayout(false);
             this.groupBox2.PerformLayout();
+            ((System.ComponentModel.ISupportInitialize)(this.nupAlphaIndex)).EndInit();
             this.groupBox3.ResumeLayout(false);
             this.groupBox3.PerformLayout();
             this.grpAutoAnimate.ResumeLayout(false);
             this.grpAutoAnimate.PerformLayout();
             ((System.ComponentModel.ISupportInitialize)(this.nupTo)).EndInit();
             ((System.ComponentModel.ISupportInitialize)(this.nupFrom)).EndInit();
-            ((System.ComponentModel.ISupportInitialize)(this.nupAlphaIndex)).EndInit();
+            this.groupBox4.ResumeLayout(false);
+            this.groupBox4.PerformLayout();
+            ((System.ComponentModel.ISupportInitialize)(this.nupMass)).EndInit();
+            ((System.ComponentModel.ISupportInitialize)(this.nupFriction)).EndInit();
+            ((System.ComponentModel.ISupportInitialize)(this.nupRestitution)).EndInit();
             this.ResumeLayout(false);
 
         }
@@ -350,5 +477,14 @@
         private System.Windows.Forms.CheckBox chkNoExport;
         private System.Windows.Forms.NumericUpDown nupAlphaIndex;
         private System.Windows.Forms.Label label3;
+        private System.Windows.Forms.GroupBox groupBox4;
+        private System.Windows.Forms.NumericUpDown nupMass;
+        private System.Windows.Forms.Label label4;
+        private System.Windows.Forms.Label label6;
+        private System.Windows.Forms.ComboBox cbImpostor;
+        private System.Windows.Forms.NumericUpDown nupRestitution;
+        private System.Windows.Forms.Label label7;
+        private System.Windows.Forms.NumericUpDown nupFriction;
+        private System.Windows.Forms.Label label5;
     }
 }

+ 10 - 0
Exporters/3ds Max/Max2Babylon/Forms/ObjectPropertiesForm.cs

@@ -29,6 +29,10 @@ namespace Max2Babylon
             Tools.UpdateNumericUpDown(nupTo, objects, "babylonjs_autoanimate_to");
 
             Tools.UpdateNumericUpDown(nupAlphaIndex, objects, "babylonjs_alphaindex");
+            Tools.UpdateNumericUpDown(nupMass, objects, "babylonjs_mass");
+            Tools.UpdateNumericUpDown(nupFriction, objects, "babylonjs_friction");
+            Tools.UpdateNumericUpDown(nupRestitution, objects, "babylonjs_restitution");
+            Tools.UpdateComboBox(cbImpostor, objects, "babylonjs_impostor");
         }
 
         private void ObjectPropertiesForm_Load(object sender, EventArgs e)
@@ -55,6 +59,12 @@ namespace Max2Babylon
             Tools.PrepareNumericUpDown(nupFrom, objects, "babylonjs_autoanimate_from");
             Tools.PrepareNumericUpDown(nupTo, objects, "babylonjs_autoanimate_to", 100.0f);
             Tools.PrepareNumericUpDown(nupAlphaIndex, objects, "babylonjs_alphaindex", 1000);
+
+            Tools.PrepareNumericUpDown(nupMass, objects, "babylonjs_mass");
+            Tools.PrepareNumericUpDown(nupFriction, objects, "babylonjs_friction", 0.2f);
+            Tools.PrepareNumericUpDown(nupRestitution, objects, "babylonjs_restitution", 0.2f);
+
+            Tools.PrepareComboBox(cbImpostor, objects[0], "babylonjs_impostor", "None");
         }
 
         private void chkAutoAnimate_CheckedChanged(object sender, EventArgs e)

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

@@ -18,6 +18,7 @@ namespace Max2Babylon
 
 <head>
     <title>Babylon.js</title>
+    <script type='text/javascript' src='http://www.babylonjs.com/oimo.js'></script>
     <script type='text/javascript' src='http://www.babylonjs.com/cannon.js'></script>
     <script type='text/javascript' src='http://www.babylonjs.com/babylon.js'></script>
     <style type='text/css'>

+ 10 - 3
Exporters/Blender/io_export_babylon.py

@@ -1,7 +1,7 @@
 bl_info = {
     'name': 'Babylon.js',
     'author': 'David Catuhe, Jeff Palmer',
-    'version': (1, 6, 0),
+    'version': (1, 6, 1),
     'blender': (2, 72, 0),
     "location": "File > Export > Babylon.js (.babylon)",
     "description": "Export Babylon.js scenes (.babylon)",
@@ -264,10 +264,10 @@ class BabylonExporter(bpy.types.Operator, bpy_extras.io_utils.ExportHelper):
                         bulb = Light(object)
                         self.lights.append(bulb)
                         if object.data.shadowMap != 'NONE':
-                            if bulb.light_type == DIRECTIONAL_LIGHT:
+                            if bulb.light_type == DIRECTIONAL_LIGHT or bulb.light_type == SPOT_LIGHT:
                                 self.shadowGenerators.append(ShadowGenerator(object, self.meshesAndNodes, scene))
                             else:
-                                BabylonExporter.warn('WARNING: Only directional (sun) type of lamp is invalid for shadows thus ignored: ' + object.name)                                
+                                BabylonExporter.warn('WARNING: Only directional (sun) and spot types of lamp are valid for shadows thus ignored: ' + object.name)                                
                     else:
                         BabylonExporter.warn('WARNING: The following lamp not visible in scene thus ignored: ' + object.name)
                         
@@ -1365,6 +1365,13 @@ class Material:
                         # Bump
                         BabylonExporter.log('Bump texture found');
                         self.textures.append(Texture('bumpTexture', mtex.normal_factor, mtex, filepath))  
+                    elif mtex.use_map_color_spec:
+                        # Specular
+                        BabylonExporter.log('Specular texture found');
+                        self.textures.append(Texture('specularTexture', mtex.specular_color_factor, mtex, filepath))
+                    else:
+                        BabylonExporter.warn('WARNING image texture type not recognized:  ' + str(mtex) + ', ignored.')
+
                         
             else:
                  BabylonExporter.warn('WARNING texture type not currently supported:  ' + mtex.texture.type + ', ignored.')

+ 1 - 0
Tools/BuildOurOwnBabylonJS/BuildOurOwnBabylonJS/babylonJS.xml

@@ -119,4 +119,5 @@
   <script src="Babylon/Tools/babylon.tools.tga.js"></script>
   <script src="Babylon/Tools/babylon.database.js"></script>
   <script src="Babylon/Math/babylon.math.js"></script>
+  <script src="Babylon/Mesh/babylon.meshSimplification.js"></script>
 </files>

+ 1 - 0
Tools/Gulp/gulpfile.js

@@ -169,6 +169,7 @@ gulp.task('scripts', ['shaders'] ,function() {
       '../../Babylon/Debug/babylon.debugLayer.js',
       '../../Babylon/Materials/Textures/babylon.rawTexture.js',
       '../../Babylon/Mesh/babylon.polygonMesh.js'
+	  '../../Babylon/Mesh/babylon.meshSimplification.js'
     ])
     .pipe(concat('babylon.js'))
     .pipe(gulp.dest('build/'))

+ 184 - 69
babylon.2.0.d.ts

@@ -77,7 +77,7 @@ declare module BABYLON {
         public cullBackFaces: boolean;
         public renderEvenInBackground: boolean;
         public scenes: Scene[];
-        private _gl;
+        public _gl: WebGLRenderingContext;
         private _renderingCanvas;
         private _windowIsBackground;
         private _audioEngine;
@@ -94,6 +94,9 @@ declare module BABYLON {
         private _loadingTextDiv;
         private _loadingDivBackgroundColor;
         private _drawCalls;
+        private _glVersion;
+        private _glRenderer;
+        private _glVendor;
         private _renderingQueueLaunched;
         private _activeRenderLoops;
         private fpsRange;
@@ -118,6 +121,11 @@ declare module BABYLON {
         private _workingCanvas;
         private _workingContext;
         constructor(canvas: HTMLCanvasElement, antialias?: boolean, options?: any);
+        public getGlInfo(): {
+            vendor: string;
+            renderer: string;
+            version: string;
+        };
         public getAudioEngine(): AudioEngine;
         public getAspectRatio(camera: Camera): number;
         public getRenderWidth(): number;
@@ -258,6 +266,12 @@ interface HTMLCanvasElement {
     mozRequestPointerLock(): void;
     webkitRequestPointerLock(): void;
 }
+interface CanvasRenderingContext2D {
+    imageSmoothingEnabled: boolean;
+    mozImageSmoothingEnabled: boolean;
+    oImageSmoothingEnabled: boolean;
+    webkitImageSmoothingEnabled: boolean;
+}
 interface WebGLTexture {
     isReady: boolean;
     isCube: boolean;
@@ -1252,41 +1266,6 @@ declare module BABYLON {
     }
 }
 declare module BABYLON {
-    class OculusCamera extends FreeCamera {
-        private _leftCamera;
-        private _rightCamera;
-        private _offsetOrientation;
-        private _deviceOrientationHandler;
-        constructor(name: string, position: Vector3, scene: Scene);
-        public _update(): void;
-        public _updateCamera(camera: FreeCamera): void;
-        public _onOrientationEvent(evt: DeviceOrientationEvent): void;
-        public attachControl(element: HTMLElement, noPreventDefault?: boolean): void;
-        public detachControl(element: HTMLElement): void;
-    }
-}
-declare module BABYLON {
-    class OculusGamepadCamera extends FreeCamera {
-        private _leftCamera;
-        private _rightCamera;
-        private _offsetOrientation;
-        private _deviceOrientationHandler;
-        private _gamepad;
-        private _gamepads;
-        public angularSensibility: number;
-        public moveSensibility: number;
-        constructor(name: string, position: Vector3, scene: Scene);
-        private _onNewGameConnected(gamepad);
-        public _update(): void;
-        public _checkInputs(): void;
-        public _updateCamera(camera: FreeCamera): void;
-        public _onOrientationEvent(evt: DeviceOrientationEvent): void;
-        public attachControl(element: HTMLElement, noPreventDefault?: boolean): void;
-        public detachControl(element: HTMLElement): void;
-        public dispose(): void;
-    }
-}
-declare module BABYLON {
     class TargetCamera extends Camera {
         public cameraDirection: Vector3;
         public cameraRotation: Vector2;
@@ -1347,32 +1326,6 @@ declare module BABYLON {
     }
 }
 declare module BABYLON {
-    class VRDeviceOrientationCamera extends OculusCamera {
-        public _alpha: number;
-        public _beta: number;
-        public _gamma: number;
-        constructor(name: string, position: Vector3, scene: Scene);
-        public _onOrientationEvent(evt: DeviceOrientationEvent): void;
-    }
-}
-declare var HMDVRDevice: any;
-declare var PositionSensorVRDevice: any;
-declare module BABYLON {
-    class WebVRCamera extends OculusCamera {
-        public _hmdDevice: any;
-        public _sensorDevice: any;
-        public _cacheState: any;
-        public _cacheQuaternion: Quaternion;
-        public _cacheRotation: Vector3;
-        public _vrEnabled: boolean;
-        constructor(name: string, position: Vector3, scene: Scene);
-        private _getWebVRDevices(devices);
-        public _update(): void;
-        public attachControl(element: HTMLElement, noPreventDefault?: boolean): void;
-        public detachControl(element: HTMLElement): void;
-    }
-}
-declare module BABYLON {
     class OculusCamera extends FreeCamera {
         private _leftCamera;
         private _rightCamera;
@@ -1622,6 +1575,7 @@ declare module BABYLON {
         public shouldDisplayAxis: (mesh: Mesh) => boolean;
         public axisRatio: number;
         public accentColor: string;
+        public customStatsFunction: () => string;
         constructor(scene: Scene);
         private _refreshMeshesTreeContent();
         private _renderSingleAxis(zero, unit, unitText, label, color);
@@ -1698,16 +1652,16 @@ declare module BABYLON {
     }
 }
 declare module BABYLON {
-    class DirectionalLight extends Light {
+    class DirectionalLight extends Light implements IShadowLight {
         public direction: Vector3;
         public position: Vector3;
         private _transformedDirection;
-        public _transformedPosition: Vector3;
+        public transformedPosition: Vector3;
         private _worldMatrix;
         constructor(name: string, direction: Vector3, scene: Scene);
         public getAbsolutePosition(): Vector3;
         public setDirectionToTarget(target: Vector3): Vector3;
-        public _computeTransformedPosition(): boolean;
+        public computeTransformedPosition(): boolean;
         public transferToEffect(effect: Effect, directionUniformName: string): void;
         public _getWorldMatrix(): Matrix;
     }
@@ -1725,6 +1679,15 @@ declare module BABYLON {
     }
 }
 declare module BABYLON {
+    interface IShadowLight {
+        position: Vector3;
+        direction: Vector3;
+        transformedPosition: Vector3;
+        name: string;
+        computeTransformedPosition(): boolean;
+        getScene(): Scene;
+        _shadowGenerator: ShadowGenerator;
+    }
     class Light extends Node {
         public diffuse: Color3;
         public specular: Color3;
@@ -1759,17 +1722,18 @@ declare module BABYLON {
     }
 }
 declare module BABYLON {
-    class SpotLight extends Light {
+    class SpotLight extends Light implements IShadowLight {
         public position: Vector3;
         public direction: Vector3;
         public angle: number;
         public exponent: number;
+        public transformedPosition: Vector3;
         private _transformedDirection;
-        private _transformedPosition;
         private _worldMatrix;
         constructor(name: string, position: Vector3, direction: Vector3, angle: number, exponent: number, scene: Scene);
         public getAbsolutePosition(): Vector3;
         public setDirectionToTarget(target: Vector3): Vector3;
+        public computeTransformedPosition(): boolean;
         public transferToEffect(effect: Effect, positionUniformName: string, directionUniformName: string): void;
         public _getWorldMatrix(): Matrix;
     }
@@ -1798,10 +1762,10 @@ declare module BABYLON {
         private _cachedPosition;
         private _cachedDirection;
         private _cachedDefines;
-        constructor(mapSize: number, light: DirectionalLight);
+        constructor(mapSize: number, light: IShadowLight);
         public isReady(subMesh: SubMesh, useInstances: boolean): boolean;
         public getShadowMap(): RenderTargetTexture;
-        public getLight(): DirectionalLight;
+        public getLight(): IShadowLight;
         public getTransformMatrix(): Matrix;
         public getDarkness(): number;
         public setDarkness(darkness: number): void;
@@ -2413,6 +2377,7 @@ declare module BABYLON {
         public scaleToRef(scale: number, result: Color4): void;
         public toString(): string;
         public clone(): Color4;
+        public copyFrom(source: Color4): void;
         static Lerp(left: Color4, right: Color4, amount: number): Color4;
         static LerpToRef(left: Color4, right: Color4, amount: number, result: Color4): void;
         static FromArray(array: number[], offset?: number): Color4;
@@ -3226,6 +3191,15 @@ declare module BABYLON {
         public convertToFlatShadedMesh(): void;
         public createInstance(name: string): InstancedMesh;
         public synchronizeInstances(): void;
+        /**
+        * Simplify the mesh according to the given array of settings.
+        * Function will return immediately and will simplify asnyc.
+        * @param settings a collection of simplification settings.
+        * @param parallelProcessing should all levels calculate parallel or one after the other.
+        * @param type the type of simplification to run.
+        * successCallback optional success callback to be called after the simplification finished processing all settings.
+        */
+        public simplify(settings: ISimplificationSettings[], parallelProcessing?: boolean, type?: SimplificationType, successCallback?: () => void): void;
         static CreateBox(name: string, size: number, scene: Scene, updatable?: boolean): Mesh;
         static CreateSphere(name: string, segments: number, diameter: number, scene: Scene, updatable?: boolean): Mesh;
         static CreateCylinder(name: string, height: number, diameterTop: number, diameterBottom: number, tessellation: number, subdivisions: any, scene: Scene, updatable?: any): Mesh;
@@ -3307,6 +3281,104 @@ declare module BABYLON.Internals {
     }
 }
 declare module BABYLON {
+    /**
+    * A simplifier interface for future simplification implementations.
+    */
+    interface ISimplifier {
+        /**
+        * Simplification of a given mesh according to the given settings.
+        * Since this requires computation, it is assumed that the function runs async.
+        * @param settings The settings of the simplification, including quality and distance
+        * @param successCallback A callback that will be called after the mesh was simplified.
+        * @param errorCallback in case of an error, this callback will be called. optional.
+        */
+        simplify(settings: ISimplificationSettings, successCallback: (simplifiedMeshes: Mesh) => void, errorCallback?: () => void): void;
+    }
+    /**
+    * Expected simplification settings.
+    * Quality should be between 0 and 1 (1 being 100%, 0 being 0%);
+    */
+    interface ISimplificationSettings {
+        quality: number;
+        distance: number;
+    }
+    class SimplificationSettings implements ISimplificationSettings {
+        public quality: number;
+        public distance: number;
+        constructor(quality: number, distance: number);
+    }
+    /**
+    * The implemented types of simplification.
+    * At the moment only Quadratic Error Decimation is implemented.
+    */
+    enum SimplificationType {
+        QUADRATIC = 0,
+    }
+    class DecimationTriangle {
+        public vertices: number[];
+        public normal: Vector3;
+        public error: number[];
+        public deleted: boolean;
+        public isDirty: boolean;
+        public borderFactor: number;
+        constructor(vertices: number[]);
+    }
+    class DecimationVertex {
+        public position: Vector3;
+        public normal: Vector3;
+        public uv: Vector2;
+        public id: any;
+        public q: QuadraticMatrix;
+        public isBorder: boolean;
+        public triangleStart: number;
+        public triangleCount: number;
+        constructor(position: Vector3, normal: Vector3, uv: Vector2, id: any);
+    }
+    class QuadraticMatrix {
+        public data: number[];
+        constructor(data?: number[]);
+        public det(a11: any, a12: any, a13: any, a21: any, a22: any, a23: any, a31: any, a32: any, a33: any): number;
+        public addInPlace(matrix: QuadraticMatrix): void;
+        public addArrayInPlace(data: number[]): void;
+        public add(matrix: QuadraticMatrix): QuadraticMatrix;
+        static FromData(a: number, b: number, c: number, d: number): QuadraticMatrix;
+        static DataFromNumbers(a: number, b: number, c: number, d: number): number[];
+    }
+    class Reference {
+        public vertexId: number;
+        public triangleId: number;
+        constructor(vertexId: number, triangleId: number);
+    }
+    /**
+    * An implementation of the Quadratic Error simplification algorithm.
+    * Original paper : http://www1.cs.columbia.edu/~cs4162/html05s/garland97.pdf
+    * Ported mostly from QSlim and http://voxels.blogspot.de/2014/05/quadric-mesh-simplification-with-source.html to babylon JS
+    * @author RaananW
+    */
+    class QuadraticErrorSimplification implements ISimplifier {
+        private _mesh;
+        private triangles;
+        private vertices;
+        private references;
+        private initialised;
+        public syncIterations: number;
+        public agressiveness: number;
+        public decimationIterations: number;
+        constructor(_mesh: Mesh);
+        public simplify(settings: ISimplificationSettings, successCallback: (simplifiedMeshes: Mesh) => void): void;
+        private runDecimation(settings, successCallback);
+        private initWithMesh(mesh, callback);
+        private init(callback);
+        private reconstructMesh();
+        private isFlipped(vertex1, index2, point, deletedArray, borderFactor);
+        private updateTriangles(vertexId, vertex, deletedArray, deletedTriangles);
+        private identifyBorder();
+        private updateMesh(identifyBorders?);
+        private vertexError(q, point);
+        private calculateError(vertex1, vertex2, pointResult?, normalResult?, uvResult?);
+    }
+}
+declare module BABYLON {
     class Polygon {
         static Rectangle(xmin: number, ymin: number, xmax: number, ymax: number): Vector2[];
         static Circle(radius: number, cx?: number, cy?: number, numberOfSides?: number): Vector2[];
@@ -3406,6 +3478,7 @@ declare module BABYLON {
         public size: number;
         public angle: number;
         public angularSpeed: number;
+        public copyTo(other: Particle): void;
     }
 }
 declare module BABYLON {
@@ -3469,6 +3542,7 @@ declare module BABYLON {
         private _actualFrame;
         private _scaledUpdateSpeed;
         constructor(name: string, capacity: number, scene: Scene, customEffect?: Effect);
+        public recycleParticle(particle: Particle): void;
         public getCapacity(): number;
         public isAlive(): boolean;
         public isStarted(): boolean;
@@ -4349,6 +4423,47 @@ declare module BABYLON {
         static Now : number;
         static GetFps(): number;
     }
+    /**
+    * An implementation of a loop for asynchronous functions.
+    */
+    class AsyncLoop {
+        public iterations: number;
+        private _fn;
+        private _successCallback;
+        public index: number;
+        private _done;
+        /**
+        * Constroctor.
+        * @param iterations the number of iterations.
+        * @param _fn the function to run each iteration
+        * @param _successCallback the callback that will be called upon succesful execution
+        * @param offset starting offset.
+        */
+        constructor(iterations: number, _fn: (asyncLoop: AsyncLoop) => void, _successCallback: () => void, offset?: number);
+        /**
+        * Execute the next iteration. Must be called after the last iteration was finished.
+        */
+        public executeNext(): void;
+        /**
+        * Break the loop and run the success callback.
+        */
+        public breakLoop(): void;
+        /**
+        * Helper function
+        */
+        static Run(iterations: number, _fn: (asyncLoop: AsyncLoop) => void, _successCallback: () => void, offset?: number): AsyncLoop;
+        /**
+        * A for-loop that will run a given number of iterations synchronous and the rest async.
+        * @param iterations total number of iterations
+        * @param syncedIterations number of synchronous iterations in each async iteration.
+        * @param fn the function to call each iteration.
+        * @param callback a success call back that will be called when iterating stops.
+        * @param breakFunction a break condition (optional)
+        * @param timeout timeout settings for the setTimeout function. default - 0.
+        * @constructor
+        */
+        static SyncAsyncForLoop(iterations: number, syncedIterations: number, fn: (iteration: number) => void, callback: () => void, breakFunction?: () => boolean, timeout?: number): void;
+    }
 }
 declare module BABYLON.Internals {
     interface DDSInfo {