Raycaster's not working with blender glb

Hello, I was following tutorial in the link below, and faced problem.

Everything worked well except the part when I created raycaster to object, nothing was detected.
Through the console logging, sample model shows { name: “stacy”, type: “SkinnedMesh”} when raycaster hits object however my customed blender model shows {name: “” , type: “Mesh”}.
It’s not a coding problem(because I copied every ctl+c ctl+v to find out what’s wrong), I found out when I imported sample model to blender and exported exactly the same (nothing changed), raycaster didn’t work.
Is there a proper way (or options) to export glb from blender (ver. 2.9) to Three JS?

original sample model: https://s3-us-west-2.amazonaws.com/s.cdpn.io/1376484/stacy_lightweight.glb

nothing-changed.glb (902.6 KB)

Could you share the code you are using to raycast? The issue is likely to be there and not in the model itself.

Code is here, raycaster part starts around line 200

The demo is detecting intersections every time I click the triangle or the animated character. The name of both objects just happens to be an empty string, "", I’m not sure that is your character.

Note that the ability to raycast against a SkinnedMesh instance was not added until three.js r116 (SkinnedMesh: Apply skinning while raycasting by donmccurdy · Pull Request #19178 · mrdoob/three.js · GitHub) and that your example is using a mixture of three.js r108 and r92. I’d recommend using only files from a single version, like:

<script src="https://unpkg.com/three@0.124.0/build/three.js"></script>
<script src="https://unpkg.com/three@0.124.0/examples/js/loaders/GLTFLoader.js"></script>

See three.js docs for more information on CDN usage.

Thank you for answering my question, I changed scripts to single version.
But my problem still exists. I want { name: “racer” } to appear when I click on the animated character(“racer” is the name I assigned to character object in blender). So I changed console log position to line 230. Is there a solution I can do?

I’m afraid this is a bug or limitation of the raycaster — the bounding volumes used to improve performance when raycasting are cached do not accurately fit SkinnedMesh objects. One way to work around the issue is to increase the size of the bounding volumes by some factor that you’re sure will contain the object even when animation is playing. This would be added in the model.traverse() loop in your code:

model.traverse(o => {
  if (o.isSkinnedMesh) {
    o.geometry.computeBoundingBox();
    o.geometry.computeBoundingSphere();
    o.geometry.boundingSphere.radius *= 400;
    o.geometry.boundingBox.min *= 400;
    o.geometry.boundingBox.max *= 400;
  }
  // ...
});

By scaling up the bounding volumes to be sure the click will hit them, the Raycaster will know that it should go ahead and check the click location against each triangle in the mesh. If you had many objects in the scene you would want to make sure the volumes are fairly tight to avoid checking too many triangles. Especially in models converted from FBX, the base geometry may be only 1/100th the size of the animated model after skinning is applied (check boundingSphere.radius here) so the adjustment may need to be fairly large.

See SkinnedMesh: Incorrect bounding box and culling · Issue #14499 · mrdoob/three.js · GitHub for more information about the underlying issue here.

2 Likes

I thought there would be easier solution but I will try what you suggested. Thank you for the answer.

@donmccurdy Hello Thank you very much it worked, with the tip it did the magic and I managed to get the name of the clicked object and this also managed to solve an old problem that was breaking the head to solve the missing mesh as the head when zooming in the 3d model, Thanks a lot for the help.

1 Like