I have read several posts about this but I still can figure out what is happening on my code. I have a THREE.JS scene and I'm loading some GLB models in it. What I want to do is attach some data coming from JSON to each model and retrieve this data when I hover the mouse over it. My issue is that I'm getting a {}
or undefined from the raycast response whenever I hover the objects in the scene.
When I compare it to other similar questions I found, users are telling the person with the similar issue to do what I already did (using intersectObjects
and the true
flag; or adding the objects to intersect to a separate array).
This is my code for loading the models:
const dracoLoader = new DRACOLoader();
dracoLoader.setDecoderPath('jsm/libs/draco/gltf/');
const loader = new GLTFLoader();
loader.setDRACOLoader(dracoLoader);
function loadModel(loader, modelToLoad, jsonDestinationData, jsonItemInfo) {
loader.load(
modelToLoad,
function (gltf) {
const model = gltf.scene;
model.userData = {
description: jsonItemInfo.description,
type: jsonItemInfo.type
};
model.translateX(jsonDestinationData.length);
itemsToRead.push(model);
scene.add(model);
console.log(model.userData);
},
undefined,
function(e) {
console.error(e);
}
);
}
modelToLoad
is the string with the GLB file path.jsonDestinationData
is some data about where the model is going to be loaded inside the scene.jsonItemInfo
is the data coming from a json file that I want to pass to the model using model.userData
.itemsToRead
is the array of items I want to get information when I hover and the model.userData
is the information I want to retrieve from the model when hovering.From this first console.log(model.userData)
I can see the information is there. I can read the information I want printed in the console.
This is my code for the raycast:
raycaster.setFromCamera(mouse, camera);
var intersects = raycaster.intersectObjects(itemsToRead, true);
if (intersects.length > 0) {
var selectedObject = intersects[0].object;
console.log(selectedObject.userData);
}
From this second console.log(selectedObject.userData)
when the the intersect function is executed during the hover, I get the {}
printed in the console instead of the userData
I was expecting to see.
Is it possible to add the userData
to a model this way (I read in another post someone saying that it might not be possible to add userData to imported models, but no one confirmed it)? Is there something missing in the raycast function to correctly retrieve the data or for this case this operation isn't possible?
Ok, I found a solution.
I don't know if it's the only one, but it worked for the code I posted above.
I didn't found this in any other question here in the Stack Overflow, so I'm gonna leave the answer here in case anyone has a similar case. One of those suggested Google's AI answers from the top of the page when you search something was the one who pointed me in the right direction of what was missing.
The issue was in the way I was setting the userData
. Instead of setting it directly like this:
model.userData = {
description: jsonItemInfo.description,
type: jsonItemInfo.type
};
The correct way is to add the info from a success callback function inside the loader.load
. This is the code for the callback:
model.traverse((loadedModel) => {
loadedModel.userData.description = jsonItemInfo.description;
loadedModel.userData.type = jsonItemInfo.type;
}
);
And the full code previously presented after the update is:
function loadModel(loader, modelToLoad, jsonDestinationData, jsonItemInfo) {
loader.load(
modelToLoad,
function (gltf) {
const model = gltf.scene;
model.translateX(jsonDestinationData.length);
itemsToRead.push(model);
scene.add(model);
model.traverse((loadedModel) => {
loadedModel.userData.description = jsonItemInfo.description;
loadedModel.userData.type = jsonItemInfo.type;
}
);
},
undefined,
function(e) {
console.error(e);
}
);
}