فهرست منبع

Optimizing the setData function of the OBJLoader

Now using direct array access to find duplicated indices.
Raanan Weber 10 سال پیش
والد
کامیت
c84433b7a6
2فایلهای تغییر یافته به همراه115 افزوده شده و 109 حذف شده
  1. 32 23
      loaders/OBJ/babylon.objFileLoader.js
  2. 83 86
      loaders/OBJ/babylon.objFileLoader.ts

+ 32 - 23
loaders/OBJ/babylon.objFileLoader.js

@@ -1,5 +1,3 @@
-/// <reference path="../References/babylon.2.1.d.ts"/>
-/// <reference path="../References/waa.d.ts"/>
 var BABYLON;
 var BABYLON;
 (function (BABYLON) {
 (function (BABYLON) {
     /**
     /**
@@ -28,6 +26,7 @@ var BABYLON;
                 var color;
                 var color;
                 //New material
                 //New material
                 var material;
                 var material;
+                //Look at each line
                 for (var i = 0; i < lines.length; i++) {
                 for (var i = 0; i < lines.length; i++) {
                     var line = lines[i];
                     var line = lines[i];
                     line = line.trim();
                     line = line.trim();
@@ -238,6 +237,7 @@ var BABYLON;
             var wrappedUvsForBabylon = []; //Array with all value of uvs to match with the indices
             var wrappedUvsForBabylon = []; //Array with all value of uvs to match with the indices
             var wrappedNormalsForBabylon = []; //Array with all value of normals to match with the indices
             var wrappedNormalsForBabylon = []; //Array with all value of normals to match with the indices
             var tuplePosNorm = []; //Create a tuple with indice of Position, Normal, UV  [pos, norm, uvs]
             var tuplePosNorm = []; //Create a tuple with indice of Position, Normal, UV  [pos, norm, uvs]
+            var curPositionInIndices = 0;
             var hasMeshes = false; //Meshes are defined in the file
             var hasMeshes = false; //Meshes are defined in the file
             var unwrappedPositionsForBabylon = []; //Value of positionForBabylon w/o Vector3() [x,y,z]
             var unwrappedPositionsForBabylon = []; //Value of positionForBabylon w/o Vector3() [x,y,z]
             var unwrappedNormalsForBabylon = []; //Value of normalsForBabylon w/o Vector3()  [x,y,z]
             var unwrappedNormalsForBabylon = []; //Value of normalsForBabylon w/o Vector3()  [x,y,z]
@@ -254,22 +254,15 @@ var BABYLON;
              * This function is called to check if a couple of data already exists in an array.
              * This function is called to check if a couple of data already exists in an array.
              *
              *
              * If found, returns the index of the founded tuple index. Returns -1 if not found
              * If found, returns the index of the founded tuple index. Returns -1 if not found
-             * @param arr Array<BABYLON.Vector2>
-             * @param obj BABYLON.Vector2
-             * @returns {number}
+             * @param arr Array<{ normals: Array<number>, idx: Array<number> }>
+             * @param obj Array<number>
+             * @returns {boolean}
              */
              */
             var isInArray = function (arr, obj) {
             var isInArray = function (arr, obj) {
-                //Default value : not found
-                var res = -1;
-                for (var i = 0; i < arr.length; i++) {
-                    var element = arr[i];
-                    //Comparison of each element of the tuple
-                    if (element.x === obj.x && element.y === obj.y) {
-                        res = i;
-                    }
-                }
-                //Return the indice of the founded element
-                return res;
+                if (!arr[obj[0]])
+                    arr[obj[0]] = { normals: [], idx: [] };
+                var idx = arr[obj[0]].normals.indexOf(obj[1]);
+                return idx === -1 ? idx : arr[obj[0]].idx[idx];
             };
             };
             /**
             /**
              * This function set the data for each triangle.
              * This function set the data for each triangle.
@@ -283,11 +276,13 @@ var BABYLON;
              * @param textureVectorFromOBJ Vector3 The value of uvs
              * @param textureVectorFromOBJ Vector3 The value of uvs
              * @param normalsVectorFromOBJ Vector3 The value of normals at index objNormale
              * @param normalsVectorFromOBJ Vector3 The value of normals at index objNormale
              */
              */
+            var _tuple = [];
             var setData = function (indicePositionFromObj, indiceNormalFromObj, positionVectorFromOBJ, textureVectorFromOBJ, normalsVectorFromOBJ) {
             var setData = function (indicePositionFromObj, indiceNormalFromObj, positionVectorFromOBJ, textureVectorFromOBJ, normalsVectorFromOBJ) {
                 //Create a new tuple composed with the indice of position and normal
                 //Create a new tuple composed with the indice of position and normal
-                var tuple = new BABYLON.Vector2(indicePositionFromObj, indiceNormalFromObj);
+                _tuple[0] = indicePositionFromObj;
+                _tuple[1] = indiceNormalFromObj;
                 //Check if this tuple already exists in the list of tuples
                 //Check if this tuple already exists in the list of tuples
-                var _index = isInArray(tuplePosNorm, tuple);
+                var _index = isInArray(tuplePosNorm, _tuple);
                 //If it not exists
                 //If it not exists
                 if (_index == -1) {
                 if (_index == -1) {
                     //Add an new indice.
                     //Add an new indice.
@@ -304,7 +299,8 @@ var BABYLON;
                     //Each element is a BABYLON.Vector3(x,y,z)
                     //Each element is a BABYLON.Vector3(x,y,z)
                     wrappedNormalsForBabylon.push(normalsVectorFromOBJ);
                     wrappedNormalsForBabylon.push(normalsVectorFromOBJ);
                     //Add the tuple in the comparison list
                     //Add the tuple in the comparison list
-                    tuplePosNorm.push(tuple);
+                    tuplePosNorm[indicePositionFromObj].normals.push(indiceNormalFromObj);
+                    tuplePosNorm[indicePositionFromObj].idx.push(curPositionInIndices++);
                 }
                 }
                 else {
                 else {
                     //The tuple already exists
                     //The tuple already exists
@@ -317,6 +313,7 @@ var BABYLON;
              * Transform BABYLON.Vector() object onto 3 digits in an array
              * Transform BABYLON.Vector() object onto 3 digits in an array
              */
              */
             var unwrapData = function () {
             var unwrapData = function () {
+                //Every array has the same length
                 for (var l = 0; l < wrappedPositionForBabylon.length; l++) {
                 for (var l = 0; l < wrappedPositionForBabylon.length; l++) {
                     //Push the x, y, z values of each element in the unwrapped array
                     //Push the x, y, z values of each element in the unwrapped array
                     unwrappedPositionsForBabylon.push(wrappedPositionForBabylon[l].x, wrappedPositionForBabylon[l].y, wrappedPositionForBabylon[l].z);
                     unwrappedPositionsForBabylon.push(wrappedPositionForBabylon[l].x, wrappedPositionForBabylon[l].y, wrappedPositionForBabylon[l].z);
@@ -362,6 +359,8 @@ var BABYLON;
             var setDataForCurrentFaceWithPattern1 = function (face, v) {
             var setDataForCurrentFaceWithPattern1 = function (face, v) {
                 //Get the indices of triangles for each polygon
                 //Get the indices of triangles for each polygon
                 getTriangles(face, v);
                 getTriangles(face, v);
+                //For each element in the triangles array.
+                //This var could contains 1 to an infinity of triangles
                 for (var k = 0; k < triangles.length; k++) {
                 for (var k = 0; k < triangles.length; k++) {
                     // Set position indice
                     // Set position indice
                     var indicePositionFromObj = parseInt(triangles[k]) - 1;
                     var indicePositionFromObj = parseInt(triangles[k]) - 1;
@@ -381,7 +380,7 @@ var BABYLON;
             };
             };
             /**
             /**
              * Create triangles and push the data for each polygon for the pattern 2
              * Create triangles and push the data for each polygon for the pattern 2
-             * In this pattern we get vertice positions and uvs
+             * In this pattern we get vertice positions and uvsu
              * @param face
              * @param face
              * @param v
              * @param v
              */
              */
@@ -488,6 +487,7 @@ var BABYLON;
             //Main function
             //Main function
             //Split the file into lines
             //Split the file into lines
             var lines = data.split('\n');
             var lines = data.split('\n');
+            //Look at each line
             for (var i = 0; i < lines.length; i++) {
             for (var i = 0; i < lines.length; i++) {
                 var line = lines[i];
                 var line = lines[i];
                 line = line.trim();
                 line = line.trim();
@@ -556,7 +556,9 @@ var BABYLON;
                     //Create a new mesh corresponding to the name of the group.
                     //Create a new mesh corresponding to the name of the group.
                     //Definition of the mesh
                     //Definition of the mesh
                     var objMeshName = line.substring(2).trim();
                     var objMeshName = line.substring(2).trim();
-                    var objMesh = {
+                    var objMesh = 
+                    //Set the name of the current obj mesh
+                    {
                         name: objMeshName,
                         name: objMeshName,
                         indices: undefined,
                         indices: undefined,
                         positions: undefined,
                         positions: undefined,
@@ -580,7 +582,9 @@ var BABYLON;
                         //Set the data for the previous mesh
                         //Set the data for the previous mesh
                         addPreviousObjMesh();
                         addPreviousObjMesh();
                         //Create a new mesh
                         //Create a new mesh
-                        var objMesh = {
+                        var objMesh = 
+                        //Set the name of the current obj mesh
+                        {
                             name: objMeshName + "_mm" + increment.toString(),
                             name: objMeshName + "_mm" + increment.toString(),
                             indices: undefined,
                             indices: undefined,
                             positions: undefined,
                             positions: undefined,
@@ -647,6 +651,7 @@ var BABYLON;
             var vertexData = new BABYLON.VertexData(); //The container for the values
             var vertexData = new BABYLON.VertexData(); //The container for the values
             var babylonMeshesArray = []; //The mesh for babylon
             var babylonMeshesArray = []; //The mesh for babylon
             var materialToUse = [];
             var materialToUse = [];
+            //Set data for each mesh
             for (var j = 0; j < meshesFromObj.length; j++) {
             for (var j = 0; j < meshesFromObj.length; j++) {
                 //check meshesNames (stlFileLoader)
                 //check meshesNames (stlFileLoader)
                 if (meshesNames && meshesFromObj[j].name) {
                 if (meshesNames && meshesFromObj[j].name) {
@@ -686,11 +691,15 @@ var BABYLON;
                 this._loadMTL(fileToLoad, rootUrl, function (dataLoaded) {
                 this._loadMTL(fileToLoad, rootUrl, function (dataLoaded) {
                     //Create materials thanks MTLLoader function
                     //Create materials thanks MTLLoader function
                     materialsFromMTLFile.parseMTL(scene, dataLoaded, rootUrl);
                     materialsFromMTLFile.parseMTL(scene, dataLoaded, rootUrl);
+                    //Look at each material loaded in the mtl file
                     for (var n = 0; n < materialsFromMTLFile.materials.length; n++) {
                     for (var n = 0; n < materialsFromMTLFile.materials.length; n++) {
                         //Three variables to get all meshes with the same material
                         //Three variables to get all meshes with the same material
                         var startIndex = 0;
                         var startIndex = 0;
                         var _indices = [];
                         var _indices = [];
                         var _index;
                         var _index;
+                        //The material from MTL file is used in the meshes loaded
+                        //Push the indice in an array
+                        //Check if the material is not used for another mesh
                         while ((_index = materialToUse.indexOf(materialsFromMTLFile.materials[n].name, startIndex)) > -1) {
                         while ((_index = materialToUse.indexOf(materialsFromMTLFile.materials[n].name, startIndex)) > -1) {
                             _indices.push(_index);
                             _indices.push(_index);
                             startIndex = _index + 1;
                             startIndex = _index + 1;
@@ -717,4 +726,4 @@ var BABYLON;
     BABYLON.OBJFileLoader = OBJFileLoader;
     BABYLON.OBJFileLoader = OBJFileLoader;
     //Add this loader into the register plugin
     //Add this loader into the register plugin
     BABYLON.SceneLoader.RegisterPlugin(new OBJFileLoader());
     BABYLON.SceneLoader.RegisterPlugin(new OBJFileLoader());
-})(BABYLON || (BABYLON = {}));
+})(BABYLON || (BABYLON = {}));

+ 83 - 86
loaders/OBJ/babylon.objFileLoader.ts

@@ -1,5 +1,5 @@
-/// <reference path="../References/babylon.2.1.d.ts"/>
-/// <reference path="../References/waa.d.ts"/>
+
+
 module BABYLON {
 module BABYLON {
 
 
     /**
     /**
@@ -8,7 +8,7 @@ module BABYLON {
     export class MTLFileLoader {
     export class MTLFileLoader {
 
 
         // All material loaded from the mtl will be set here
         // All material loaded from the mtl will be set here
-        public materials : BABYLON.StandardMaterial[] = [];
+        public materials: BABYLON.StandardMaterial[] = [];
 
 
         /**
         /**
          * This function will read the mtl file and create each material described inside
          * This function will read the mtl file and create each material described inside
@@ -20,15 +20,15 @@ module BABYLON {
          * @param data
          * @param data
          * @param rootUrl
          * @param rootUrl
          */
          */
-        public parseMTL = function(scene:BABYLON.Scene, data:string, rootUrl:string) {
+        public parseMTL = function (scene: BABYLON.Scene, data: string, rootUrl: string) {
             //Split the lines from the file
             //Split the lines from the file
             var lines = data.split('\n');
             var lines = data.split('\n');
             //Space char
             //Space char
             var delimiter_pattern = /\s+/;
             var delimiter_pattern = /\s+/;
             //Array with RGB colors
             //Array with RGB colors
-            var color : number[];
+            var color: number[];
             //New material
             //New material
-            var material : BABYLON.StandardMaterial;
+            var material: BABYLON.StandardMaterial;
 
 
             //Look at each line
             //Look at each line
             for (var i = 0; i < lines.length; i++) {
             for (var i = 0; i < lines.length; i++) {
@@ -46,14 +46,14 @@ module BABYLON {
                 key = key.toLowerCase();
                 key = key.toLowerCase();
 
 
                 //Get the data following the key
                 //Get the data following the key
-                var value : any = (pos >= 0) ? line.substring(pos + 1) : "";
+                var value: any = (pos >= 0) ? line.substring(pos + 1) : "";
                 value = value.trim();
                 value = value.trim();
 
 
                 //This mtl keyword will create the new material
                 //This mtl keyword will create the new material
                 if (key === "newmtl") {
                 if (key === "newmtl") {
                     //Check if it is the first material.
                     //Check if it is the first material.
                     // Materials specifications are described after this keyword.
                     // Materials specifications are described after this keyword.
-                    if (material){
+                    if (material) {
                         //Add the previous material in the material array.
                         //Add the previous material in the material array.
                         this.materials.push(material);
                         this.materials.push(material);
                     }
                     }
@@ -64,7 +64,7 @@ module BABYLON {
                     // Diffuse color (color under white light) using RGB values
                     // Diffuse color (color under white light) using RGB values
 
 
                     //value  = "r g b"
                     //value  = "r g b"
-                    color = <number[]> value.split(delimiter_pattern, 3);
+                    color = <number[]>value.split(delimiter_pattern, 3);
                     //color = [r,g,b]
                     //color = [r,g,b]
                     //Set tghe color into the material
                     //Set tghe color into the material
                     material.diffuseColor = BABYLON.Color3.FromArray(color);
                     material.diffuseColor = BABYLON.Color3.FromArray(color);
@@ -72,7 +72,7 @@ module BABYLON {
                     // Ambient color (color under shadow) using RGB values
                     // Ambient color (color under shadow) using RGB values
 
 
                     //value = "r g b"
                     //value = "r g b"
-                    color = <number[]> value.split(delimiter_pattern, 3);
+                    color = <number[]>value.split(delimiter_pattern, 3);
                     //color = [r,g,b]
                     //color = [r,g,b]
                     //Set tghe color into the material
                     //Set tghe color into the material
                     material.ambientColor = BABYLON.Color3.FromArray(color);
                     material.ambientColor = BABYLON.Color3.FromArray(color);
@@ -80,7 +80,7 @@ module BABYLON {
                     // Specular color (color when light is reflected from shiny surface) using RGB values
                     // Specular color (color when light is reflected from shiny surface) using RGB values
 
 
                     //value = "r g b"
                     //value = "r g b"
-                    color = <number[]> value.split(delimiter_pattern, 3);
+                    color = <number[]>value.split(delimiter_pattern, 3);
                     //color = [r,g,b]
                     //color = [r,g,b]
                     //Set the color into the material
                     //Set the color into the material
                     material.specularColor = BABYLON.Color3.FromArray(color);
                     material.specularColor = BABYLON.Color3.FromArray(color);
@@ -190,11 +190,11 @@ module BABYLON {
          * @param onSuccess Callback function to be called when the MTL file is loaded
          * @param onSuccess Callback function to be called when the MTL file is loaded
          * @private
          * @private
          */
          */
-        private _loadMTL(url:string, rootUrl:string,  onSuccess:(response:string) => any) {
+        private _loadMTL(url: string, rootUrl: string, onSuccess: (response: string) => any) {
             //XMLHTTP object to load the file
             //XMLHTTP object to load the file
             var request = new XMLHttpRequest();
             var request = new XMLHttpRequest();
             //The complete path to the mtl file
             //The complete path to the mtl file
-            var pathOfFile = BABYLON.Tools.BaseUrl+ rootUrl + url;
+            var pathOfFile = BABYLON.Tools.BaseUrl + rootUrl + url;
             //Get the file synchronously
             //Get the file synchronously
             request.open('GET', pathOfFile, false);
             request.open('GET', pathOfFile, false);
             //Check the server status
             //Check the server status
@@ -213,7 +213,7 @@ module BABYLON {
             request.send(null);
             request.send(null);
         }
         }
 
 
-        public importMesh(meshesNames: any, scene: Scene, data: any, rootUrl: string, meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]):  boolean {
+        public importMesh(meshesNames: any, scene: Scene, data: any, rootUrl: string, meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]): boolean {
             //get the meshes from OBJ file
             //get the meshes from OBJ file
             var loadedMeshes = this._parseSolid(meshesNames, scene, data, rootUrl);
             var loadedMeshes = this._parseSolid(meshesNames, scene, data, rootUrl);
             //Push each mesh from OBJ file into the variable mesh of this function
             //Push each mesh from OBJ file into the variable mesh of this function
@@ -242,51 +242,44 @@ module BABYLON {
          * @returns Array<AbstractMesh>
          * @returns Array<AbstractMesh>
          * @private
          * @private
          */
          */
-        private _parseSolid(meshesNames: any, scene:BABYLON.Scene, data:string, rootUrl:string): Array<AbstractMesh> {
-
-            var positions                       : Array<BABYLON.Vector3>    = [];      //values for the positions of vertices
-            var normals                         : Array<BABYLON.Vector3>    = [];      //Values for the normals
-            var uvs                             : Array<BABYLON.Vector2>    = [];      //Values for the textures
-            var meshesFromObj                   : Array<any>                = [];      //[mesh] Contains all the obj meshes
-            var handledMesh                     : any                           ;      //The current mesh of meshes array
-            var indicesForBabylon               : Array<number>             = [];      //The list of indices for VertexData
-            var wrappedPositionForBabylon       : Array<BABYLON.Vector3>    = [];      //The list of position in vectors
-            var wrappedUvsForBabylon            : Array<BABYLON.Vector2>    = [];      //Array with all value of uvs to match with the indices
-            var wrappedNormalsForBabylon        : Array<BABYLON.Vector3>    = [];      //Array with all value of normals to match with the indices
-            var tuplePosNorm                    : Array<BABYLON.Vector2>    = [];      //Create a tuple with indice of Position, Normal, UV  [pos, norm, uvs]
-            var hasMeshes                       : Boolean                   = false;   //Meshes are defined in the file
-            var unwrappedPositionsForBabylon    : Array<number>             = [];      //Value of positionForBabylon w/o Vector3() [x,y,z]
-            var unwrappedNormalsForBabylon      : Array<number>             = [];      //Value of normalsForBabylon w/o Vector3()  [x,y,z]
-            var unwrappedUVForBabylon           : Array<number>             = [];      //Value of uvsForBabylon w/o Vector3()      [x,y,z]
-            var triangles                       : Array<string>             = [];      //Indices from new triangles coming from polygons
-            var materialNameFromObj             : string                    = "";      //The name of the current material
-            var fileToLoad                      : string                    = "";      //The name of the mtlFile to load
-            var materialsFromMTLFile            : MTLFileLoader             = new MTLFileLoader();
-            var objMeshName                     : string                    = "";      //The name of the current obj mesh
-            var increment                       : number                    =  1;      //Id for meshes created by the multimaterial
-            var isFirstMaterial                 : boolean                   = true;
+        private _parseSolid(meshesNames: any, scene: BABYLON.Scene, data: string, rootUrl: string): Array<AbstractMesh> {
+
+            var positions: Array<BABYLON.Vector3> = [];      //values for the positions of vertices
+            var normals: Array<BABYLON.Vector3> = [];      //Values for the normals
+            var uvs: Array<BABYLON.Vector2> = [];      //Values for the textures
+            var meshesFromObj: Array<any> = [];      //[mesh] Contains all the obj meshes
+            var handledMesh: any;      //The current mesh of meshes array
+            var indicesForBabylon: Array<number> = [];      //The list of indices for VertexData
+            var wrappedPositionForBabylon: Array<BABYLON.Vector3> = [];      //The list of position in vectors
+            var wrappedUvsForBabylon: Array<BABYLON.Vector2> = [];      //Array with all value of uvs to match with the indices
+            var wrappedNormalsForBabylon: Array<BABYLON.Vector3> = [];      //Array with all value of normals to match with the indices
+            var tuplePosNorm: Array<{ normals: Array<number>, idx: Array<number> }> = [];      //Create a tuple with indice of Position, Normal, UV  [pos, norm, uvs]
+            var curPositionInIndices = 0;
+            var hasMeshes: Boolean = false;   //Meshes are defined in the file
+            var unwrappedPositionsForBabylon: Array<number> = [];      //Value of positionForBabylon w/o Vector3() [x,y,z]
+            var unwrappedNormalsForBabylon: Array<number> = [];      //Value of normalsForBabylon w/o Vector3()  [x,y,z]
+            var unwrappedUVForBabylon: Array<number> = [];      //Value of uvsForBabylon w/o Vector3()      [x,y,z]
+            var triangles: Array<string> = [];      //Indices from new triangles coming from polygons
+            var materialNameFromObj: string = "";      //The name of the current material
+            var fileToLoad: string = "";      //The name of the mtlFile to load
+            var materialsFromMTLFile: MTLFileLoader = new MTLFileLoader();
+            var objMeshName: string = "";      //The name of the current obj mesh
+            var increment: number = 1;      //Id for meshes created by the multimaterial
+            var isFirstMaterial: boolean = true;
 
 
             /**
             /**
              * Search for obj in the given array.
              * Search for obj in the given array.
              * This function is called to check if a couple of data already exists in an array.
              * This function is called to check if a couple of data already exists in an array.
              *
              *
              * If found, returns the index of the founded tuple index. Returns -1 if not found
              * If found, returns the index of the founded tuple index. Returns -1 if not found
-             * @param arr Array<BABYLON.Vector2>
-             * @param obj BABYLON.Vector2
-             * @returns {number}
+             * @param arr Array<{ normals: Array<number>, idx: Array<number> }>
+             * @param obj Array<number>
+             * @returns {boolean}
              */
              */
-            var isInArray = (arr: Array<BABYLON.Vector2>, obj: BABYLON.Vector2) => {
-                //Default value : not found
-                var res = -1;
-                for (var i = 0; i<arr.length; i++) {
-                    var element = arr[i];
-                    //Comparison of each element of the tuple
-                    if (element.x === obj.x && element.y === obj.y){
-                        res = i;
-                    }
-                }
-                //Return the indice of the founded element
-                return res;
+            var isInArray = (arr: Array<{ normals: Array<number>, idx: Array<number> }>, obj: Array<number>) => {
+                if (!arr[obj[0]]) arr[obj[0]] = { normals: [], idx: [] };
+                var idx = arr[obj[0]].normals.indexOf(obj[1]);
+                return idx === -1 ? idx : arr[obj[0]].idx[idx];
             };
             };
 
 
             /**
             /**
@@ -301,11 +294,14 @@ module BABYLON {
              * @param textureVectorFromOBJ Vector3 The value of uvs
              * @param textureVectorFromOBJ Vector3 The value of uvs
              * @param normalsVectorFromOBJ Vector3 The value of normals at index objNormale
              * @param normalsVectorFromOBJ Vector3 The value of normals at index objNormale
              */
              */
+            var _tuple = []
             var setData = (indicePositionFromObj: number, indiceNormalFromObj: number, positionVectorFromOBJ: BABYLON.Vector3, textureVectorFromOBJ: BABYLON.Vector2, normalsVectorFromOBJ: BABYLON.Vector3) => {
             var setData = (indicePositionFromObj: number, indiceNormalFromObj: number, positionVectorFromOBJ: BABYLON.Vector3, textureVectorFromOBJ: BABYLON.Vector2, normalsVectorFromOBJ: BABYLON.Vector3) => {
                 //Create a new tuple composed with the indice of position and normal
                 //Create a new tuple composed with the indice of position and normal
-                var tuple = new BABYLON.Vector2(indicePositionFromObj, indiceNormalFromObj);
+                _tuple[0] = indicePositionFromObj;
+                _tuple[1] = indiceNormalFromObj;
                 //Check if this tuple already exists in the list of tuples
                 //Check if this tuple already exists in the list of tuples
-                var _index = isInArray(tuplePosNorm, tuple);
+                var _index = isInArray(tuplePosNorm, _tuple);
+
                 //If it not exists
                 //If it not exists
                 if (_index == -1) {
                 if (_index == -1) {
                     //Add an new indice.
                     //Add an new indice.
@@ -322,7 +318,8 @@ module BABYLON {
                     //Each element is a BABYLON.Vector3(x,y,z)
                     //Each element is a BABYLON.Vector3(x,y,z)
                     wrappedNormalsForBabylon.push(normalsVectorFromOBJ);
                     wrappedNormalsForBabylon.push(normalsVectorFromOBJ);
                     //Add the tuple in the comparison list
                     //Add the tuple in the comparison list
-                    tuplePosNorm.push(tuple);
+                    tuplePosNorm[indicePositionFromObj].normals.push(indiceNormalFromObj);
+                    tuplePosNorm[indicePositionFromObj].idx.push(curPositionInIndices++);
                 } else {
                 } else {
                     //The tuple already exists
                     //The tuple already exists
                     //Add the index of the already existing tuple
                     //Add the index of the already existing tuple
@@ -336,11 +333,11 @@ module BABYLON {
              */
              */
             var unwrapData = () => {
             var unwrapData = () => {
                 //Every array has the same length
                 //Every array has the same length
-                for (var l=0; l<wrappedPositionForBabylon.length; l++) {
+                for (var l = 0; l < wrappedPositionForBabylon.length; l++) {
                     //Push the x, y, z values of each element in the unwrapped array
                     //Push the x, y, z values of each element in the unwrapped array
                     unwrappedPositionsForBabylon.push(wrappedPositionForBabylon[l].x, wrappedPositionForBabylon[l].y, wrappedPositionForBabylon[l].z);
                     unwrappedPositionsForBabylon.push(wrappedPositionForBabylon[l].x, wrappedPositionForBabylon[l].y, wrappedPositionForBabylon[l].z);
-                    unwrappedNormalsForBabylon.push(wrappedNormalsForBabylon[l].x,wrappedNormalsForBabylon[l].y,wrappedNormalsForBabylon[l].z);
-                    unwrappedUVForBabylon.push(wrappedUvsForBabylon[l].x,wrappedUvsForBabylon[l].y); //z is an optional value not supported by BABYLON
+                    unwrappedNormalsForBabylon.push(wrappedNormalsForBabylon[l].x, wrappedNormalsForBabylon[l].y, wrappedNormalsForBabylon[l].z);
+                    unwrappedUVForBabylon.push(wrappedUvsForBabylon[l].x, wrappedUvsForBabylon[l].y); //z is an optional value not supported by BABYLON
                 }
                 }
             };
             };
 
 
@@ -359,11 +356,11 @@ module BABYLON {
              */
              */
             var getTriangles = (face: Array<string>, v: number) => {
             var getTriangles = (face: Array<string>, v: number) => {
                 //Work for each element of the array
                 //Work for each element of the array
-                if (v+1 < face.length){
+                if (v + 1 < face.length) {
                     //Add on the triangle variable the indexes to obtain triangles
                     //Add on the triangle variable the indexes to obtain triangles
-                    triangles.push(face[0], face[v], face[v+1]);
+                    triangles.push(face[0], face[v], face[v + 1]);
                     //Incrementation for recursion
                     //Incrementation for recursion
-                    v +=1;
+                    v += 1;
                     //Recursion
                     //Recursion
                     getTriangles(face, v);
                     getTriangles(face, v);
                 }
                 }
@@ -409,7 +406,7 @@ module BABYLON {
 
 
             /**
             /**
              * Create triangles and push the data for each polygon for the pattern 2
              * Create triangles and push the data for each polygon for the pattern 2
-             * In this pattern we get vertice positions and uvs
+             * In this pattern we get vertice positions and uvsu
              * @param face
              * @param face
              * @param v
              * @param v
              */
              */
@@ -480,7 +477,7 @@ module BABYLON {
              * @param face
              * @param face
              * @param v
              * @param v
              */
              */
-            var setDataForCurrentFaceWithPattern4 = (face: Array<string>, v: number) =>{
+            var setDataForCurrentFaceWithPattern4 = (face: Array<string>, v: number) => {
                 getTriangles(face, v);
                 getTriangles(face, v);
 
 
                 for (var k = 0; k < triangles.length; k++) {
                 for (var k = 0; k < triangles.length; k++) {
@@ -577,7 +574,7 @@ module BABYLON {
                     var vectUV = new BABYLON.Vector2(
                     var vectUV = new BABYLON.Vector2(
                         parseFloat(result[1]),
                         parseFloat(result[1]),
                         parseFloat(result[2])
                         parseFloat(result[2])
-                        );
+                    );
                     //Add the Vector in the list of uvs
                     //Add the Vector in the list of uvs
                     uvs.push(vectUV);
                     uvs.push(vectUV);
 
 
@@ -626,7 +623,7 @@ module BABYLON {
                 } else if (this.group.test(line) || this.obj.test(line)) {
                 } else if (this.group.test(line) || this.obj.test(line)) {
                     //Create a new mesh corresponding to the name of the group.
                     //Create a new mesh corresponding to the name of the group.
                     //Definition of the mesh
                     //Definition of the mesh
-                    var objMeshName =  line.substring(2).trim();
+                    var objMeshName = line.substring(2).trim();
                     var objMesh: {
                     var objMesh: {
                         name: string;
                         name: string;
                         indices: Array<number>;
                         indices: Array<number>;
@@ -636,14 +633,14 @@ module BABYLON {
                         materialName: string;
                         materialName: string;
                     } =
                     } =
                         //Set the name of the current obj mesh
                         //Set the name of the current obj mesh
-                    {
-                        name: objMeshName,
-                        indices: undefined,
-                        positions: undefined,
-                        normals: undefined,
-                        uvs: undefined,
-                        materialName: ""
-                    };
+                        {
+                            name: objMeshName,
+                            indices: undefined,
+                            positions: undefined,
+                            normals: undefined,
+                            uvs: undefined,
+                            materialName: ""
+                        };
                     addPreviousObjMesh();
                     addPreviousObjMesh();
 
 
                     //Push the last mesh created with only the name
                     //Push the last mesh created with only the name
@@ -664,7 +661,7 @@ module BABYLON {
                         //Set the data for the previous mesh
                         //Set the data for the previous mesh
                         addPreviousObjMesh();
                         addPreviousObjMesh();
                         //Create a new mesh
                         //Create a new mesh
-                        var objMesh:{
+                        var objMesh: {
                             name: string;
                             name: string;
                             indices: Array<number>;
                             indices: Array<number>;
                             positions: Array<number>;
                             positions: Array<number>;
@@ -673,15 +670,15 @@ module BABYLON {
                             materialName: string;
                             materialName: string;
                         } =
                         } =
                             //Set the name of the current obj mesh
                             //Set the name of the current obj mesh
-                        {
-                            name: objMeshName + "_mm" + increment.toString(),
-                            indices: undefined,
-                            positions: undefined,
-                            normals: undefined,
-                            uvs: undefined,
-                            materialName: materialNameFromObj
-                        };
-                        increment+=1;
+                            {
+                                name: objMeshName + "_mm" + increment.toString(),
+                                indices: undefined,
+                                positions: undefined,
+                                normals: undefined,
+                                uvs: undefined,
+                                materialName: materialNameFromObj
+                            };
+                        increment += 1;
                         //If meshes are already defined
                         //If meshes are already defined
                         meshesFromObj.push(objMesh);
                         meshesFromObj.push(objMesh);
                     }
                     }
@@ -789,10 +786,10 @@ module BABYLON {
             }
             }
             //load the materials
             //load the materials
             //Check if we have a file to load
             //Check if we have a file to load
-            if (fileToLoad!== "") {
+            if (fileToLoad !== "") {
                 //Load the file synchronously
                 //Load the file synchronously
                 this._loadMTL(fileToLoad, rootUrl, function (dataLoaded) {
                 this._loadMTL(fileToLoad, rootUrl, function (dataLoaded) {
-                      //Create materials thanks MTLLoader function
+                    //Create materials thanks MTLLoader function
                     materialsFromMTLFile.parseMTL(scene, dataLoaded, rootUrl);
                     materialsFromMTLFile.parseMTL(scene, dataLoaded, rootUrl);
                     //Look at each material loaded in the mtl file
                     //Look at each material loaded in the mtl file
                     for (var n = 0; n < materialsFromMTLFile.materials.length; n++) {
                     for (var n = 0; n < materialsFromMTLFile.materials.length; n++) {
@@ -813,7 +810,7 @@ module BABYLON {
                             //If the material is not needed, remove it
                             //If the material is not needed, remove it
                             materialsFromMTLFile.materials[n].dispose();
                             materialsFromMTLFile.materials[n].dispose();
                         } else {
                         } else {
-                            for (var o =0; o<_indices.length; o++) {
+                            for (var o = 0; o < _indices.length; o++) {
                                 //Apply the material to the BABYLON.Mesh for each mesh with the material
                                 //Apply the material to the BABYLON.Mesh for each mesh with the material
                                 babylonMeshesArray[_indices[o]].material = materialsFromMTLFile.materials[n];
                                 babylonMeshesArray[_indices[o]].material = materialsFromMTLFile.materials[n];
                             }
                             }