How can I use MeshBVH?

Hi, I would like to use MeshBVH instead of a Mesh in my code, due to my models being too complex, when I perform drag, it causes trouble with Mesh but I was hoping that using MeshBVH would help my issue. I just cant access it, could you please help me ?

Thanks.

To use MeshBVH in your project and replace existing mesh implementations, you can follow this structured approach:

  1. Load the MeshBVH Library: Use the function loadMeshBVHLibrary to import the necessary parts from three-mesh-bvh. This ensures you have access to MeshBVH, StaticGeometryGenerator, and accelerated raycasting.

  2. Initialize the MeshBVH: When creating your object, instantiate MeshBVH and generate the bounding volume hierarchy from your geometry.

  3. Use for Raycasting: Instead of the default raycasting methods, use the accelerated raycasting capabilities provided by MeshBVH when you need to determine intersects with objects.

Here’s a sample code snippet:

import { Mesh, BufferGeometry } from 'three';
import { MeshBVH, StaticGeometryGenerator } from 'three-mesh-bvh';

// Function to set up and initialize MeshBVH
function setupMeshBVH(mesh) {
    // Ensure the geometry of the mesh is a BufferGeometry
    if (mesh.geometry instanceof BufferGeometry) {
        const staticGenerator = new StaticGeometryGenerator(mesh);
        const staticGeometry = staticGenerator.generate();

        // Generate the bounding volume hierarchy
        const bvh = new MeshBVH(staticGeometry);
        mesh.geometry.boundsTree = bvh;

        // Attach accelerated raycast method
        mesh.raycast = mesh.acceleratedRaycast.bind(mesh);
    }
}

// Example usage
const myMesh = new Mesh(yourGeometry, yourMaterial);
setupMeshBVH(myMesh);

Tips for Successful Implementation:

  • Ensure you maintain the reference to the original geometry.
  • If you are working with skinned meshes, take care of updating the geometry as needed.
  • You may need to periodically re-generate the MeshBVH if your geometry changes frequently.

Documentation and Samples

For more detailed implementation and examples, you can refer to the following resources:

If you have specific issues or errors during the integration, please share them, and I can assist you further!

1 replies left - Get a PRO license for more AI replies.
thread_VKCOQB6ImHyeDw5Iijsyi7Db
Reply to this message to continue the conversation

It crashes for me on this line of your snippet:

mesh.raycast = mesh.acceleratedRaycast.bind(mesh);

it can register that MeshBVH exists but it has problem with acceleratedRaycast as it returns it as “undefined”

It seems that the acceleratedRaycast method is not being properly referenced in your setup. This may happen if the MeshBVH is not correctly initialized or if the mesh does not support raycasting with a BVH.

Here’s a more detailed approach to resolve this issue:

  1. Ensure Proper Import of MeshBVH: Make sure you are importing MeshBVH and related classes correctly from the appropriate library.

  2. Initialize MeshBVH after Geometry Generation: Confirm that MeshBVH is initialized after generating the geometry.

  3. Use the Correct Raycasting Function: Instead of directly connecting acceleratedRaycast, you can define your custom raycasting method to handle raycasting differently.

Here’s the revised code snippet with a custom raycasting function:

import { Mesh, BufferGeometry } from 'three';
import { MeshBVH, StaticGeometryGenerator } from 'three-mesh-bvh';

function setupMeshBVH(mesh) {
    if (mesh.geometry instanceof BufferGeometry) {
        const staticGenerator = new StaticGeometryGenerator(mesh);
        const staticGeometry = staticGenerator.generate();

        // Generate the bounding volume hierarchy
        const bvh = new MeshBVH(staticGeometry);
        mesh.geometry.boundsTree = bvh;

        // Custom raycasting function
        mesh.raycast = function (raycaster, intersects) {
            if (this.geometry.boundsTree) {
                // Use the BVH for raycasting
                const intersected = [];

                // Perform the raycast using the boundsTree
                const result = this.geometry.boundsTree.intersectRay(raycaster.ray);
                if (result) {
                    intersected.push(result);
                }

                // Add to intersects array
                intersects.push(...intersected);
            } else {
                // Fallback to default raycasting method if BVH is not available
                Mesh.prototype.raycast.call(this, raycaster, intersects);
            }
        };
    }
}

// Example usage
const myMesh = new Mesh(yourGeometry, yourMaterial);
setupMeshBVH(myMesh);

Additional Checks:

  • Ensure you have the latest version of the three-mesh-bvh library, in case improvements or fixes have been made.
  • If you encounter additional errors, please provide the specific error messages or console logs for more targeted help.

Feel free to reach out for further troubleshooting!

1 replies left - Get a PRO license for more AI replies.
thread_VKCOQB6ImHyeDw5Iijsyi7Db
Reply to this message to continue the conversation

Hello, when you do a raycast with Needle Engine you already use the mesh bvh structures. They are built by the engine. So performing a raycast with this.context.physics.raycast(…) already does what you want.

Do you have an example where it’s not performing well?

Hi Marcel,
I want to use it when trying to drag a complex object like this. So the mouse cursor will catch the model even when the user is moving close to the mesh. Do you recommed using Mesh bvh or just simple bounding boxes ?

Hi, as said this is already using a bvh structure. Your team sent this scene before via a bugreport and it has too many vertices. I recommended to use either a low poly proxy mesh or testing on bounding boxes the last time.