Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Using three.js in my Qt QML Program
QtWS25 Last Chance

Using three.js in my Qt QML Program

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
10 Posts 4 Posters 3.8k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • D Offline
    D Offline
    dillydill123
    wrote on last edited by
    #1

    Hi, I'd like to use three.js in my program to render .obj files. I've looked online at https://github.com/tronlec/three.js which describes a simple example that I can run on my own. I changed the program to have the following code for rendering an .obj file:

    var manager = new THREE.LoadingManager();
    loader = new THREE.OBJLoader(manager);
    loader.load('C:/Users/dillydill123/Documents/Qt/exampleProj/object.obj', function (object) {
    
        object.traverse(function (child) {
            if (child instanceof THREE.Mesh) {
                child.material.side = THREE.Material.DoubleSide;
            }
        });
    
        scene.add(object);
    });
    

    Unfortunately, when I run this code, I get type errors, saying that OBJLoader is not a type. It looks like the three.js library from https://github.com/tronlec/three.js/blob/master/build/three.js does not include OBJLoader. I've tried appending the source code of OBJLoader from https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/OBJLoader.js to the end of my three.js file in my QRC, but I get other type errors for FIleLoader. When I attempt to append that to three.js, I get other type errors.

    I also want to be able to use other extensions/modules from three.js, namely TrackBallControls. Unfortunately, I get other type errors when trying to append this to the end of my three.js.

    My questions are the following: How do I render a .obj file in Qt QML using three.js? And how can I easily add modules and extensions to three.js?

    I 1 Reply Last reply
    0
    • D dillydill123

      Hi, I'd like to use three.js in my program to render .obj files. I've looked online at https://github.com/tronlec/three.js which describes a simple example that I can run on my own. I changed the program to have the following code for rendering an .obj file:

      var manager = new THREE.LoadingManager();
      loader = new THREE.OBJLoader(manager);
      loader.load('C:/Users/dillydill123/Documents/Qt/exampleProj/object.obj', function (object) {
      
          object.traverse(function (child) {
              if (child instanceof THREE.Mesh) {
                  child.material.side = THREE.Material.DoubleSide;
              }
          });
      
          scene.add(object);
      });
      

      Unfortunately, when I run this code, I get type errors, saying that OBJLoader is not a type. It looks like the three.js library from https://github.com/tronlec/three.js/blob/master/build/three.js does not include OBJLoader. I've tried appending the source code of OBJLoader from https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/OBJLoader.js to the end of my three.js file in my QRC, but I get other type errors for FIleLoader. When I attempt to append that to three.js, I get other type errors.

      I also want to be able to use other extensions/modules from three.js, namely TrackBallControls. Unfortunately, I get other type errors when trying to append this to the end of my three.js.

      My questions are the following: How do I render a .obj file in Qt QML using three.js? And how can I easily add modules and extensions to three.js?

      I Offline
      I Offline
      IPO_DEV
      wrote on last edited by
      #2

      @dillydill123 in case this is still an issue :
      you have to include the loader code - copy the OBJLoader.js to a directory (e.g. loaders) where it gets found by this statement:
      Qt.include("loaders/OBJLoader.js")
      ....
      // load file :
      var objLoader = new THREE.OBJLoader( THREE.DefaultLoadingManager );
      objLoader.setMaterials( materials );
      objLoader.setPath('C:/Users/dillydill123/Documents/Qt/exampleProj/');
      objLoader.load('object.obj', function ( object ) {
      // here add the loaded object
      scene.add(object)
      } );

      best regards,
      Michael

      DiracsbracketD 1 Reply Last reply
      2
      • I IPO_DEV

        @dillydill123 in case this is still an issue :
        you have to include the loader code - copy the OBJLoader.js to a directory (e.g. loaders) where it gets found by this statement:
        Qt.include("loaders/OBJLoader.js")
        ....
        // load file :
        var objLoader = new THREE.OBJLoader( THREE.DefaultLoadingManager );
        objLoader.setMaterials( materials );
        objLoader.setPath('C:/Users/dillydill123/Documents/Qt/exampleProj/');
        objLoader.load('object.obj', function ( object ) {
        // here add the loaded object
        scene.add(object)
        } );

        best regards,
        Michael

        DiracsbracketD Offline
        DiracsbracketD Offline
        Diracsbracket
        wrote on last edited by
        #3

        Hi @IPO_DEV
        I just tried your approach with the three.js-master\qt-examples\quickitemtexture example, but I get the following error

        qrc:/loader/OBJLoader.js:381: TypeError: Type error
        

        Line 381 in OBJLoader.js is:

        var loader = new THREE.FileLoader( scope.manager );
        

        I tried with the mesh from Qt\Examples\Qt-5.11.0\datavisualization\customitems\refinery.obj which I copied to the quickitemtexture example dir and then used:

            // load file :
            var objLoader = new THREE.OBJLoader(THREE.DefaultLoadingManager );
            objLoader.setMaterials( material );
            objLoader.setPath('G:/Source/Qt/three.js-master/qt-examples/quickitemtexture/');
        
            objLoader.load('refinery.obj', function ( object ) {
                // here add the loaded object
                scene.add(object)
            } );
        

        Any ideas?

        I 1 Reply Last reply
        0
        • DiracsbracketD Diracsbracket

          Hi @IPO_DEV
          I just tried your approach with the three.js-master\qt-examples\quickitemtexture example, but I get the following error

          qrc:/loader/OBJLoader.js:381: TypeError: Type error
          

          Line 381 in OBJLoader.js is:

          var loader = new THREE.FileLoader( scope.manager );
          

          I tried with the mesh from Qt\Examples\Qt-5.11.0\datavisualization\customitems\refinery.obj which I copied to the quickitemtexture example dir and then used:

              // load file :
              var objLoader = new THREE.OBJLoader(THREE.DefaultLoadingManager );
              objLoader.setMaterials( material );
              objLoader.setPath('G:/Source/Qt/three.js-master/qt-examples/quickitemtexture/');
          
              objLoader.load('refinery.obj', function ( object ) {
                  // here add the loaded object
                  scene.add(object)
              } );
          

          Any ideas?

          I Offline
          I Offline
          IPO_DEV
          wrote on last edited by
          #4

          @Diracsbracket
          ok I've forgot to paste the MTLLoader part - here' s a complete snippet:

          
          
          Qt.include("loaders/MTLLoader.js")
          Qt.include("loaders/OBJLoader.js")
          
          function addOBJ(scene)
          {
              // suppose we load a campfire.obj with its material file campfire.mtl
              var baseName =  "campfire"
              var baseUrl = "file:///D:/_SOURCE/threejs_qt_74/examples/models/campfire/"
          
              var mtlLoader = new THREE.MTLLoader();
                      // set baseurl + path to baseurl
                      mtlLoader.setBaseUrl( baseUrl );
                      mtlLoader.setPath(baseUrl);
                      var materialFile =  baseName + ".mtl"
                      console.log("matfile ->" + materialFile)
                      // now load material file first
                      mtlLoader.load(materialFile, function( materials ) {
          
          
                      // make sure all materials are loaded
                      materials.preload();
                      console.log("LOADED MAT..");
          
                      // define progress and error callbacks
                      var onProgress = function ( xhr ) {
                          console.log("PRG " + xhr);
          
                          };
                      var onError = function ( xhr ) {
                          console.log("ERROR" + xhr);
                          };
                         // now load OBJ with materials already loaded
                      var objLoader = new THREE.OBJLoader( THREE.DefaultLoadingManager );
                      objLoader.setMaterials( materials );
                      objLoader.setPath(baseUrl );
                      objLoader.load( baseName+".obj", function ( object ) {
                              // callback for model loaded :
                              console.log("LOADED OBJ");
                              // get some info about loaded model
                              var box = new  THREE.Box3();
                              box.setFromObject(object);
                              var center = box.center();
                              var size = box.size();
                              console.log("SIZE:" + JSON.stringify( size))
                              console.log("CENTER:" + JSON.stringify( center))
                              scene.add(object)
                              // sample manipulation, move the loaded object -17 along z
                              object.position.z = -17.0;
                              }
                      ) //  objLoader.load
          
                      }) // mtlLoader.load
          
          
          }
          

          call addOBJ() with your scene...

          DiracsbracketD 1 Reply Last reply
          1
          • I IPO_DEV

            @Diracsbracket
            ok I've forgot to paste the MTLLoader part - here' s a complete snippet:

            
            
            Qt.include("loaders/MTLLoader.js")
            Qt.include("loaders/OBJLoader.js")
            
            function addOBJ(scene)
            {
                // suppose we load a campfire.obj with its material file campfire.mtl
                var baseName =  "campfire"
                var baseUrl = "file:///D:/_SOURCE/threejs_qt_74/examples/models/campfire/"
            
                var mtlLoader = new THREE.MTLLoader();
                        // set baseurl + path to baseurl
                        mtlLoader.setBaseUrl( baseUrl );
                        mtlLoader.setPath(baseUrl);
                        var materialFile =  baseName + ".mtl"
                        console.log("matfile ->" + materialFile)
                        // now load material file first
                        mtlLoader.load(materialFile, function( materials ) {
            
            
                        // make sure all materials are loaded
                        materials.preload();
                        console.log("LOADED MAT..");
            
                        // define progress and error callbacks
                        var onProgress = function ( xhr ) {
                            console.log("PRG " + xhr);
            
                            };
                        var onError = function ( xhr ) {
                            console.log("ERROR" + xhr);
                            };
                           // now load OBJ with materials already loaded
                        var objLoader = new THREE.OBJLoader( THREE.DefaultLoadingManager );
                        objLoader.setMaterials( materials );
                        objLoader.setPath(baseUrl );
                        objLoader.load( baseName+".obj", function ( object ) {
                                // callback for model loaded :
                                console.log("LOADED OBJ");
                                // get some info about loaded model
                                var box = new  THREE.Box3();
                                box.setFromObject(object);
                                var center = box.center();
                                var size = box.size();
                                console.log("SIZE:" + JSON.stringify( size))
                                console.log("CENTER:" + JSON.stringify( center))
                                scene.add(object)
                                // sample manipulation, move the loaded object -17 along z
                                object.position.z = -17.0;
                                }
                        ) //  objLoader.load
            
                        }) // mtlLoader.load
            
            
            }
            

            call addOBJ() with your scene...

            DiracsbracketD Offline
            DiracsbracketD Offline
            Diracsbracket
            wrote on last edited by Diracsbracket
            #5

            Thanks for the code @IPO_DEV !
            I tried it but I still get the same error at the same line:

            var loader = new THREE.FileLoader( scope.manager );
            

            No worries though, as I am a complete NOOB concerning JavaScript (apart from the little I use for QML), three.js and 3D graphics, really. I was just trying to test something out by taking a working example and replacing the object added to the scene by the one read from the .obj file...

            I know I must be missing some simple stuff that will become obvious if I learn more, which I will.

            Cheers!

            1 Reply Last reply
            0
            • I Offline
              I Offline
              IPO_DEV
              wrote on last edited by
              #6

              @Diracsbracket hm this is strange, i've also used the quickitemtexture example and just added the code i've posted - it seems that u're using a different loader code - the line in my OBJLoader.js looks different (var loader = new THREE.XHRLoader( scope.manager ); )
              Here is the complete source for both files:

              OBJLoader.js:

              /**
               * @author mrdoob / http://mrdoob.com/
               */
              
              THREE.OBJLoader = function ( manager ) {
              
              	this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
              
              	this.materials = null;
              
              };
              
              THREE.OBJLoader.prototype = {
              
              	constructor: THREE.OBJLoader,
              
              	load: function ( url, onLoad, onProgress, onError ) {
              
              		var scope = this;
              
              		var loader = new THREE.XHRLoader( scope.manager );
              		loader.setPath( this.path );
              		loader.load( url, function ( text ) {
              
              			onLoad( scope.parse( text ) );
              
              		}, onProgress, onError );
              
              	},
              
              	setPath: function ( value ) {
              
              		this.path = value;
              
              	},
              
              	setMaterials: function ( materials ) {
              
              		this.materials = materials;
              
              	},
              
              	parse: function ( text ) {
              
              		console.time( 'OBJLoader' );
              
              		var objects = [];
              		var object;
              		var foundObjects = false;
              		var vertices = [];
              		var normals = [];
              		var uvs = [];
              
              		function addObject( name ) {
              
              			var geometry = {
              				vertices: [],
              				normals: [],
              				uvs: []
              			};
              
              			var material = {
              				name: '',
              				smooth: true
              			};
              
              			object = {
              				name: name,
              				geometry: geometry,
              				material: material
              			};
              
              			objects.push( object );
              
              		}
              
              		function parseVertexIndex( value ) {
              
              			var index = parseInt( value );
              
              			return ( index >= 0 ? index - 1 : index + vertices.length / 3 ) * 3;
              
              		}
              
              		function parseNormalIndex( value ) {
              
              			var index = parseInt( value );
              
              			return ( index >= 0 ? index - 1 : index + normals.length / 3 ) * 3;
              
              		}
              
              		function parseUVIndex( value ) {
              
              			var index = parseInt( value );
              
              			return ( index >= 0 ? index - 1 : index + uvs.length / 2 ) * 2;
              
              		}
              
              		function addVertex( a, b, c ) {
              
              			object.geometry.vertices.push(
              				vertices[ a ], vertices[ a + 1 ], vertices[ a + 2 ],
              				vertices[ b ], vertices[ b + 1 ], vertices[ b + 2 ],
              				vertices[ c ], vertices[ c + 1 ], vertices[ c + 2 ]
              			);
              
              		}
              
              		function addNormal( a, b, c ) {
              
              			object.geometry.normals.push(
              				normals[ a ], normals[ a + 1 ], normals[ a + 2 ],
              				normals[ b ], normals[ b + 1 ], normals[ b + 2 ],
              				normals[ c ], normals[ c + 1 ], normals[ c + 2 ]
              			);
              
              		}
              
              		function addUV( a, b, c ) {
              
              			object.geometry.uvs.push(
              				uvs[ a ], uvs[ a + 1 ],
              				uvs[ b ], uvs[ b + 1 ],
              				uvs[ c ], uvs[ c + 1 ]
              			);
              
              		}
              
              		function addFace( a, b, c, d,  ua, ub, uc, ud, na, nb, nc, nd ) {
              
              			var ia = parseVertexIndex( a );
              			var ib = parseVertexIndex( b );
              			var ic = parseVertexIndex( c );
              			var id;
              
              			if ( d === undefined ) {
              
              				addVertex( ia, ib, ic );
              
              			} else {
              
              				id = parseVertexIndex( d );
              
              				addVertex( ia, ib, id );
              				addVertex( ib, ic, id );
              
              			}
              
              			if ( ua !== undefined ) {
              
              				ia = parseUVIndex( ua );
              				ib = parseUVIndex( ub );
              				ic = parseUVIndex( uc );
              
              				if ( d === undefined ) {
              
              					addUV( ia, ib, ic );
              
              				} else {
              
              					id = parseUVIndex( ud );
              
              					addUV( ia, ib, id );
              					addUV( ib, ic, id );
              
              				}
              
              			}
              
              			if ( na !== undefined ) {
              
              				ia = parseNormalIndex( na );
              				ib = parseNormalIndex( nb );
              				ic = parseNormalIndex( nc );
              
              				if ( d === undefined ) {
              
              					addNormal( ia, ib, ic );
              
              				} else {
              
              					id = parseNormalIndex( nd );
              
              					addNormal( ia, ib, id );
              					addNormal( ib, ic, id );
              
              				}
              
              			}
              
              		}
              
              		addObject( '' );
              
              		// v float float float
              		var vertex_pattern = /^v\s+([\d|\.|\+|\-|e|E]+)\s+([\d|\.|\+|\-|e|E]+)\s+([\d|\.|\+|\-|e|E]+)/;
              
              		// vn float float float
              		var normal_pattern = /^vn\s+([\d|\.|\+|\-|e|E]+)\s+([\d|\.|\+|\-|e|E]+)\s+([\d|\.|\+|\-|e|E]+)/;
              
              		// vt float float
              		var uv_pattern = /^vt\s+([\d|\.|\+|\-|e|E]+)\s+([\d|\.|\+|\-|e|E]+)/;
              
              		// f vertex vertex vertex ...
              		var face_pattern1 = /^f\s+(-?\d+)\s+(-?\d+)\s+(-?\d+)(?:\s+(-?\d+))?/;
              
              		// f vertex/uv vertex/uv vertex/uv ...
              		var face_pattern2 = /^f\s+((-?\d+)\/(-?\d+))\s+((-?\d+)\/(-?\d+))\s+((-?\d+)\/(-?\d+))(?:\s+((-?\d+)\/(-?\d+)))?/;
              
              		// f vertex/uv/normal vertex/uv/normal vertex/uv/normal ...
              		var face_pattern3 = /^f\s+((-?\d+)\/(-?\d+)\/(-?\d+))\s+((-?\d+)\/(-?\d+)\/(-?\d+))\s+((-?\d+)\/(-?\d+)\/(-?\d+))(?:\s+((-?\d+)\/(-?\d+)\/(-?\d+)))?/;
              
              		// f vertex//normal vertex//normal vertex//normal ...
              		var face_pattern4 = /^f\s+((-?\d+)\/\/(-?\d+))\s+((-?\d+)\/\/(-?\d+))\s+((-?\d+)\/\/(-?\d+))(?:\s+((-?\d+)\/\/(-?\d+)))?/;
              
              		var object_pattern = /^[og]\s+(.+)/;
              
              		var smoothing_pattern = /^s\s+([01]|on|off)/;
              
              		//
              
              		var lines = text.split( '\n' );
              
              		for ( var i = 0; i < lines.length; i ++ ) {
              
              			var line = lines[ i ];
              			line = line.trim();
              
              			var result;
              
              			if ( line.length === 0 || line.charAt( 0 ) === '#' ) {
              
              				continue;
              
              			} else if ( ( result = vertex_pattern.exec( line ) ) !== null ) {
              
              				// ["v 1.0 2.0 3.0", "1.0", "2.0", "3.0"]
              
              				vertices.push(
              					parseFloat( result[ 1 ] ),
              					parseFloat( result[ 2 ] ),
              					parseFloat( result[ 3 ] )
              				);
              
              			} else if ( ( result = normal_pattern.exec( line ) ) !== null ) {
              
              				// ["vn 1.0 2.0 3.0", "1.0", "2.0", "3.0"]
              
              				normals.push(
              					parseFloat( result[ 1 ] ),
              					parseFloat( result[ 2 ] ),
              					parseFloat( result[ 3 ] )
              				);
              
              			} else if ( ( result = uv_pattern.exec( line ) ) !== null ) {
              
              				// ["vt 0.1 0.2", "0.1", "0.2"]
              
              				uvs.push(
              					parseFloat( result[ 1 ] ),
              					parseFloat( result[ 2 ] )
              				);
              
              			} else if ( ( result = face_pattern1.exec( line ) ) !== null ) {
              
              				// ["f 1 2 3", "1", "2", "3", undefined]
              
              				addFace(
              					result[ 1 ], result[ 2 ], result[ 3 ], result[ 4 ]
              				);
              
              			} else if ( ( result = face_pattern2.exec( line ) ) !== null ) {
              
              				// ["f 1/1 2/2 3/3", " 1/1", "1", "1", " 2/2", "2", "2", " 3/3", "3", "3", undefined, undefined, undefined]
              
              				addFace(
              					result[ 2 ], result[ 5 ], result[ 8 ], result[ 11 ],
              					result[ 3 ], result[ 6 ], result[ 9 ], result[ 12 ]
              				);
              
              			} else if ( ( result = face_pattern3.exec( line ) ) !== null ) {
              
              				// ["f 1/1/1 2/2/2 3/3/3", " 1/1/1", "1", "1", "1", " 2/2/2", "2", "2", "2", " 3/3/3", "3", "3", "3", undefined, undefined, undefined, undefined]
              
              				addFace(
              					result[ 2 ], result[ 6 ], result[ 10 ], result[ 14 ],
              					result[ 3 ], result[ 7 ], result[ 11 ], result[ 15 ],
              					result[ 4 ], result[ 8 ], result[ 12 ], result[ 16 ]
              				);
              
              			} else if ( ( result = face_pattern4.exec( line ) ) !== null ) {
              
              				// ["f 1//1 2//2 3//3", " 1//1", "1", "1", " 2//2", "2", "2", " 3//3", "3", "3", undefined, undefined, undefined]
              
              				addFace(
              					result[ 2 ], result[ 5 ], result[ 8 ], result[ 11 ],
              					undefined, undefined, undefined, undefined,
              					result[ 3 ], result[ 6 ], result[ 9 ], result[ 12 ]
              				);
              
              			} else if ( ( result = object_pattern.exec( line ) ) !== null ) {
              
              				// o object_name
              				// or
              				// g group_name
              
              				var name = result[ 1 ].trim();
              
              				if ( foundObjects === false ) {
              
              					foundObjects = true;
              					object.name = name;
              
              				} else {
              
              					addObject( name );
              
              				}
              
              			} else if ( /^usemtl /.test( line ) ) {
              
              				// material
              
              				object.material.name = line.substring( 7 ).trim();
              
              			} else if ( /^mtllib /.test( line ) ) {
              
              				// mtl file
              
              			} else if ( ( result = smoothing_pattern.exec( line ) ) !== null ) {
              
              				// smooth shading
              
              				object.material.smooth = result[ 1 ] === "1" || result[ 1 ] === "on";
              
              			} else {
              
              				throw new Error( "Unexpected line: " + line );
              
              			}
              
              		}
              
              		var container = new THREE.Group();
              
              		for ( var i = 0, l = objects.length; i < l; i ++ ) {
              
              			object = objects[ i ];
              			var geometry = object.geometry;
              
              			var buffergeometry = new THREE.BufferGeometry();
              
              			buffergeometry.addAttribute( 'position', new THREE.BufferAttribute( new Float32Array( geometry.vertices ), 3 ) );
              
              			if ( geometry.normals.length > 0 ) {
              
              				buffergeometry.addAttribute( 'normal', new THREE.BufferAttribute( new Float32Array( geometry.normals ), 3 ) );
              
              			} else {
              
              				buffergeometry.computeVertexNormals();
              
              			}
              
              			if ( geometry.uvs.length > 0 ) {
              
              				buffergeometry.addAttribute( 'uv', new THREE.BufferAttribute( new Float32Array( geometry.uvs ), 2 ) );
              
              			}
              
              			var material;
              
              			if ( this.materials !== null ) {
              
              				material = this.materials.create( object.material.name );
              
              			}
              
              			if ( !material ) {
              
              				material = new THREE.MeshPhongMaterial();
              				material.name = object.material.name;
              
              			}
              
              			material.shading = object.material.smooth ? THREE.SmoothShading : THREE.FlatShading;
              
              			var mesh = new THREE.Mesh( buffergeometry, material );
              			mesh.name = object.name;
              
              			container.add( mesh );
              
              		}
              
              		console.timeEnd( 'OBJLoader' );
              
              		return container;
              
              	}
              
              };
              
              

              MTLLoader.js

              /**
               * Loads a Wavefront .mtl file specifying materials
               *
               * @author angelxuanchang
               */
              
              THREE.MTLLoader = function( manager ) {
              
              	this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
              
              };
              
              THREE.MTLLoader.prototype = {
              
              	constructor: THREE.MTLLoader,
              
              	load: function ( url, onLoad, onProgress, onError ) {
              
              		var scope = this;
              
              		var loader = new THREE.XHRLoader( this.manager );
              		loader.setPath( this.path );
              		loader.load( url, function ( text ) {
              
              			onLoad( scope.parse( text ) );
              
              		}, onProgress, onError );
              
              	},
              
              	setPath: function ( value ) {
              
              		this.path = value;
              
              	},
              
              	setBaseUrl: function( value ) {
              
              		// TODO: Merge with setPath()? Or rename to setTexturePath?
              
              		this.baseUrl = value;
              
              	},
              
              	setCrossOrigin: function ( value ) {
              
              		this.crossOrigin = value;
              
              	},
              
              	setMaterialOptions: function ( value ) {
              
              		this.materialOptions = value;
              
              	},
              
              	/**
              	 * Parses loaded MTL file
              	 * @param text - Content of MTL file
              	 * @return {THREE.MTLLoader.MaterialCreator}
              	 */
              	parse: function ( text ) {
              
              		var lines = text.split( "\n" );
              		var info = {};
              		var delimiter_pattern = /\s+/;
              		var materialsInfo = {};
              
              		for ( var i = 0; i < lines.length; i ++ ) {
              
              			var line = lines[ i ];
              			line = line.trim();
              
              			if ( line.length === 0 || line.charAt( 0 ) === '#' ) {
              
              				// Blank line or comment ignore
              				continue;
              
              			}
              
              			var pos = line.indexOf( ' ' );
              
              			var key = ( pos >= 0 ) ? line.substring( 0, pos ) : line;
              			key = key.toLowerCase();
              
              			var value = ( pos >= 0 ) ? line.substring( pos + 1 ) : "";
              			value = value.trim();
              
              			if ( key === "newmtl" ) {
              
              				// New material
              
              				info = { name: value };
              				materialsInfo[ value ] = info;
              
              			} else if ( info ) {
              
              				if ( key === "ka" || key === "kd" || key === "ks" ) {
              
              					var ss = value.split( delimiter_pattern, 3 );
              					info[ key ] = [ parseFloat( ss[ 0 ] ), parseFloat( ss[ 1 ] ), parseFloat( ss[ 2 ] ) ];
              
              				} else {
              
              					info[ key ] = value;
              
              				}
              
              			}
              
              		}
              
              		var materialCreator = new THREE.MTLLoader.MaterialCreator( this.baseUrl, this.materialOptions );
              		materialCreator.setCrossOrigin( this.crossOrigin );
              		materialCreator.setManager( this.manager );
              		materialCreator.setMaterials( materialsInfo );
              		return materialCreator;
              
              	}
              
              };
              
              /**
               * Create a new THREE-MTLLoader.MaterialCreator
               * @param baseUrl - Url relative to which textures are loaded
               * @param options - Set of options on how to construct the materials
               *                  side: Which side to apply the material
               *                        THREE.FrontSide (default), THREE.BackSide, THREE.DoubleSide
               *                  wrap: What type of wrapping to apply for textures
               *                        THREE.RepeatWrapping (default), THREE.ClampToEdgeWrapping, THREE.MirroredRepeatWrapping
               *                  normalizeRGB: RGBs need to be normalized to 0-1 from 0-255
               *                                Default: false, assumed to be already normalized
               *                  ignoreZeroRGBs: Ignore values of RGBs (Ka,Kd,Ks) that are all 0's
               *                                  Default: false
               * @constructor
               */
              
              THREE.MTLLoader.MaterialCreator = function( baseUrl, options ) {
              
              	this.baseUrl = baseUrl;
              	this.options = options;
              	this.materialsInfo = {};
              	this.materials = {};
              	this.materialsArray = [];
              	this.nameLookup = {};
              
              	this.side = ( this.options && this.options.side ) ? this.options.side : THREE.FrontSide;
              	this.wrap = ( this.options && this.options.wrap ) ? this.options.wrap : THREE.RepeatWrapping;
              
              };
              
              THREE.MTLLoader.MaterialCreator.prototype = {
              
              	constructor: THREE.MTLLoader.MaterialCreator,
              
              	setCrossOrigin: function ( value ) {
              
              		this.crossOrigin = value;
              
              	},
              
              	setManager: function ( value ) {
              
              		this.manager = value;
              
              	},
              
              	setMaterials: function( materialsInfo ) {
              
              		this.materialsInfo = this.convert( materialsInfo );
              		this.materials = {};
              		this.materialsArray = [];
              		this.nameLookup = {};
              
              	},
              
              	convert: function( materialsInfo ) {
              
              		if ( ! this.options ) return materialsInfo;
              
              		var converted = {};
              
              		for ( var mn in materialsInfo ) {
              
              			// Convert materials info into normalized form based on options
              
              			var mat = materialsInfo[ mn ];
              
              			var covmat = {};
              
              			converted[ mn ] = covmat;
              
              			for ( var prop in mat ) {
              
              				var save = true;
              				var value = mat[ prop ];
              				var lprop = prop.toLowerCase();
              
              				switch ( lprop ) {
              
              					case 'kd':
              					case 'ka':
              					case 'ks':
              
              						// Diffuse color (color under white light) using RGB values
              
              						if ( this.options && this.options.normalizeRGB ) {
              
              							value = [ value[ 0 ] / 255, value[ 1 ] / 255, value[ 2 ] / 255 ];
              
              						}
              
              						if ( this.options && this.options.ignoreZeroRGBs ) {
              
              							if ( value[ 0 ] === 0 && value[ 1 ] === 0 && value[ 1 ] === 0 ) {
              
              								// ignore
              
              								save = false;
              
              							}
              
              						}
              
              						break;
              
              					default:
              
              						break;
              				}
              
              				if ( save ) {
              
              					covmat[ lprop ] = value;
              
              				}
              
              			}
              
              		}
              
              		return converted;
              
              	},
              
              	preload: function () {
              
              		for ( var mn in this.materialsInfo ) {
              
              			this.create( mn );
              
              		}
              
              	},
              
              	getIndex: function( materialName ) {
              
              		return this.nameLookup[ materialName ];
              
              	},
              
              	getAsArray: function() {
              
              		var index = 0;
              
              		for ( var mn in this.materialsInfo ) {
              
              			this.materialsArray[ index ] = this.create( mn );
              			this.nameLookup[ mn ] = index;
              			index ++;
              
              		}
              
              		return this.materialsArray;
              
              	},
              
              	create: function ( materialName ) {
              
              		if ( this.materials[ materialName ] === undefined ) {
              
              			this.createMaterial_( materialName );
              
              		}
              
              		return this.materials[ materialName ];
              
              	},
              
              	createMaterial_: function ( materialName ) {
              
              		// Create material
              
              		var mat = this.materialsInfo[ materialName ];
              		var params = {
              
              			name: materialName,
              			side: this.side
              
              		};
              
              		for ( var prop in mat ) {
              
              			var value = mat[ prop ];
              
              			if ( value === '' ) {
              				continue;
              			}
              
              			switch ( prop.toLowerCase() ) {
              
              				// Ns is material specular exponent
              
              				case 'kd':
              
              					// Diffuse color (color under white light) using RGB values
              
              					params[ 'color' ] = new THREE.Color().fromArray( value );
              
              					break;
              
              				case 'ks':
              
              					// Specular color (color when light is reflected from shiny surface) using RGB values
              					params[ 'specular' ] = new THREE.Color().fromArray( value );
              
              					break;
              
              				case 'map_kd':
              
              					// Diffuse texture map
              
              					params[ 'map' ] = this.loadTexture( this.baseUrl + value );
              					params[ 'map' ].wrapS = this.wrap;
              					params[ 'map' ].wrapT = this.wrap;
              
              					break;
              
              				case 'ns':
              
              					// The specular exponent (defines the focus of the specular highlight)
              					// A high exponent results in a tight, concentrated highlight. Ns values normally range from 0 to 1000.
              
              					params[ 'shininess' ] = parseFloat( value );
              
              					break;
              
              				case 'd':
              
              					if ( value < 1 ) {
              
              						params[ 'opacity' ] = value;
              						params[ 'transparent' ] = true;
              
              					}
              
              					break;
              
              				case 'Tr':
              
              					if ( value > 0 ) {
              
              						params[ 'opacity' ] = 1 - value;
              						params[ 'transparent' ] = true;
              
              					}
              
              					break;
              
              				case 'map_bump':
              				case 'bump':
              
              					// Bump texture map
              
              					if ( params[ 'bumpMap' ] ) break; // Avoid loading twice.
              
              					params[ 'bumpMap' ] = this.loadTexture( this.baseUrl + value );
              					params[ 'bumpMap' ].wrapS = this.wrap;
              					params[ 'bumpMap' ].wrapT = this.wrap;
              
              					break;
              
              				default:
              					break;
              
              			}
              
              		}
              
              		this.materials[ materialName ] = new THREE.MeshPhongMaterial( params );
              		return this.materials[ materialName ];
              
              	},
              
              
              	loadTexture: function ( url, mapping, onLoad, onProgress, onError ) {
              
              		var texture;
              		var loader = THREE.Loader.Handlers.get( url );
              		var manager = ( this.manager !== undefined ) ? this.manager : THREE.DefaultLoadingManager;
              
              		if ( loader === null ) {
              
              			loader = new THREE.TextureLoader( manager );
              
              		}
              
              		if ( loader.setCrossOrigin ) loader.setCrossOrigin( this.crossOrigin );
              		texture = loader.load( url, onLoad, onProgress, onError );
              
              		if ( mapping !== undefined ) texture.mapping = mapping;
              
              		return texture;
              
              	}
              
              };
              
              THREE.EventDispatcher.prototype.apply( THREE.MTLLoader.prototype );
              
              
              DiracsbracketD 1 Reply Last reply
              2
              • I IPO_DEV

                @Diracsbracket hm this is strange, i've also used the quickitemtexture example and just added the code i've posted - it seems that u're using a different loader code - the line in my OBJLoader.js looks different (var loader = new THREE.XHRLoader( scope.manager ); )
                Here is the complete source for both files:

                OBJLoader.js:

                /**
                 * @author mrdoob / http://mrdoob.com/
                 */
                
                THREE.OBJLoader = function ( manager ) {
                
                	this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
                
                	this.materials = null;
                
                };
                
                THREE.OBJLoader.prototype = {
                
                	constructor: THREE.OBJLoader,
                
                	load: function ( url, onLoad, onProgress, onError ) {
                
                		var scope = this;
                
                		var loader = new THREE.XHRLoader( scope.manager );
                		loader.setPath( this.path );
                		loader.load( url, function ( text ) {
                
                			onLoad( scope.parse( text ) );
                
                		}, onProgress, onError );
                
                	},
                
                	setPath: function ( value ) {
                
                		this.path = value;
                
                	},
                
                	setMaterials: function ( materials ) {
                
                		this.materials = materials;
                
                	},
                
                	parse: function ( text ) {
                
                		console.time( 'OBJLoader' );
                
                		var objects = [];
                		var object;
                		var foundObjects = false;
                		var vertices = [];
                		var normals = [];
                		var uvs = [];
                
                		function addObject( name ) {
                
                			var geometry = {
                				vertices: [],
                				normals: [],
                				uvs: []
                			};
                
                			var material = {
                				name: '',
                				smooth: true
                			};
                
                			object = {
                				name: name,
                				geometry: geometry,
                				material: material
                			};
                
                			objects.push( object );
                
                		}
                
                		function parseVertexIndex( value ) {
                
                			var index = parseInt( value );
                
                			return ( index >= 0 ? index - 1 : index + vertices.length / 3 ) * 3;
                
                		}
                
                		function parseNormalIndex( value ) {
                
                			var index = parseInt( value );
                
                			return ( index >= 0 ? index - 1 : index + normals.length / 3 ) * 3;
                
                		}
                
                		function parseUVIndex( value ) {
                
                			var index = parseInt( value );
                
                			return ( index >= 0 ? index - 1 : index + uvs.length / 2 ) * 2;
                
                		}
                
                		function addVertex( a, b, c ) {
                
                			object.geometry.vertices.push(
                				vertices[ a ], vertices[ a + 1 ], vertices[ a + 2 ],
                				vertices[ b ], vertices[ b + 1 ], vertices[ b + 2 ],
                				vertices[ c ], vertices[ c + 1 ], vertices[ c + 2 ]
                			);
                
                		}
                
                		function addNormal( a, b, c ) {
                
                			object.geometry.normals.push(
                				normals[ a ], normals[ a + 1 ], normals[ a + 2 ],
                				normals[ b ], normals[ b + 1 ], normals[ b + 2 ],
                				normals[ c ], normals[ c + 1 ], normals[ c + 2 ]
                			);
                
                		}
                
                		function addUV( a, b, c ) {
                
                			object.geometry.uvs.push(
                				uvs[ a ], uvs[ a + 1 ],
                				uvs[ b ], uvs[ b + 1 ],
                				uvs[ c ], uvs[ c + 1 ]
                			);
                
                		}
                
                		function addFace( a, b, c, d,  ua, ub, uc, ud, na, nb, nc, nd ) {
                
                			var ia = parseVertexIndex( a );
                			var ib = parseVertexIndex( b );
                			var ic = parseVertexIndex( c );
                			var id;
                
                			if ( d === undefined ) {
                
                				addVertex( ia, ib, ic );
                
                			} else {
                
                				id = parseVertexIndex( d );
                
                				addVertex( ia, ib, id );
                				addVertex( ib, ic, id );
                
                			}
                
                			if ( ua !== undefined ) {
                
                				ia = parseUVIndex( ua );
                				ib = parseUVIndex( ub );
                				ic = parseUVIndex( uc );
                
                				if ( d === undefined ) {
                
                					addUV( ia, ib, ic );
                
                				} else {
                
                					id = parseUVIndex( ud );
                
                					addUV( ia, ib, id );
                					addUV( ib, ic, id );
                
                				}
                
                			}
                
                			if ( na !== undefined ) {
                
                				ia = parseNormalIndex( na );
                				ib = parseNormalIndex( nb );
                				ic = parseNormalIndex( nc );
                
                				if ( d === undefined ) {
                
                					addNormal( ia, ib, ic );
                
                				} else {
                
                					id = parseNormalIndex( nd );
                
                					addNormal( ia, ib, id );
                					addNormal( ib, ic, id );
                
                				}
                
                			}
                
                		}
                
                		addObject( '' );
                
                		// v float float float
                		var vertex_pattern = /^v\s+([\d|\.|\+|\-|e|E]+)\s+([\d|\.|\+|\-|e|E]+)\s+([\d|\.|\+|\-|e|E]+)/;
                
                		// vn float float float
                		var normal_pattern = /^vn\s+([\d|\.|\+|\-|e|E]+)\s+([\d|\.|\+|\-|e|E]+)\s+([\d|\.|\+|\-|e|E]+)/;
                
                		// vt float float
                		var uv_pattern = /^vt\s+([\d|\.|\+|\-|e|E]+)\s+([\d|\.|\+|\-|e|E]+)/;
                
                		// f vertex vertex vertex ...
                		var face_pattern1 = /^f\s+(-?\d+)\s+(-?\d+)\s+(-?\d+)(?:\s+(-?\d+))?/;
                
                		// f vertex/uv vertex/uv vertex/uv ...
                		var face_pattern2 = /^f\s+((-?\d+)\/(-?\d+))\s+((-?\d+)\/(-?\d+))\s+((-?\d+)\/(-?\d+))(?:\s+((-?\d+)\/(-?\d+)))?/;
                
                		// f vertex/uv/normal vertex/uv/normal vertex/uv/normal ...
                		var face_pattern3 = /^f\s+((-?\d+)\/(-?\d+)\/(-?\d+))\s+((-?\d+)\/(-?\d+)\/(-?\d+))\s+((-?\d+)\/(-?\d+)\/(-?\d+))(?:\s+((-?\d+)\/(-?\d+)\/(-?\d+)))?/;
                
                		// f vertex//normal vertex//normal vertex//normal ...
                		var face_pattern4 = /^f\s+((-?\d+)\/\/(-?\d+))\s+((-?\d+)\/\/(-?\d+))\s+((-?\d+)\/\/(-?\d+))(?:\s+((-?\d+)\/\/(-?\d+)))?/;
                
                		var object_pattern = /^[og]\s+(.+)/;
                
                		var smoothing_pattern = /^s\s+([01]|on|off)/;
                
                		//
                
                		var lines = text.split( '\n' );
                
                		for ( var i = 0; i < lines.length; i ++ ) {
                
                			var line = lines[ i ];
                			line = line.trim();
                
                			var result;
                
                			if ( line.length === 0 || line.charAt( 0 ) === '#' ) {
                
                				continue;
                
                			} else if ( ( result = vertex_pattern.exec( line ) ) !== null ) {
                
                				// ["v 1.0 2.0 3.0", "1.0", "2.0", "3.0"]
                
                				vertices.push(
                					parseFloat( result[ 1 ] ),
                					parseFloat( result[ 2 ] ),
                					parseFloat( result[ 3 ] )
                				);
                
                			} else if ( ( result = normal_pattern.exec( line ) ) !== null ) {
                
                				// ["vn 1.0 2.0 3.0", "1.0", "2.0", "3.0"]
                
                				normals.push(
                					parseFloat( result[ 1 ] ),
                					parseFloat( result[ 2 ] ),
                					parseFloat( result[ 3 ] )
                				);
                
                			} else if ( ( result = uv_pattern.exec( line ) ) !== null ) {
                
                				// ["vt 0.1 0.2", "0.1", "0.2"]
                
                				uvs.push(
                					parseFloat( result[ 1 ] ),
                					parseFloat( result[ 2 ] )
                				);
                
                			} else if ( ( result = face_pattern1.exec( line ) ) !== null ) {
                
                				// ["f 1 2 3", "1", "2", "3", undefined]
                
                				addFace(
                					result[ 1 ], result[ 2 ], result[ 3 ], result[ 4 ]
                				);
                
                			} else if ( ( result = face_pattern2.exec( line ) ) !== null ) {
                
                				// ["f 1/1 2/2 3/3", " 1/1", "1", "1", " 2/2", "2", "2", " 3/3", "3", "3", undefined, undefined, undefined]
                
                				addFace(
                					result[ 2 ], result[ 5 ], result[ 8 ], result[ 11 ],
                					result[ 3 ], result[ 6 ], result[ 9 ], result[ 12 ]
                				);
                
                			} else if ( ( result = face_pattern3.exec( line ) ) !== null ) {
                
                				// ["f 1/1/1 2/2/2 3/3/3", " 1/1/1", "1", "1", "1", " 2/2/2", "2", "2", "2", " 3/3/3", "3", "3", "3", undefined, undefined, undefined, undefined]
                
                				addFace(
                					result[ 2 ], result[ 6 ], result[ 10 ], result[ 14 ],
                					result[ 3 ], result[ 7 ], result[ 11 ], result[ 15 ],
                					result[ 4 ], result[ 8 ], result[ 12 ], result[ 16 ]
                				);
                
                			} else if ( ( result = face_pattern4.exec( line ) ) !== null ) {
                
                				// ["f 1//1 2//2 3//3", " 1//1", "1", "1", " 2//2", "2", "2", " 3//3", "3", "3", undefined, undefined, undefined]
                
                				addFace(
                					result[ 2 ], result[ 5 ], result[ 8 ], result[ 11 ],
                					undefined, undefined, undefined, undefined,
                					result[ 3 ], result[ 6 ], result[ 9 ], result[ 12 ]
                				);
                
                			} else if ( ( result = object_pattern.exec( line ) ) !== null ) {
                
                				// o object_name
                				// or
                				// g group_name
                
                				var name = result[ 1 ].trim();
                
                				if ( foundObjects === false ) {
                
                					foundObjects = true;
                					object.name = name;
                
                				} else {
                
                					addObject( name );
                
                				}
                
                			} else if ( /^usemtl /.test( line ) ) {
                
                				// material
                
                				object.material.name = line.substring( 7 ).trim();
                
                			} else if ( /^mtllib /.test( line ) ) {
                
                				// mtl file
                
                			} else if ( ( result = smoothing_pattern.exec( line ) ) !== null ) {
                
                				// smooth shading
                
                				object.material.smooth = result[ 1 ] === "1" || result[ 1 ] === "on";
                
                			} else {
                
                				throw new Error( "Unexpected line: " + line );
                
                			}
                
                		}
                
                		var container = new THREE.Group();
                
                		for ( var i = 0, l = objects.length; i < l; i ++ ) {
                
                			object = objects[ i ];
                			var geometry = object.geometry;
                
                			var buffergeometry = new THREE.BufferGeometry();
                
                			buffergeometry.addAttribute( 'position', new THREE.BufferAttribute( new Float32Array( geometry.vertices ), 3 ) );
                
                			if ( geometry.normals.length > 0 ) {
                
                				buffergeometry.addAttribute( 'normal', new THREE.BufferAttribute( new Float32Array( geometry.normals ), 3 ) );
                
                			} else {
                
                				buffergeometry.computeVertexNormals();
                
                			}
                
                			if ( geometry.uvs.length > 0 ) {
                
                				buffergeometry.addAttribute( 'uv', new THREE.BufferAttribute( new Float32Array( geometry.uvs ), 2 ) );
                
                			}
                
                			var material;
                
                			if ( this.materials !== null ) {
                
                				material = this.materials.create( object.material.name );
                
                			}
                
                			if ( !material ) {
                
                				material = new THREE.MeshPhongMaterial();
                				material.name = object.material.name;
                
                			}
                
                			material.shading = object.material.smooth ? THREE.SmoothShading : THREE.FlatShading;
                
                			var mesh = new THREE.Mesh( buffergeometry, material );
                			mesh.name = object.name;
                
                			container.add( mesh );
                
                		}
                
                		console.timeEnd( 'OBJLoader' );
                
                		return container;
                
                	}
                
                };
                
                

                MTLLoader.js

                /**
                 * Loads a Wavefront .mtl file specifying materials
                 *
                 * @author angelxuanchang
                 */
                
                THREE.MTLLoader = function( manager ) {
                
                	this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
                
                };
                
                THREE.MTLLoader.prototype = {
                
                	constructor: THREE.MTLLoader,
                
                	load: function ( url, onLoad, onProgress, onError ) {
                
                		var scope = this;
                
                		var loader = new THREE.XHRLoader( this.manager );
                		loader.setPath( this.path );
                		loader.load( url, function ( text ) {
                
                			onLoad( scope.parse( text ) );
                
                		}, onProgress, onError );
                
                	},
                
                	setPath: function ( value ) {
                
                		this.path = value;
                
                	},
                
                	setBaseUrl: function( value ) {
                
                		// TODO: Merge with setPath()? Or rename to setTexturePath?
                
                		this.baseUrl = value;
                
                	},
                
                	setCrossOrigin: function ( value ) {
                
                		this.crossOrigin = value;
                
                	},
                
                	setMaterialOptions: function ( value ) {
                
                		this.materialOptions = value;
                
                	},
                
                	/**
                	 * Parses loaded MTL file
                	 * @param text - Content of MTL file
                	 * @return {THREE.MTLLoader.MaterialCreator}
                	 */
                	parse: function ( text ) {
                
                		var lines = text.split( "\n" );
                		var info = {};
                		var delimiter_pattern = /\s+/;
                		var materialsInfo = {};
                
                		for ( var i = 0; i < lines.length; i ++ ) {
                
                			var line = lines[ i ];
                			line = line.trim();
                
                			if ( line.length === 0 || line.charAt( 0 ) === '#' ) {
                
                				// Blank line or comment ignore
                				continue;
                
                			}
                
                			var pos = line.indexOf( ' ' );
                
                			var key = ( pos >= 0 ) ? line.substring( 0, pos ) : line;
                			key = key.toLowerCase();
                
                			var value = ( pos >= 0 ) ? line.substring( pos + 1 ) : "";
                			value = value.trim();
                
                			if ( key === "newmtl" ) {
                
                				// New material
                
                				info = { name: value };
                				materialsInfo[ value ] = info;
                
                			} else if ( info ) {
                
                				if ( key === "ka" || key === "kd" || key === "ks" ) {
                
                					var ss = value.split( delimiter_pattern, 3 );
                					info[ key ] = [ parseFloat( ss[ 0 ] ), parseFloat( ss[ 1 ] ), parseFloat( ss[ 2 ] ) ];
                
                				} else {
                
                					info[ key ] = value;
                
                				}
                
                			}
                
                		}
                
                		var materialCreator = new THREE.MTLLoader.MaterialCreator( this.baseUrl, this.materialOptions );
                		materialCreator.setCrossOrigin( this.crossOrigin );
                		materialCreator.setManager( this.manager );
                		materialCreator.setMaterials( materialsInfo );
                		return materialCreator;
                
                	}
                
                };
                
                /**
                 * Create a new THREE-MTLLoader.MaterialCreator
                 * @param baseUrl - Url relative to which textures are loaded
                 * @param options - Set of options on how to construct the materials
                 *                  side: Which side to apply the material
                 *                        THREE.FrontSide (default), THREE.BackSide, THREE.DoubleSide
                 *                  wrap: What type of wrapping to apply for textures
                 *                        THREE.RepeatWrapping (default), THREE.ClampToEdgeWrapping, THREE.MirroredRepeatWrapping
                 *                  normalizeRGB: RGBs need to be normalized to 0-1 from 0-255
                 *                                Default: false, assumed to be already normalized
                 *                  ignoreZeroRGBs: Ignore values of RGBs (Ka,Kd,Ks) that are all 0's
                 *                                  Default: false
                 * @constructor
                 */
                
                THREE.MTLLoader.MaterialCreator = function( baseUrl, options ) {
                
                	this.baseUrl = baseUrl;
                	this.options = options;
                	this.materialsInfo = {};
                	this.materials = {};
                	this.materialsArray = [];
                	this.nameLookup = {};
                
                	this.side = ( this.options && this.options.side ) ? this.options.side : THREE.FrontSide;
                	this.wrap = ( this.options && this.options.wrap ) ? this.options.wrap : THREE.RepeatWrapping;
                
                };
                
                THREE.MTLLoader.MaterialCreator.prototype = {
                
                	constructor: THREE.MTLLoader.MaterialCreator,
                
                	setCrossOrigin: function ( value ) {
                
                		this.crossOrigin = value;
                
                	},
                
                	setManager: function ( value ) {
                
                		this.manager = value;
                
                	},
                
                	setMaterials: function( materialsInfo ) {
                
                		this.materialsInfo = this.convert( materialsInfo );
                		this.materials = {};
                		this.materialsArray = [];
                		this.nameLookup = {};
                
                	},
                
                	convert: function( materialsInfo ) {
                
                		if ( ! this.options ) return materialsInfo;
                
                		var converted = {};
                
                		for ( var mn in materialsInfo ) {
                
                			// Convert materials info into normalized form based on options
                
                			var mat = materialsInfo[ mn ];
                
                			var covmat = {};
                
                			converted[ mn ] = covmat;
                
                			for ( var prop in mat ) {
                
                				var save = true;
                				var value = mat[ prop ];
                				var lprop = prop.toLowerCase();
                
                				switch ( lprop ) {
                
                					case 'kd':
                					case 'ka':
                					case 'ks':
                
                						// Diffuse color (color under white light) using RGB values
                
                						if ( this.options && this.options.normalizeRGB ) {
                
                							value = [ value[ 0 ] / 255, value[ 1 ] / 255, value[ 2 ] / 255 ];
                
                						}
                
                						if ( this.options && this.options.ignoreZeroRGBs ) {
                
                							if ( value[ 0 ] === 0 && value[ 1 ] === 0 && value[ 1 ] === 0 ) {
                
                								// ignore
                
                								save = false;
                
                							}
                
                						}
                
                						break;
                
                					default:
                
                						break;
                				}
                
                				if ( save ) {
                
                					covmat[ lprop ] = value;
                
                				}
                
                			}
                
                		}
                
                		return converted;
                
                	},
                
                	preload: function () {
                
                		for ( var mn in this.materialsInfo ) {
                
                			this.create( mn );
                
                		}
                
                	},
                
                	getIndex: function( materialName ) {
                
                		return this.nameLookup[ materialName ];
                
                	},
                
                	getAsArray: function() {
                
                		var index = 0;
                
                		for ( var mn in this.materialsInfo ) {
                
                			this.materialsArray[ index ] = this.create( mn );
                			this.nameLookup[ mn ] = index;
                			index ++;
                
                		}
                
                		return this.materialsArray;
                
                	},
                
                	create: function ( materialName ) {
                
                		if ( this.materials[ materialName ] === undefined ) {
                
                			this.createMaterial_( materialName );
                
                		}
                
                		return this.materials[ materialName ];
                
                	},
                
                	createMaterial_: function ( materialName ) {
                
                		// Create material
                
                		var mat = this.materialsInfo[ materialName ];
                		var params = {
                
                			name: materialName,
                			side: this.side
                
                		};
                
                		for ( var prop in mat ) {
                
                			var value = mat[ prop ];
                
                			if ( value === '' ) {
                				continue;
                			}
                
                			switch ( prop.toLowerCase() ) {
                
                				// Ns is material specular exponent
                
                				case 'kd':
                
                					// Diffuse color (color under white light) using RGB values
                
                					params[ 'color' ] = new THREE.Color().fromArray( value );
                
                					break;
                
                				case 'ks':
                
                					// Specular color (color when light is reflected from shiny surface) using RGB values
                					params[ 'specular' ] = new THREE.Color().fromArray( value );
                
                					break;
                
                				case 'map_kd':
                
                					// Diffuse texture map
                
                					params[ 'map' ] = this.loadTexture( this.baseUrl + value );
                					params[ 'map' ].wrapS = this.wrap;
                					params[ 'map' ].wrapT = this.wrap;
                
                					break;
                
                				case 'ns':
                
                					// The specular exponent (defines the focus of the specular highlight)
                					// A high exponent results in a tight, concentrated highlight. Ns values normally range from 0 to 1000.
                
                					params[ 'shininess' ] = parseFloat( value );
                
                					break;
                
                				case 'd':
                
                					if ( value < 1 ) {
                
                						params[ 'opacity' ] = value;
                						params[ 'transparent' ] = true;
                
                					}
                
                					break;
                
                				case 'Tr':
                
                					if ( value > 0 ) {
                
                						params[ 'opacity' ] = 1 - value;
                						params[ 'transparent' ] = true;
                
                					}
                
                					break;
                
                				case 'map_bump':
                				case 'bump':
                
                					// Bump texture map
                
                					if ( params[ 'bumpMap' ] ) break; // Avoid loading twice.
                
                					params[ 'bumpMap' ] = this.loadTexture( this.baseUrl + value );
                					params[ 'bumpMap' ].wrapS = this.wrap;
                					params[ 'bumpMap' ].wrapT = this.wrap;
                
                					break;
                
                				default:
                					break;
                
                			}
                
                		}
                
                		this.materials[ materialName ] = new THREE.MeshPhongMaterial( params );
                		return this.materials[ materialName ];
                
                	},
                
                
                	loadTexture: function ( url, mapping, onLoad, onProgress, onError ) {
                
                		var texture;
                		var loader = THREE.Loader.Handlers.get( url );
                		var manager = ( this.manager !== undefined ) ? this.manager : THREE.DefaultLoadingManager;
                
                		if ( loader === null ) {
                
                			loader = new THREE.TextureLoader( manager );
                
                		}
                
                		if ( loader.setCrossOrigin ) loader.setCrossOrigin( this.crossOrigin );
                		texture = loader.load( url, onLoad, onProgress, onError );
                
                		if ( mapping !== undefined ) texture.mapping = mapping;
                
                		return texture;
                
                	}
                
                };
                
                THREE.EventDispatcher.prototype.apply( THREE.MTLLoader.prototype );
                
                
                DiracsbracketD Offline
                DiracsbracketD Offline
                Diracsbracket
                wrote on last edited by
                #7

                Hi @IPO_DEV
                I am an idiot... as you already suspected...

                I indeed copied the wrong versions of the files (from the latest three.js version at https://github.com/mrdoob/three.js/archive/master.zip) and not those from https://github.com/tronlec/three.js...

                Your example then works beautifully! I just needed to add

                mesh = object
                

                before the line

                scene.add(object)
                

                for the quickitemtexture example to work completely, since function paintGL(canvas) expects the object to be referenced by the variable mesh.

                function paintGL(canvas) {
                    mesh.rotation.x = degToRad(canvas.xRotAnim);
                    mesh.rotation.y = degToRad(canvas.yRotAnim);
                    mesh.rotation.z = degToRad(canvas.zRotAnim);
                    mesh.position.x = (canvas.yRotAnim - 120.0) / 120.0;
                    mesh.position.y = (canvas.xRotAnim -  60.0) / 50.0;
                    mesh.position.z = -7.0;
                    renderer.render( scene, camera );
                }
                

                Thanks again!

                I 1 Reply Last reply
                1
                • DiracsbracketD Diracsbracket

                  Hi @IPO_DEV
                  I am an idiot... as you already suspected...

                  I indeed copied the wrong versions of the files (from the latest three.js version at https://github.com/mrdoob/three.js/archive/master.zip) and not those from https://github.com/tronlec/three.js...

                  Your example then works beautifully! I just needed to add

                  mesh = object
                  

                  before the line

                  scene.add(object)
                  

                  for the quickitemtexture example to work completely, since function paintGL(canvas) expects the object to be referenced by the variable mesh.

                  function paintGL(canvas) {
                      mesh.rotation.x = degToRad(canvas.xRotAnim);
                      mesh.rotation.y = degToRad(canvas.yRotAnim);
                      mesh.rotation.z = degToRad(canvas.zRotAnim);
                      mesh.position.x = (canvas.yRotAnim - 120.0) / 120.0;
                      mesh.position.y = (canvas.xRotAnim -  60.0) / 50.0;
                      mesh.position.z = -7.0;
                      renderer.render( scene, camera );
                  }
                  

                  Thanks again!

                  I Offline
                  I Offline
                  IPO_DEV
                  wrote on last edited by IPO_DEV
                  #8

                  @Diracsbracket ok thanks for your feedback, glad that it works for you, so have fun :-)
                  p.s. you might want to add light sources to the scene in order for the model to appear not completely black

                  DiracsbracketD ShaeS 2 Replies Last reply
                  0
                  • I IPO_DEV

                    @Diracsbracket ok thanks for your feedback, glad that it works for you, so have fun :-)
                    p.s. you might want to add light sources to the scene in order for the model to appear not completely black

                    DiracsbracketD Offline
                    DiracsbracketD Offline
                    Diracsbracket
                    wrote on last edited by
                    #9

                    @IPO_DEV said in Using three.js in my Qt QML Program:

                    you might want to add light sources to the scene in order for the model to appear not completely black

                    Thanks, I wondered why the texture looked black like that^^. Now I know.

                    1 Reply Last reply
                    0
                    • I IPO_DEV

                      @Diracsbracket ok thanks for your feedback, glad that it works for you, so have fun :-)
                      p.s. you might want to add light sources to the scene in order for the model to appear not completely black

                      ShaeS Offline
                      ShaeS Offline
                      Shae
                      wrote on last edited by
                      #10

                      @IPO_DEV Hi IPO_DEV , I wanna use three.js the newest version r99. but I copy the qt example to r99 ,can not find the THREE type ? only use the r74 version can run it successful . how can I do to run this qt canvas 3d demo in three.js r99

                      1 Reply Last reply
                      0

                      • Login

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • Users
                      • Groups
                      • Search
                      • Get Qt Extensions
                      • Unsolved