Explorar o código

Fixing json generation for 3ds max exporter
Adding new paramater to executecodeaction to define which object has raised the action

David Catuhe %!s(int64=11) %!d(string=hai) anos
pai
achega
29036ac228

+ 3 - 3
Babylon/Actions/babylon.action.js

@@ -10,7 +10,7 @@
         Action.prototype._prepare = function () {
         };
 
-        Action.prototype._executeCurrent = function () {
+        Action.prototype._executeCurrent = function (source) {
             if (this._condition) {
                 var currentRenderId = this._actionManager.getScene().getRenderId();
 
@@ -31,7 +31,7 @@
                 }
             }
 
-            this._nextActiveAction.execute();
+            this._nextActiveAction.execute(source);
 
             if (this._nextActiveAction._child) {
                 this._nextActiveAction = this._nextActiveAction._child;
@@ -40,7 +40,7 @@
             }
         };
 
-        Action.prototype.execute = function () {
+        Action.prototype.execute = function (source) {
         };
 
         Action.prototype.then = function (action) {

+ 5 - 5
Babylon/Actions/babylon.action.ts

@@ -2,8 +2,8 @@
     export class Action {
         public _actionManager: ActionManager;
 
-        private _nextActiveAction;
-        private _child;
+        private _nextActiveAction: Action;
+        private _child: Action;
         private _condition: Condition;
 
         constructor(public trigger: number, condition?: Condition) {
@@ -15,7 +15,7 @@
         public _prepare(): void {
         }
 
-        public _executeCurrent(): void {
+        public _executeCurrent(source: AbstractMesh): void {
             if (this._condition) {
                 var currentRenderId = this._actionManager.getScene().getRenderId();
 
@@ -36,7 +36,7 @@
                 }
             }
 
-            this._nextActiveAction.execute();
+            this._nextActiveAction.execute(source);
 
             if (this._nextActiveAction._child) {
                 this._nextActiveAction = this._nextActiveAction._child;
@@ -45,7 +45,7 @@
             }
         }
 
-        public execute(): void {
+        public execute(source: AbstractMesh): void {
 
         }
 

+ 2 - 2
Babylon/Actions/babylon.actionManager.js

@@ -91,12 +91,12 @@
             return action;
         };
 
-        ActionManager.prototype.processTrigger = function (trigger) {
+        ActionManager.prototype.processTrigger = function (trigger, source) {
             for (var index = 0; index < this.actions.length; index++) {
                 var action = this.actions[index];
 
                 if (action.trigger === trigger) {
-                    action._executeCurrent();
+                    action._executeCurrent(source);
                 }
             }
         };

+ 2 - 2
Babylon/Actions/babylon.actionManager.ts

@@ -73,12 +73,12 @@
             return action;
         }
 
-        public processTrigger(trigger: number): void {
+        public processTrigger(trigger: number, source: AbstractMesh): void {
             for (var index = 0; index < this.actions.length; index++) {
                 var action = this.actions[index];
 
                 if (action.trigger === trigger) {
-                    action._executeCurrent();
+                    action._executeCurrent(source);
                 }
             }
         }

+ 4 - 4
Babylon/Actions/babylon.directActions.js

@@ -145,9 +145,9 @@ var BABYLON;
             }
         };
 
-        CombineAction.prototype.execute = function () {
+        CombineAction.prototype.execute = function (source) {
             for (var index = 0; index < this.children.length; index++) {
-                this.children[index].execute();
+                this.children[index].execute(source);
             }
         };
         return CombineAction;
@@ -160,8 +160,8 @@ var BABYLON;
             _super.call(this, trigger, condition);
             this.func = func;
         }
-        ExecuteCodeAction.prototype.execute = function () {
-            this.func();
+        ExecuteCodeAction.prototype.execute = function (source) {
+            this.func(source);
         };
         return ExecuteCodeAction;
     })(BABYLON.Action);

+ 5 - 5
Babylon/Actions/babylon.directActions.ts

@@ -128,20 +128,20 @@
             }
         }
 
-        public execute(): void {
+        public execute(source: AbstractMesh): void {
             for (var index = 0; index < this.children.length; index++) {
-                this.children[index].execute();
+                this.children[index].execute(source);
             }
         }
     }
 
     export class ExecuteCodeAction extends Action {
-        constructor(trigger: number, public func: () => void, condition?: Condition) {
+        constructor(trigger: number, public func: (source: AbstractMesh) => void, condition?: Condition) {
             super(trigger, condition);
         }
 
-        public execute(): void {
-            this.func();
+        public execute(source: AbstractMesh): void {
+            this.func(source);
         }
     }
 

+ 2 - 2
Babylon/Collisions/babylon.pickingInfo.ts

@@ -9,8 +9,8 @@
     export class PickingInfo {
         public hit = false;
         public distance = 0;
-        public pickedPoint = null;
-        public pickedMesh = null;
+        public pickedPoint: Vector3 = null;
+        public pickedMesh: AbstractMesh = null;
         public bu = 0;
         public bv = 0;
         public faceId = -1;

+ 1 - 1
Babylon/Culling/babylon.boundingBox.js

@@ -156,4 +156,4 @@
     })();
     BABYLON.BoundingBox = BoundingBox;
 })(BABYLON || (BABYLON = {}));
-//# sourceMappingURL=babylon.BoundingBox.js.map
+//# sourceMappingURL=babylon.boundingBox.js.map

+ 2 - 0
Babylon/Loading/Plugins/babylon.babylonFileLoader.js

@@ -523,6 +523,8 @@ var BABYLON = BABYLON || {};
 
         if (parsedMesh.localMatrix) {
             mesh.setPivotMatrix(BABYLON.Matrix.FromArray(parsedMesh.localMatrix));
+        } else if (parsedMesh.pivotMatrix) {
+            mesh.setPivotMatrix(BABYLON.Matrix.FromArray(parsedMesh.pivotMatrix));
         }
 
         mesh.setEnabled(parsedMesh.isEnabled);

+ 8 - 8
Babylon/babylon.scene.js

@@ -203,16 +203,16 @@
                     if (pickResult.pickedMesh.actionManager) {
                         switch (evt.buttons) {
                             case 1:
-                                pickResult.pickedMesh.actionManager.processTrigger(BABYLON.ActionManager.OnLeftPickTrigger);
+                                pickResult.pickedMesh.actionManager.processTrigger(BABYLON.ActionManager.OnLeftPickTrigger, pickResult.pickedMesh);
                                 break;
                             case 2:
-                                pickResult.pickedMesh.actionManager.processTrigger(BABYLON.ActionManager.OnRightPickTrigger);
+                                pickResult.pickedMesh.actionManager.processTrigger(BABYLON.ActionManager.OnRightPickTrigger, pickResult.pickedMesh);
                                 break;
                             case 3:
-                                pickResult.pickedMesh.actionManager.processTrigger(BABYLON.ActionManager.OnCenterPickTrigger);
+                                pickResult.pickedMesh.actionManager.processTrigger(BABYLON.ActionManager.OnCenterPickTrigger, pickResult.pickedMesh);
                                 break;
                         }
-                        pickResult.pickedMesh.actionManager.processTrigger(BABYLON.ActionManager.OnPickTrigger);
+                        pickResult.pickedMesh.actionManager.processTrigger(BABYLON.ActionManager.OnPickTrigger, pickResult.pickedMesh);
                     }
                 }
 
@@ -774,7 +774,7 @@
             var beforeRenderTargetDate = new Date().getTime();
             if (this.renderTargetsEnabled) {
                 for (var renderIndex = 0; renderIndex < this._renderTargets.length; renderIndex++) {
-                    var renderTarget = this._renderTargets.data[renderIndex];
+                    renderTarget = this._renderTargets.data[renderIndex];
                     if (renderTarget._shouldRender()) {
                         this._renderId++;
                         renderTarget.render();
@@ -874,7 +874,7 @@
 
             // Actions
             if (this.actionManager) {
-                this.actionManager.processTrigger(BABYLON.ActionManager.OnEveryFrameTrigger);
+                this.actionManager.processTrigger(BABYLON.ActionManager.OnEveryFrameTrigger, null);
             }
 
             // Before render
@@ -1162,12 +1162,12 @@
             }
 
             if (this._pointerOverMesh && this._pointerOverMesh.actionManager) {
-                this._pointerOverMesh.actionManager.processTrigger(BABYLON.ActionManager.OnPointerOutTrigger);
+                this._pointerOverMesh.actionManager.processTrigger(BABYLON.ActionManager.OnPointerOutTrigger, this._pointerOverMesh);
             }
 
             this._pointerOverMesh = mesh;
             if (this._pointerOverMesh && this._pointerOverMesh.actionManager) {
-                this._pointerOverMesh.actionManager.processTrigger(BABYLON.ActionManager.OnPointerOverTrigger);
+                this._pointerOverMesh.actionManager.processTrigger(BABYLON.ActionManager.OnPointerOverTrigger, this._pointerOverMesh);
             }
         };
 

+ 11 - 11
Babylon/babylon.scene.ts

@@ -149,7 +149,7 @@
 
         private _selectionOctree: Octree<AbstractMesh>;
 
-        private _pointerOverMesh: Mesh;
+        private _pointerOverMesh: AbstractMesh;
 
         // Constructor
         constructor(engine: Engine) {
@@ -266,16 +266,16 @@
                     if (pickResult.pickedMesh.actionManager) {
                         switch (evt.buttons) {
                             case 1:
-                                pickResult.pickedMesh.actionManager.processTrigger(BABYLON.ActionManager.OnLeftPickTrigger);
+                                pickResult.pickedMesh.actionManager.processTrigger(BABYLON.ActionManager.OnLeftPickTrigger, pickResult.pickedMesh);
                                 break;
                             case 2:
-                                pickResult.pickedMesh.actionManager.processTrigger(BABYLON.ActionManager.OnRightPickTrigger);
+                                pickResult.pickedMesh.actionManager.processTrigger(BABYLON.ActionManager.OnRightPickTrigger, pickResult.pickedMesh);
                                 break;
                             case 3:
-                                pickResult.pickedMesh.actionManager.processTrigger(BABYLON.ActionManager.OnCenterPickTrigger);
+                                pickResult.pickedMesh.actionManager.processTrigger(BABYLON.ActionManager.OnCenterPickTrigger, pickResult.pickedMesh);
                                 break;
                         }
-                        pickResult.pickedMesh.actionManager.processTrigger(BABYLON.ActionManager.OnPickTrigger);
+                        pickResult.pickedMesh.actionManager.processTrigger(BABYLON.ActionManager.OnPickTrigger, pickResult.pickedMesh);
                     }
                 }
 
@@ -838,7 +838,7 @@
             var beforeRenderTargetDate = new Date().getTime();
             if (this.renderTargetsEnabled) {
                 for (var renderIndex = 0; renderIndex < this._renderTargets.length; renderIndex++) {
-                    var renderTarget = this._renderTargets.data[renderIndex];
+                    renderTarget = this._renderTargets.data[renderIndex];
                     if (renderTarget._shouldRender()) {
                         this._renderId++;
                         renderTarget.render();
@@ -940,7 +940,7 @@
 
             // Actions
             if (this.actionManager) {
-                this.actionManager.processTrigger(ActionManager.OnEveryFrameTrigger);
+                this.actionManager.processTrigger(ActionManager.OnEveryFrameTrigger, null);
             }
 
             // Before render
@@ -1227,22 +1227,22 @@
             }, predicate, fastCheck);
         }
 
-        public setPointerOverMesh(mesh: Mesh): void {
+        public setPointerOverMesh(mesh: AbstractMesh): void {
             if (this._pointerOverMesh === mesh) {
                 return;
             }
 
             if (this._pointerOverMesh && this._pointerOverMesh.actionManager) {
-                this._pointerOverMesh.actionManager.processTrigger(ActionManager.OnPointerOutTrigger);
+                this._pointerOverMesh.actionManager.processTrigger(ActionManager.OnPointerOutTrigger, this._pointerOverMesh);
             }
 
             this._pointerOverMesh = mesh;
             if (this._pointerOverMesh && this._pointerOverMesh.actionManager) {
-                this._pointerOverMesh.actionManager.processTrigger(ActionManager.OnPointerOverTrigger);
+                this._pointerOverMesh.actionManager.processTrigger(ActionManager.OnPointerOverTrigger, this._pointerOverMesh);
             }
         }
 
-        public getPointerOverMesh(): Mesh {
+        public getPointerOverMesh(): AbstractMesh {
             return this._pointerOverMesh;
         }
 

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

@@ -39,7 +39,7 @@ namespace BabylonExport.Entities
         public float[] rotationQuaternion { get; set; }
 
         [DataMember]
-        public float[] localMatrix { get; set; }
+        public float[] pivotMatrix { get; set; }
 
         [DataMember]
         public float[] positions { get; set; }

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

@@ -48,6 +48,7 @@ namespace Max2Babylon
                 babylonMultimaterial.materials = guids.ToArray();
 
                 babylonScene.MultiMaterialsList.Add(babylonMultimaterial);
+                return;
             }
 
 

+ 32 - 19
Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.Mesh.cs

@@ -74,11 +74,11 @@ namespace Max2Babylon
             }
 
             // Pivot
-            //var pivotMatrix = Matrix3.Identity._IMatrix3;
-            //pivotMatrix.PreTranslate(meshNode._Node.ObjOffsetPos);
-            //Loader.Global.PreRotateMatrix(pivotMatrix, meshNode._Node.ObjOffsetRot);
-            //Loader.Global.ApplyScaling(pivotMatrix, meshNode._Node.ObjOffsetScale);
-            //babylonMesh.localMatrix = pivotMatrix.ToArray();
+            var pivotMatrix = Matrix3.Identity._IMatrix3;
+            pivotMatrix.PreTranslate(meshNode._Node.ObjOffsetPos);
+            Loader.Global.PreRotateMatrix(pivotMatrix, meshNode._Node.ObjOffsetRot);
+            Loader.Global.ApplyScaling(pivotMatrix, meshNode._Node.ObjOffsetScale);
+            babylonMesh.pivotMatrix = pivotMatrix.ToArray();
 
             // Mesh
             var objectState = meshNode._Node.EvalWorldState(0, false);
@@ -129,14 +129,21 @@ namespace Max2Babylon
                 var hasUV = mesh.NumTVerts > 0;
                 var hasUV2 = mesh.GetNumMapVerts(2) > 0;
 
+                var noOptimize = meshNode._Node.GetBoolProperty("babylonjs_nooptimize");
+                
                 for (var face = 0; face < mesh.NumFaces; face++)
                 {
-                    indices.Add(CreateGlobalVertex(mesh, computedMesh, face, vx1, vertices, hasUV, hasUV2));
-                    indices.Add(CreateGlobalVertex(mesh, computedMesh, face, vx2, vertices, hasUV, hasUV2));
-                    indices.Add(CreateGlobalVertex(mesh, computedMesh, face, vx3, vertices, hasUV, hasUV2));
+                    indices.Add(CreateGlobalVertex(mesh, computedMesh, face, vx1, vertices, hasUV, hasUV2, noOptimize));
+                    indices.Add(CreateGlobalVertex(mesh, computedMesh, face, vx2, vertices, hasUV, hasUV2, noOptimize));
+                    indices.Add(CreateGlobalVertex(mesh, computedMesh, face, vx3, vertices, hasUV, hasUV2, noOptimize));
                     matIDs.Add(mesh.Faces[face].MatID % multiMatsCount);
                 }
 
+                if (vertices.Count >= 65536)
+                {
+                    RaiseError(string.Format("Mesh {0} has too many vertices: {1} (limit is 65535)", babylonMesh.name, vertices.Count));
+                }
+
                 // Buffers
                 babylonMesh.positions = vertices.SelectMany(v => v.Position.ToArraySwitched()).ToArray();
                 babylonMesh.normals = vertices.SelectMany(v => v.Normal.ToArraySwitched()).ToArray();
@@ -207,13 +214,17 @@ namespace Max2Babylon
                             }
                         }
                     }
-                    subMesh.indexCount = indexCount;
-                    subMesh.verticesStart = minVertexIndex;
-                    subMesh.verticesCount = maxVertexIndex - minVertexIndex + 1;
+                    if (indexCount != 0)
+                    {
+
+                        subMesh.indexCount = indexCount;
+                        subMesh.verticesStart = minVertexIndex;
+                        subMesh.verticesCount = maxVertexIndex - minVertexIndex + 1;
 
-                    indexStart += indexCount;
+                        indexStart += indexCount;
 
-                    subMeshes.Add(subMesh);
+                        subMeshes.Add(subMesh);
+                    }
                 }
                 babylonMesh.subMeshes = subMeshes.ToArray();
 
@@ -227,7 +238,7 @@ namespace Max2Babylon
             return babylonMesh;
         }
 
-        int CreateGlobalVertex(IMesh mesh, Mesh computedMesh, int face, int facePart, List<GlobalVertex> vertices, bool hasUV, bool hasUV2)
+        int CreateGlobalVertex(IMesh mesh, Mesh computedMesh, int face, int facePart, List<GlobalVertex> vertices, bool hasUV, bool hasUV2, bool noOptimize)
         {
             var vertexIndex = (int)mesh.Faces[face].V[facePart];
 
@@ -250,12 +261,14 @@ namespace Max2Babylon
                 vertex.UV2 = Loader.Global.Point2.Create(mesh.MapVerts(2)[tvertexIndex].X, mesh.MapVerts(2)[tvertexIndex].Y);
             }
 
-
-            var index = vertices.IndexOf(vertex);
-
-            if (index > -1)
+            if (!noOptimize)
             {
-                return index;
+                var index = vertices.IndexOf(vertex);
+
+                if (index > -1)
+                {
+                    return index;
+                }
             }
 
             vertices.Add(vertex);

+ 13 - 5
Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.cs

@@ -1,11 +1,14 @@
 using System;
 using System.Collections.Generic;
+using System.Globalization;
 using System.IO;
 using System.Runtime.InteropServices;
 using System.Runtime.Serialization.Json;
+using System.Text;
 using Autodesk.Max;
 using BabylonExport.Entities;
 using MaxSharp;
+using Newtonsoft.Json;
 using Animatable = MaxSharp.Animatable;
 
 namespace Max2Babylon
@@ -27,7 +30,7 @@ namespace Max2Babylon
             }
         }
 
-        void RaiseError(string error, bool asChild = false)
+        void RaiseError(string error, bool asChild = true)
         {
             if (OnError != null)
             {
@@ -141,14 +144,19 @@ namespace Max2Babylon
 
             // Output
             babylonScene.Prepare(false);
-            using (var outputStream = new FileStream(outputFile, FileMode.Create, FileAccess.Write))
+            var jsonSerializer = JsonSerializer.Create();
+            var sb = new StringBuilder();
+            var sw = new StringWriter(sb, CultureInfo.InvariantCulture);
+            using (var jsonWriter = new JsonTextWriterOptimized(sw))
             {
-                var ser = new DataContractJsonSerializer(typeof(BabylonScene));
-                ser.WriteObject(outputStream, babylonScene);
+                jsonWriter.Formatting = Formatting.None;
+                jsonSerializer.Serialize(jsonWriter, babylonScene);
             }
+            File.WriteAllText(outputFile, sb.ToString());
+
             ReportProgressChanged(100);
 
             RaiseMessage("Exportation done");
-        }             
+        }
     }
 }

+ 15 - 1
Exporters/3ds Max/Max2Babylon/Forms/ObjectPropertiesForm.Designer.cs

@@ -34,6 +34,7 @@
             this.butOK = new System.Windows.Forms.Button();
             this.groupBox2 = new System.Windows.Forms.GroupBox();
             this.chkPickable = new System.Windows.Forms.CheckBox();
+            this.chkNoOptimize = new System.Windows.Forms.CheckBox();
             this.groupBox1.SuspendLayout();
             this.groupBox2.SuspendLayout();
             this.SuspendLayout();
@@ -87,11 +88,12 @@
             // 
             // groupBox2
             // 
+            this.groupBox2.Controls.Add(this.chkNoOptimize);
             this.groupBox2.Controls.Add(this.chkPickable);
             this.groupBox2.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
             this.groupBox2.Location = new System.Drawing.Point(12, 77);
             this.groupBox2.Name = "groupBox2";
-            this.groupBox2.Size = new System.Drawing.Size(319, 59);
+            this.groupBox2.Size = new System.Drawing.Size(319, 113);
             this.groupBox2.TabIndex = 2;
             this.groupBox2.TabStop = false;
             this.groupBox2.Text = "Misc.";
@@ -107,6 +109,17 @@
             this.chkPickable.ThreeState = true;
             this.chkPickable.UseVisualStyleBackColor = true;
             // 
+            // chkNoOptimize
+            // 
+            this.chkNoOptimize.AutoSize = true;
+            this.chkNoOptimize.Location = new System.Drawing.Point(21, 51);
+            this.chkNoOptimize.Name = "chkNoOptimize";
+            this.chkNoOptimize.Size = new System.Drawing.Size(165, 17);
+            this.chkNoOptimize.TabIndex = 1;
+            this.chkNoOptimize.Text = "Do not try to optimize vertices";
+            this.chkNoOptimize.ThreeState = true;
+            this.chkNoOptimize.UseVisualStyleBackColor = true;
+            // 
             // ObjectPropertiesForm
             // 
             this.AcceptButton = this.butOK;
@@ -139,5 +152,6 @@
         private System.Windows.Forms.Button butOK;
         private System.Windows.Forms.GroupBox groupBox2;
         private System.Windows.Forms.CheckBox chkPickable;
+        private System.Windows.Forms.CheckBox chkNoOptimize;
     }
 }

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

@@ -17,7 +17,8 @@ namespace Max2Babylon
         private void butOK_Click(object sender, EventArgs e)
         {
             Tools.UpdateCheckBox(chkCollisions, objects, "babylonjs_checkcollisions");
-            Tools.UpdateCheckBox(chkPickable, objects, "babylonjs_checkpickable");            
+            Tools.UpdateCheckBox(chkPickable, objects, "babylonjs_checkpickable");   
+            Tools.UpdateCheckBox(chkNoOptimize, objects, "babylonjs_nooptimize");
         }
 
         private void ObjectPropertiesForm_Load(object sender, EventArgs e)
@@ -34,6 +35,7 @@ namespace Max2Babylon
 
             Tools.PrepareCheckBox(chkCollisions, objects, "babylonjs_checkcollisions");
             Tools.PrepareCheckBox(chkPickable, objects, "babylonjs_checkpickable");
+            Tools.PrepareCheckBox(chkNoOptimize, objects, "babylonjs_nooptimize");
         }
     }
 }

+ 19 - 0
Exporters/3ds Max/Max2Babylon/JsonTextWriterOptimized.cs

@@ -0,0 +1,19 @@
+using System;
+using System.IO;
+using Newtonsoft.Json;
+
+namespace Max2Babylon
+{
+    class JsonTextWriterOptimized : JsonTextWriter
+    {
+        public JsonTextWriterOptimized(TextWriter textWriter)
+            : base(textWriter)
+        {
+        }
+        public override void WriteValue(float value)
+        {
+            value = (float)Math.Round(value, 4);
+            base.WriteValue(value);
+        }
+    }
+}

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

@@ -5,11 +5,33 @@ using System.Windows.Forms;
 using Autodesk.Max;
 using Autodesk.Max.IMXSDebugger;
 using MaxSharp;
+using SharpDX;
+using Color = MaxSharp.Color;
 
 namespace Max2Babylon
 {
     public static class Tools
     {
+        public static float[] ToArray(this IMatrix3 value)
+        {
+            var row0 = value.GetRow(0).ToArraySwitched();
+            var row1 = value.GetRow(1).ToArraySwitched();
+            var row2 = value.GetRow(2).ToArraySwitched();
+            var row3 = value.GetRow(3).ToArraySwitched();
+
+            return new[]
+            {
+                row0[0], row0[1], row0[2], 0,
+                row2[0], row2[1], row2[2], 0,
+                row1[0], row1[1], row1[2], 0,
+                row3[0], row3[1], row3[2], 1
+            };
+        }
+
+        public static Quaternion ToQuat(this IQuat value)
+        {
+            return new Quaternion(value.X, value.Z, value.Y, value.W );
+        }
         public static float[] ToArray(this IQuat value)
         {
             return new[] { value.X, value.Z, value.Y, value.W };

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 12 - 12
babylon.1.12-beta.js