I try to use Jasmine to automatically test some functionality. The issue I have is that I want to test a class and for that need to load a geometry for all related tests. However due to asynchronous loading at time of execution of the tests the geometry has not been loaded and is undefined and thus test cases fail. Any idea how to make sure the geometry is loaded at time of test execution? Here the snipet to load the geometry
describe("Model Class", function() {
var geometry;
beforeAll(function() {
var loader = new THREE.STLLoader();
loader.load( '../tests/testdata/cube_big.stl', function ( geo ) {
geometry = geo;
});
});
I believe the beforeAll() function takes one argument that you can call when async operations are complete:
beforeAll(function(done) {
var loader = new THREE.STLLoader();
loader.load( '../tests/testdata/cube_big.stl', function ( geo ) {
geometry = geo;
done();
});
});
Related
I want to load a model in my scene, and the loading works well, but I want to keep a reference to it, so I can edit position and other variables later.
As you can see by the naming, the model is a boat. (not that that matters a whole bunch)
When I write the code like this it works, and I can edit the scale of the model:
function Boat(scene, loader) {
var boatObject;
this.SpawnBoat = function() {
loader.load('resources/SimpleBoat.gltf', handleLoad,
undefined, function (error) {
console.error(error);
});
}
function handleLoad(gltf) {
boatObject = gltf.scene;
scene.add(boatObject);
boatObject.scale.set(0.1,0.1,0.1);
} }
However, when I want to edit the variable after it's been loaded it says the variable is "undefined" and won't run the code.
function Boat(scene, loader) {
var boatObject;
this.SpawnBoat = function() {
loader.load('resources/SimpleBoat.gltf', handleLoad,
undefined, function (error) {
console.error(error);
});
boatObject.scale.set(0.1,0.1,0.1);
}
function handleLoad(gltf) {
boatObject = gltf.scene;
scene.add(boatObject);
} }
The boat function is called as followed, in a module that has reference to Three.js and GLTFLoader
const loader = new GLTFLoader();
const boat = new Boat(scene, loader);
const boatModel = boat.SpawnBoat();
Is there a way I can keep reference to the loaded model so I can edit proporties later?
been stuck for hours trying to figure out how to make my 3d model spin like a coin spinning. my code is below anything help i really appreciate you guys.
// add a light
const light = new THREE.AmbientLight(0xffffff,5)
scene.add(light);
// controls
// load object
const loader = new THREE.GLTFLoader();
loader.load('yattee.gltf', function (gltf) {
scene.add(gltf.scene);
})
const render = function() {
requestAnimationFrame(render)
// camera.rotation.z += .0010
renderer.render(scene, camera);
}
render();
Try it like so:
let myModel;
const loader = new GLTFLoader();
loader.load( 'model.gltf', function ( gltf ) {
myModel = gltf.scene;
scene.add( myModel );
} );
const render = function() {
requestAnimationFrame(render)
if ( myModel ) {
myModel.rotation.z += 0.01;
}
renderer.render(scene, camera);
}
The problem is, you are defining the model gltf inside a function, which means that it cannot be accessed from render(). In order to spin the model, you need to define the variable gltf prior to loading the model, so it can be stored inside of it:
const loader = new THREE.GLTFLoader();
var gltf; //By defining it prior to loading, it is now in global scope.
loader.load('yattee.gltf', function (gltf) {
scene.add(gltf.scene);
})
Then, you can add the flipping effect in the render() loop. Make sure that you add the given if statement so it doesn't crash before the model even loads!
const render = function() {
requestAnimationFrame(render);
if(gltf) {
gltf.rotation.z += .0010; //Make sure you rotate the gltf, not the camera.
}
renderer.render(scene, camera);
}
And that should do it!
Note: I've taken a look at some of the other answers, and it seems like they either don't work, or they don't explain what they are doing properly. I think that this should help you achieve what you want.
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.
Does anybody knows how can i acess a object outside a OBJMTLLoader
var loader = new THREE.OBJMTLLoader();
loader.load( obj, mtl, function ( object ) {
object.position.set(0,0,0);
scene.add( object );
});
console.log(object);
inside of the function objects = THREE.Object3D but outside is equal do ObjectLoad.
Thanks for everybody.
The object is simply inside the scope of the undefined function.
Set the function to return the object
var loader = new THREE.OBJMTLLoader();
loader.load( obj, mtl, function ( object ) {
object.position.set(0,0,0);
return object;//here
});
scene.add( object );
console.log(object);
I am trying to load multiple pieces simultaneously. Either only one piece shows up, correctly, or both pieces show up, with one correct and one incorrect. Here's my code:
var loader = THREE.ColladaLoader();
loader.load('model.dae', function colladaReady(result) {
var piece = result.scene.children[0];
piece.position.set(-100, 0, 0);
scene.add(piece);
renderer.render(scene, camera);
});
loader.load('model2.dae', function colladaReady2(result2) {
var piece2 = result2.scene.children[0];
piece2.position.set(100, 0, 0);
scene.add(piece2);
renderer.render(scene, camera);
});
The reason is because ColladaLoader is not thread-safe, so multiple load() calls cannot be made on the same object. Simply create a new instance of ColladaLoader like so and all should work
var loader = THREE.ColladaLoader();
loader.load('model.dae', function colladaReady(result) {
var piece = result.scene.children[0];
piece.position.set(-100, 0, 0);
scene.add(piece);
renderer.render(scene, camera);
});
/*** Line added here! ***/
var loader2 = THREE.ColladaLoader();
loader.load('model2.dae', function colladaReady2(result2) {
var piece2 = result2.scene.children[0];
piece2.position.set(100, 0, 0);
scene.add(piece2);
renderer.render(scene, camera);
});