I am starting to learn this awesome library and I am totally in love. I followed a couple of tutorials and managed to import my 3d model (obj extension) just fine.
But when I want to import the .mtl file as well, nothing happens just a black screen.
Could anyone please explain me what I am doing wrong?
working code (without materials):
loader.load(
'scene.obj',
function ( object ) {
scene.add( object );
},
function ( xhr ) {
console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );
},
function ( error ) {
console.log( 'An error happened' );
}
);
Code that is not working:
let materialLoader = new THREE.MTLLoader();
materialLoader.load('scene.mtl', function(materials){
materials.preload();
let objectLoader = new THREE.OBJLoader();
objectLoader.setMaterials(materials);
objectLoader.load('scene.obj', function(mesh){
scene.add(mesh);
});
});
Unfortunately, I do not receive any errors or warnings in my developers console, and thus I have no clue where to look.
I hope someone can help me out with this matter.
Best regards
P.S. Link to my code: http://159.69.213.164/3d/
Related
i tried to import a 3D model but I'm not sure if i m doing in right way.
var loader = new THREE.GLTFLoader();
loader.load('./CesiumMilkTruck.gltf',
function (gltf) {
scene.add(gltf.scene);
gltf.animations;
gltf.scene;
gltf.scenes;
gltf.cameras;
gltf.asset;
},
function (xhr) {
console.log((xhr.loaded / xhr.total * 100 ) + '% loaded' );
},
function (error) {
console.log( 'An error happened = ', error );
}
);
my html is
<script type="text/javascript" src="js/three.min.js"></script>
<script type="text/javascript" src="js/GLTFLoader.js"></script>
I download the model on this page :
link
in particular i download the three files:
CesiumMilkTruck.gltf
CesiumMilkTruck.png
CesiumMilkTruck0.bin
I had this errors:
An error happened = SyntaxError: "JSON.parse: unexpected character at
line 7 column 1 of the JSON data" parse
file:///C:/Users/an/Desktop/master/js/GLTFLoader.js:157
load file:///C:/Users/an/Desktop/master/js/GLTFLoader.js:75
load file:///C:/Users/an/Desktop/master/js/three.min.js:715
What I m wrong?
Sorry for my question, but is my first time with Threejs.
It's possible you have an issue with the GLTF model, perhaps corrupted?. The error message would lead me to believe that the formatting of the GLTF file is incorrect (it's all numerical).
Here is a code excerpt from my flight simulator I'm building with Threejs and Konva.js: https://github.com/mpaccione/everest_flight_sim
In the code below I load in a helicopter model, turn it wireframe, and add it to a group which contains the first person camera so it seems you are flying a helicopter.
I'm using commonJS modules with browserfy for this project.
const GLTFLoader = require('three-gltf-loader'),
miniModelLoader = new GLTFLoader();
// Load Helicopter Model
miniModelLoader.load( './src/models/helicopter/scene.gltf', function(gltf){
miniModel = gltf.scene;
miniModel.name = "miniHeli"
miniModel.rotation.y = -90 * Math.PI / 180; // Radians
miniModel.position.set( 0, 0, 0 );
let miniModelMesh = miniModel.children[0].children[0].children[0],
miniModelMeshArr = [ miniModelMesh.children[0], miniModelMesh.children[1], miniModelMesh.children[2] ];
for (var i = miniModelMeshArr.length - 1; i >= 0; i--) {
miniModelMeshArr[i].material.wireframe = true;
}
miniHeliGroup.add( miniModel );
} )
this.loadMyModel = function(){
const loader2 = new THREE.GLTFLoader();
// Load a glTF resource
loader2.load(
// resource URL
'Duck.gltf',
// called when the resource is loaded
function ( gltf ) {
//alert('success');
this.scene.add( gltf.scene );
})
};
The js files have been included.
I got an error, but I don't know why:
TypeError:undefined is not an object (evaluating 'this,scene.add')
Inside of your callback function, this is not the same as outside of the function. For more information on how this works in JS, I'd suggest this article: http://www.digital-web.com/articles/scope_in_javascript/
To fix the issue, you should save a reference to the scene outside the callback:
var scene = this.scene;
this.loadMyModel = function () {
// ...
loader.load( 'foo.glb', function ( gltf ) {
scene.add( gltf.scene );
} );
}
Alternatively, using newer JS features like arrow functions will also get around this problem.
I've been hitting myself overhead with this one for the good three hours now..
My question is, would someone be kind enough to reorganize my example in such a way, that the object that I load comes with a color, any color
var loader = new THREE.OBJLoader()
loader.load( 'learning/exported1.obj', function ( object )
{
object.traverse( function (child)
{
if ( child instanceof THREE.Mesh )
{
child.material.color.setHex( 0xffffff );
}
}
var OBJBoundingBox = new THREE.Box3().setFromObject(object);
OBJBoundingBox.center(object.position);
object.position.multiplyScalar(-1);
object.position.x = object.position.x;
object.position.y = object.position.y;
object.position.z = object.position.z;
scene.add( object );
}, onProgress, onError );
If I throw the traverse part away the object is loaded successfully but is a simple white color, with it, the object does not appear on my screen...
<script src="../build/three.js"></script>
<script src="js/loaders/OBJLoader.js"></script>
<script src="js/controls/OrbitControls.js"></script>
<script src="js/shaders/CopyShader.js"></script>
<script src="js/shaders/SMAAShader.js"></script>
<script src="js/postprocessing/EffectComposer.js"></script>
<script src="js/postprocessing/SMAAPass.js"></script>
<script src="js/postprocessing/RenderPass.js"></script>
<script src="js/postprocessing/MaskPass.js"></script>
<script src="js/postprocessing/ShaderPass.js"></script>
<script src="js/libs/dat.gui.min.js"></script>
These are my imports in case you think the problem lies in here
Thanks so much in advance, this is a project which I'm developing independently and would love it if I can get it working!
I feel like an idiot but the thing I was missing was
);
at the end of object.traverse function
var loader = new THREE.OBJLoader()
loader.load( 'learning/exported1.obj', function ( object )
{
object.traverse( function (child)
{
if ( child instanceof THREE.Mesh )
{
child.material.color.setHex( 0xffffff );
}
});
// ^This over here^
var OBJBoundingBox = new THREE.Box3().setFromObject(object);
OBJBoundingBox.center(object.position);
object.position.multiplyScalar(-1);
object.position.x = object.position.x;
object.position.y = object.position.y;
object.position.z = object.position.z;
scene.add( object );
}, onProgress, onError );
Assigning a material now works perfectly with this code.
with the loader bellow the obj and mtl files are loaded, so how can I access the material and make it doublesided?
If I use mtlLoader.setMaterialOptions({side: THREE.DoubleSide}) as in the following threejs.org documentation page, it doesn't work -and I'm not getting any hinting from VScode about the .setMaterialOptions either.
https://threejs.org/docs/#examples/loaders/MTLLoader
Here's the main part of the obj+mtl loader:
var mtlLoader = new THREE.MTLLoader();
mtlLoader.setPath( 'female02/' );
//mtlloader.setMaterialOptions(side:THREE.DoubleSide)
mtlLoader.load( 'female02.mtl', function( materials ) {
materials.preload();
var objLoader = new THREE.OBJLoader();
objLoader.setMaterials( materials );
objLoader.setPath( 'female02/' );
objLoader.load( 'female02.obj', function ( object ) {
object.position.set( 0, -95, 0 );
sceneRTT.add( object );
}, onProgress, onError );
});
[and I can't add the main keyword "doublesided" because I lack... reputation]
In MTLLoader.setMaterialOptions( options ), the options argument is an object, so you must pass it as such.
loader.setMaterialOptions( { side: THREE.DoubleSide } );
three.js r.89
Am I able to add progress event listener to THREE.OBJMTLLoader?
I've tried this but it didn't work...
var callbackProgress = function( progress, result ) {}
var loader = new THREE.OBJMTLLoader();
loader.callbackProgress = callbackProgress;
loader.load(...);
Unless the signature has changed this should work :
loader = new THREE.OBJMTLLoader();
loader.load
(
'thefile.obj',
'thefile.mtl',
function ( object )
{
// onload ...
scene.add( object );
animate();
},
function ( progress, result )
{
console.log (100 * progress.loaded / progress.total);
}
);