|
@@ -1,5 +1,5 @@
|
|
|
-/// <reference path="../References/babylon.2.1.d.ts"/>
|
|
|
-/// <reference path="../References/waa.d.ts"/>
|
|
|
+
|
|
|
+
|
|
|
module BABYLON {
|
|
|
|
|
|
/**
|
|
@@ -8,7 +8,7 @@ module BABYLON {
|
|
|
export class MTLFileLoader {
|
|
|
|
|
|
// 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
|
|
@@ -20,15 +20,15 @@ module BABYLON {
|
|
|
* @param data
|
|
|
* @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
|
|
|
var lines = data.split('\n');
|
|
|
//Space char
|
|
|
var delimiter_pattern = /\s+/;
|
|
|
//Array with RGB colors
|
|
|
- var color : number[];
|
|
|
+ var color: number[];
|
|
|
//New material
|
|
|
- var material : BABYLON.StandardMaterial;
|
|
|
+ var material: BABYLON.StandardMaterial;
|
|
|
|
|
|
//Look at each line
|
|
|
for (var i = 0; i < lines.length; i++) {
|
|
@@ -46,14 +46,14 @@ module BABYLON {
|
|
|
key = key.toLowerCase();
|
|
|
|
|
|
//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();
|
|
|
|
|
|
//This mtl keyword will create the new material
|
|
|
if (key === "newmtl") {
|
|
|
//Check if it is the first material.
|
|
|
// Materials specifications are described after this keyword.
|
|
|
- if (material){
|
|
|
+ if (material) {
|
|
|
//Add the previous material in the material array.
|
|
|
this.materials.push(material);
|
|
|
}
|
|
@@ -64,7 +64,7 @@ module BABYLON {
|
|
|
// Diffuse color (color under white light) using RGB values
|
|
|
|
|
|
//value = "r g b"
|
|
|
- color = <number[]> value.split(delimiter_pattern, 3);
|
|
|
+ color = <number[]>value.split(delimiter_pattern, 3);
|
|
|
//color = [r,g,b]
|
|
|
//Set tghe color into the material
|
|
|
material.diffuseColor = BABYLON.Color3.FromArray(color);
|
|
@@ -72,7 +72,7 @@ module BABYLON {
|
|
|
// Ambient color (color under shadow) using RGB values
|
|
|
|
|
|
//value = "r g b"
|
|
|
- color = <number[]> value.split(delimiter_pattern, 3);
|
|
|
+ color = <number[]>value.split(delimiter_pattern, 3);
|
|
|
//color = [r,g,b]
|
|
|
//Set tghe color into the material
|
|
|
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
|
|
|
|
|
|
//value = "r g b"
|
|
|
- color = <number[]> value.split(delimiter_pattern, 3);
|
|
|
+ color = <number[]>value.split(delimiter_pattern, 3);
|
|
|
//color = [r,g,b]
|
|
|
//Set the color into the material
|
|
|
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
|
|
|
* @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
|
|
|
var request = new XMLHttpRequest();
|
|
|
//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
|
|
|
request.open('GET', pathOfFile, false);
|
|
|
//Check the server status
|
|
@@ -213,7 +213,7 @@ module BABYLON {
|
|
|
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
|
|
|
var loadedMeshes = this._parseSolid(meshesNames, scene, data, rootUrl);
|
|
|
//Push each mesh from OBJ file into the variable mesh of this function
|
|
@@ -242,51 +242,44 @@ module BABYLON {
|
|
|
* @returns Array<AbstractMesh>
|
|
|
* @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.
|
|
|
* 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
|
|
|
- * @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 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) => {
|
|
|
//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
|
|
|
- var _index = isInArray(tuplePosNorm, tuple);
|
|
|
+ var _index = isInArray(tuplePosNorm, _tuple);
|
|
|
+
|
|
|
//If it not exists
|
|
|
if (_index == -1) {
|
|
|
//Add an new indice.
|
|
@@ -322,7 +318,8 @@ module BABYLON {
|
|
|
//Each element is a BABYLON.Vector3(x,y,z)
|
|
|
wrappedNormalsForBabylon.push(normalsVectorFromOBJ);
|
|
|
//Add the tuple in the comparison list
|
|
|
- tuplePosNorm.push(tuple);
|
|
|
+ tuplePosNorm[indicePositionFromObj].normals.push(indiceNormalFromObj);
|
|
|
+ tuplePosNorm[indicePositionFromObj].idx.push(curPositionInIndices++);
|
|
|
} else {
|
|
|
//The tuple already exists
|
|
|
//Add the index of the already existing tuple
|
|
@@ -336,11 +333,11 @@ module BABYLON {
|
|
|
*/
|
|
|
var unwrapData = () => {
|
|
|
//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
|
|
|
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) => {
|
|
|
//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
|
|
|
- triangles.push(face[0], face[v], face[v+1]);
|
|
|
+ triangles.push(face[0], face[v], face[v + 1]);
|
|
|
//Incrementation for recursion
|
|
|
- v +=1;
|
|
|
+ v += 1;
|
|
|
//Recursion
|
|
|
getTriangles(face, v);
|
|
|
}
|
|
@@ -409,7 +406,7 @@ module BABYLON {
|
|
|
|
|
|
/**
|
|
|
* 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 v
|
|
|
*/
|
|
@@ -480,7 +477,7 @@ module BABYLON {
|
|
|
* @param face
|
|
|
* @param v
|
|
|
*/
|
|
|
- var setDataForCurrentFaceWithPattern4 = (face: Array<string>, v: number) =>{
|
|
|
+ var setDataForCurrentFaceWithPattern4 = (face: Array<string>, v: number) => {
|
|
|
getTriangles(face, v);
|
|
|
|
|
|
for (var k = 0; k < triangles.length; k++) {
|
|
@@ -577,7 +574,7 @@ module BABYLON {
|
|
|
var vectUV = new BABYLON.Vector2(
|
|
|
parseFloat(result[1]),
|
|
|
parseFloat(result[2])
|
|
|
- );
|
|
|
+ );
|
|
|
//Add the Vector in the list of uvs
|
|
|
uvs.push(vectUV);
|
|
|
|
|
@@ -626,7 +623,7 @@ module BABYLON {
|
|
|
} else if (this.group.test(line) || this.obj.test(line)) {
|
|
|
//Create a new mesh corresponding to the name of the group.
|
|
|
//Definition of the mesh
|
|
|
- var objMeshName = line.substring(2).trim();
|
|
|
+ var objMeshName = line.substring(2).trim();
|
|
|
var objMesh: {
|
|
|
name: string;
|
|
|
indices: Array<number>;
|
|
@@ -636,14 +633,14 @@ module BABYLON {
|
|
|
materialName: string;
|
|
|
} =
|
|
|
//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();
|
|
|
|
|
|
//Push the last mesh created with only the name
|
|
@@ -664,7 +661,7 @@ module BABYLON {
|
|
|
//Set the data for the previous mesh
|
|
|
addPreviousObjMesh();
|
|
|
//Create a new mesh
|
|
|
- var objMesh:{
|
|
|
+ var objMesh: {
|
|
|
name: string;
|
|
|
indices: Array<number>;
|
|
|
positions: Array<number>;
|
|
@@ -673,15 +670,15 @@ module BABYLON {
|
|
|
materialName: string;
|
|
|
} =
|
|
|
//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
|
|
|
meshesFromObj.push(objMesh);
|
|
|
}
|
|
@@ -789,10 +786,10 @@ module BABYLON {
|
|
|
}
|
|
|
//load the materials
|
|
|
//Check if we have a file to load
|
|
|
- if (fileToLoad!== "") {
|
|
|
+ if (fileToLoad !== "") {
|
|
|
//Load the file synchronously
|
|
|
this._loadMTL(fileToLoad, rootUrl, function (dataLoaded) {
|
|
|
- //Create materials thanks MTLLoader function
|
|
|
+ //Create materials thanks MTLLoader function
|
|
|
materialsFromMTLFile.parseMTL(scene, dataLoaded, rootUrl);
|
|
|
//Look at each material loaded in the mtl file
|
|
|
for (var n = 0; n < materialsFromMTLFile.materials.length; n++) {
|
|
@@ -813,7 +810,7 @@ module BABYLON {
|
|
|
//If the material is not needed, remove it
|
|
|
materialsFromMTLFile.materials[n].dispose();
|
|
|
} 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
|
|
|
babylonMeshesArray[_indices[o]].material = materialsFromMTLFile.materials[n];
|
|
|
}
|