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
Forum Updated to NodeBB v4.3 + New Features

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