Closed sguimmara closed 3 months ago
I think this is something that's fairly easily handled in user-applications. There are many ways to improve or speed up raycasting and I don't think it's reasonable to expect three.js to lean too far into supporting any specific approach since there is no one size fits all solution.
Some of the more obvious methods are:
Mesh.raycast
function on the objects you want to behave differently.I think we can close this for now until it's understood why these other solutions aren't viable.
Sorry for the late reply. The main issue is that the main function to compute raycasting against meshes is the method Mesh._computeIntersections()
. This method has several issues:
_computeIntersections( raycaster, intersects, rayLocalSpace ) {
let intersection;
const geometry = this.geometry;
const material = this.material;
...
}
So as a user, if I want to circumvent those limitations, I have to copy/paste this code and modify it, which I want to avoid.
It might be nice to modularize some of these internal functions with more simple APIs but it's not immediately clear to me how that can be done without likely sacrificing some performance. It's also not the case, though, that you have to copy and paste code or rely on private functions to do what you're suggesting. You can just as easily use a temporary mesh instance to perform the raycasting which is what is done in BatchedMesh (see here and here).
It might be nice to modularize some of these internal functions with more simple APIs but it's not immediately clear to me how that can be done without likely sacrificing some performance. It's also not the case, though, that you have to copy and paste code or rely on private functions to do what you're suggesting. You can just as easily use a temporary mesh instance to perform the raycasting which is what is done in BatchedMesh (see here and here).
Indeed, but having to create a whole new mesh with an useless material feels a bit clunky.
Description
Currently, calling
Mesh.raycast()
will use the.geometry
of the mesh for raycasting purposes. However, in some cases it might be useful to specify another geometry (for example, a simplified convex hull geometry).Currently, the only way to do that is if the simplified geometry is its own mesh in the scene graph (as a child of the renderable mesh). The renderable mesh would then override
raycast()
to raycast the simplified mesh instead.However, since the simplified mesh is not renderable, adding it to the scene graph is superfluous and might lead to performance overhead (even if the mesh is not
visible
).Solution
A possible solution would be to extract the mesh raycasting logic in a helper (that
Mesh
would use). Something like:This way, any object would be able to perform mesh intersection tests without having a geometry itself, or maybe if it has to use a different geometry than the renderable one.
An additional benefit is that currently the implementation of
raycast()
by the mesh checks if the material is visible, and does not perform the raycast if the material is not visible. TheMeshRaycaster
helper does not care about the material, so this logic could be circumvented for geometries used purely for raycasting.Alternatives
Another possibility would be to add options to
Mesh.raycast()
, to allow for overriding the geometry used:However this would change the API (although not a breaking change), so it is less elegant than the helper solution.
Additional context
When raycasting against complex geometries, we might want a simplified geometry for raycasting purposes.
For example, the Unity3D game engine distinguish between the collider component of the GameObject (which can have its own mesh) and the renderable mesh.