how to animate gltf model using three.js - three.js

I am trying to animate my 3d model, which is a gltf model. I am trying it and getting but not sure what could have been wrong in code.
// Load a glTF resource
loader.load(
// resource URL
"human-small-with-uniform-and-lighting-all.gltf",
// called when the resource is loaded
function(gltf) {
console.log(gltf.animations[0]);
mixer = new THREE.AnimationMixer(gltf.scene);
action = mixer.clipAction(gltf.animations[0]);
action.play();
scene.add(gltf.scene);
},
function(xhr) {
console.log((xhr.loaded / xhr.total) * 100 + "% loaded");
},
function(error) {
console.log("An error happened");
}
);
This is json structure of gltf.animations, right side of image

Related

Keeping reference to .gltf model after loading it in in Three.js

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?

Import 3D model Threejs

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 );
} )

How can do uniformly (same sized checker boxes) of custom checkered texture image which applied on all objects of Model which loaded in Three Js?

I have loaded one model (obj file) in three js and applied custom checker texture image on all objects. Texture is applied on Model. But, issue is that - checker are not like uniformly - some checker are look small and some are look larger.
Here is link of screenshot.
Is there any way to fix it ? I mean - any calculation on geometry or any in-built properties of texture etc. in three js.
Here is link of model file Model.obj
loaded this model in three js and applied texture image.
// Below some code which I have tried.
function loadModel() {
object.traverse( function ( child ) {
if (child.type.toLowerCase() == "mesh" && child.material) {
if (child.material.length) {
for (var i=0; i < child.material.length; i++) {
child.material[i].map = texture;
child.material[i].needsUpdate = true;
}
}
else {
child.material.map = texture;
child.material.needsUpdate = true;
}
}
} );
scene.add( object );
}
manager = new THREE.LoadingManager( loadModel );
manager.onProgress = function ( item, loaded, total ) {
console.log( item, loaded, total );
};
textureLoader = new THREE.TextureLoader( manager );
texture = textureLoader.load(currentTextureUrl); // texture checker image
texture.onUpdate = true;
function onProgress( xhr ) {
if ( xhr.lengthComputable ) {
var percentComplete = xhr.loaded / xhr.total * 100;
console.log( 'model ' + Math.round( percentComplete, 2 ) + '% downloaded' );
}
}
function onError() {}
var loader = new THREE.OBJLoader( manager );
loader.load(modals.currentModal.objectFile, function ( obj ) {
object = obj;
}, onProgress, onError );

I can't load the model using GLTFLoader

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.

Artifacts in loaded texture - Three js

I am trying to render an object with UV maps and updating the texture with a loaded image thru Three JS. My problem is, I'm having artifacts on the rendered result. Why does this happen?
Notes:
Object is from a gltf file
I used blender for creating the model
I used KhronosGroup's blender gltf exporter for exporting the model
Image texture is 3239x2745 big
Here's my code
var inside_image = load_image("texture/inside.jpg");
var outside_image = load_image("texture/outside.jpg");
var textures = [];
Promise.all([inside_image, outside_image]).then((images)=>{
console.log('image', images);
for (var i in images) {
var canvas = document.createElement('canvas');
var compositeTexture = new THREE.Texture(canvas);
compositeTexture.wrapS = compositeTexture.wrapT = THREE.RepeatWrapping;
compositeTexture.repeat.y = -1;
var ctx = canvas.getContext('2d');
canvas.width = images[i].width;
canvas.height = images[i].height;
ctx.globalCompositeOperation = 'source-over';
ctx.fillRect(0,0,0,0);
ctx.drawImage(images[i], 0, 0, images[i].width, images[i].height);
compositeTexture.needsUpdate = true;
textures.push(compositeTexture);
}
loader.load(
'http://local.webgl.com/model.gltf',
function ( gltf ) {
console.log('gltf', gltf);
gltf.scene.traverse( function ( child ) {
if ( child.isMesh ) {
if (child.material.name == "Inside") {
child.material.map = textures[0];
} else {
child.material.map = textures[1];
}
console.log('child', child);
}
});
scene.add(gltf.scene);
// mixer = new THREE.AnimationMixer(gltf.scene);
// animations = gltf.animations;
},
// called when loading is in progresses
function ( xhr ) {
console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );
},
// called when loading has errors
function ( error ) {
console.log( 'An error happened', error );
}
);
});

Resources