How do I replace the geometry property of a Mesh?

I have an object that contains a list of balls (spheres). I want to add the ability to interactively change the ball radii.

Here is the method I added to do it:

replaceGeometry () {

    for (let mesh of this.balls) {

        // discard current geometry, an instance of a SphereBufferGeometry
        mesh.geometry.dispose();

        // replace with clone of a SphereBufferGeometry with a changed radius
        mesh.geometry = Globals.sceneManager.ballGeometry.clone();
    }

}

I added a helper function to the object that is called in the render loop:

renderLoopHelper () {

if (this.balls) {
    for (let mesh of this.balls) {
        mesh.geometry.attributes.position.needsUpdate = true;
        mesh.geometry.attributes.normal.needsUpdate = true;
        mesh.geometry.attributes.uv.needsUpdate = true;
    }
}

}

When I call replaceGeometry the spheres disappear. What am I missing?

Don’t. Use mesh.scale instead. :slight_smile:

If you wanna replace geometry tho, use geometry.copy(otherGeometry)

So don’t discard, just replace?

Hmmm … Hacking it up now.

Im not sure if it is necessary to dispose the geometry if you copy a new one. But if you really just wanna scale it use Mesh.scale.set(x, y, z).

Weird. Now, all I’m doing is scaling the meshes … and they just vanish. Poof! I don’t get it.

I am doing - essentially - exactly the same thing as example webgl_geometry_extrude_splines.html in setScale().

If you scale your meshes this way Mesh.scale(x, y, z), it’s wrong. Set scaling of meshes like that Mesh.scale.set(x, y, z), or Mesh.scale.setScalar(n) if you want to scale them uniformly.

2 Likes

Still no joy. Here is the code:

scaleRadius(scaleFactor) {
    for (let mesh of this.balls) {
        mesh.scale.setScalar(scaleFactor);
    }
}

Pretty simple. But the balls vanish when I can the method on the scale vector. Are there no other method calls I need to make? Maybe within the renderloop? Maybe mesh matrices that need to be poked? As a sanity check, when I comment out the scaling call the balls do not vanish, so it is clearly to do with the scaling. Frustrating.

Any chance to provide a fiddle or a pen (jsfiddle, codepen), that shows the problem?

Solved. The bug was actually nothing to do with the above code. When I construct the set of spheres I was calling geometry.translate(..) to position them in the scene rather then mesh.position.set(...). I suspect mixing geometry matrix methods and mesh matrix methods is not the way to go. Anyway, solved. Thanks for the assist y’all.

1 Like

Ah… That means the scaling applied to the offsets too. I am happy that you solved it.

It is generally discouraged to do a lot of geometry manipulation in animation. Modifying geometry will require moving much more data to the GPU than changing a transform.

Yep. It is also a lesson to - in general - prefer working at the highest level API available - mesh - rather then hacking at a lower level - geometry.

Well… If you are creating many simple objects, like in the “bird” flock examples, you may be better off modifying a geometry instead, because the many draw calls build a huge overhead.