mrdoob / three.js

JavaScript 3D Library.
https://threejs.org/
MIT License
102.47k stars 35.36k forks source link

Add concept of bounding box and raycast to Object3D #27493

Closed tripdragon closed 10 months ago

tripdragon commented 10 months ago

Description

This is mostly a question or feature request. Why does Object3D not implement a bounding box and bounding sphere? Since Box3 can be set from the object and its objects the concept seems like the root should have the option. It would solve having to patch and process imported model files, and raycasting recursive seems expensive.

I am testing adding the members and methods and a raycast method so I can implement

raycaster.intersectObjects( items, false );

While it crops up a bunch of bugs, using this method is a more consistent api vs

const box = new Box3();
for (var i = 0; i < items.length; i++) {
  const pick = items[i];
  pick.updateMatrix();
  box.setFromObject(pick, true); // note must set second argument here to get a box that is not infinity
  const target = new Vector3();
  if( raycaster.ray.intersectBox(box, target) !== null ){
  ...stuff
  }

This above does not handle sorted by distance either though easy enough to also implement

Solution

simply to use raycaster.intersectObjects( items, false ) like Mesh objects get to use

Alternatives

none

Additional context

No response

Mugen87 commented 10 months ago

The idea is to have bounding volumes on geometry level since that's where data which define the bounding box in local space. Logic like ray casting or culling makes sure the bounding volumes get properly transformed into other spaces for intersection tests if required.

There are two exceptions regarding this policy: Certain types of 3D objects like SkinnedMesh have bounding volumes on object level since the geometry data alone are not sufficient to compute correct bounding volumes.

tripdragon commented 10 months ago

I get that, however its counter to the available workflow game engines provide. In other engines you can add a bounds or volume component to the root and tweak as needed. And since three has the Box3.setfromObject, it seems it would be an obvious next step.

In your explainer the only time its optimized is if you add a cube geometry in the case of multiple meshes, and then setup management logic to resize as needed.

tripdragon commented 10 months ago

I read your reason again and you note SkinnedMesh as having this concept directly already. Would you not argue then the same reasoning is true that a multi meshed imported model does not have sufficient singular geometry of reference to build an adequate bounding volume so a full encompassing bounding box at object level would be a proper location?

One could go further and say imported models should have a subclass of Group() and handle some data caching and special functions.

Looking though the code at https://github.com/mrdoob/three.js/blob/d04539a76736ff500cae883d6a38b3dd8643c548/src/objects/SkinnedMesh.js#L136 Swapping out the digging through mesh function routine would be a proper place for it, and since all other classes rewrite their own raycast to handle current singular geometry bounds, then nothing should really suffer.