Switch the geometry of a mesh in real time three.js
Asked Answered
B

6

6

I'm currently creating a mesh in three.js using the following:

sphereGeometry  = new THREE.SphereGeometry( 1, 16,16 );
mesh = new THREE.Mesh( sphereGeometry, material );

I've also created a torus:

torusGeometry   = new THREE.TorusGeometry( 1, 0.42 );

At any point in my animation loop, I want to be able to swap the sphere out for the torus. Is this possible? How do I swap one geometry for another?

Bureaucratic answered 19/6, 2013 at 22:35 Comment(1)
Did you get the geometry switching to work?Champaign
W
12

in Three.js R59, setGeometry and setMaterial were removed again from Three.Mesh

What you can do to replace geometry is removing your Mesh from Scene and creating a new one with your new geometry and your old material and add it back to your scene. This will work for sure :)

Workout answered 18/7, 2013 at 14:18 Comment(1)
how do you efficiently remove an object form the scene? Object3D.remove() does a linear scan of the children array : github.com/mrdoob/three.js/blob/master/src/core/…Czarra
F
6

Switching geometries can be costly. I would simply add both to the scene and hide / reveal based on your situation.

Fatherless answered 19/6, 2013 at 22:50 Comment(2)
How can I hide geometry?Monophysite
@BartekKosa Every THREE.Object3D has a .visible property. You can set it to false or true in real time.Stella
W
0

You can use SetGeometryCommand to change the geometry of a Mesh in realtime.

Usage:

  editor.execute( new SetGeometryCommand( object, new THREE[ geometry.type ](
        radiusTop,
        radiusBottom,
        height,
        radialSegments,
        heightSegments,
        openEnded
    ) ) );

https://github.com/mrdoob/three.js/blob/dev/editor/js/commands/SetGeometryCommand.js

Wilbanks answered 26/11, 2018 at 10:16 Comment(0)
P
0

Something like this should work

// In this example we will distort a plane
let plane = new THREE.Mesh(g1, m1);
plane.rotation.x = Math.PI * 270 / 180;
plane.position.y = 0;
plane.position.z = 0;
scene.add(plane);

// Distort plane
let positions = plane.geometry.attributes.position.array;
let count = positions.length / 3;

for (let i = 0; i < count; i++) {
    let v = new THREE.Vector3(positions[i * 3], positions[i * 3 + 1], positions[i * 3 + 2]);
    let distanceFromCenterY = Math.abs(v.x) / 100;
    v.z += distanceFromCenterY > .2 ?
         (Math.random() * (20 - .15) + .15) * distanceFromCenterY * 2 :
         (Math.random() * (.8 - .2) + .2) + distanceFromCenterY;
    
    // In this example we are updating the z coordinate or ther vertices
    plane.geometry.attributes.position.array[ i * 3 + 2 ] = v.z;
}
        
Pedagogy answered 17/12, 2021 at 5:17 Comment(0)
S
0

youre probably not supposed to do it this way, but i tried it and it works for me.

let newgeom = new BoxGeometry(width, height, depth);
mesh.geometry.setAttribute('position', newgeom.attributes.position);

If you want to be more complete, do the same for uv, normal, and any other attribute you have to set

Note: in my case, i only changed the geometry when the user specifically changed the size of the object, which isn't all the time. I don't know how performant it would be if you're changing the size every frame.

Also, the old geometry and the new geometry both had the same number of points, just in different positions.

Samy answered 20/5 at 21:12 Comment(0)
C
-2

Try looking at this: http://threejs.org/docs/58/#Reference/Objects/Mesh

Especially this method:

mesh.setGeometry(geometry)

Here is how you would do it inside your render loop (you set the flag whenever you want to swap the sphere out for the torus)

var flag;  
...
function render () {
    if (flag) {
        mesh.setGeometry(torusGeometry);
        flag = false;
    }
}
render();

If you want to flip back and forth (inside render loop):

if (conditions) { 
    mesh.setGeometry(sphereGeometry);
}

if (condition) {
    mesh.setGeometry(torusGeometry);
}
Champaign answered 19/6, 2013 at 22:48 Comment(1)
This doesn't work anymore... see answer below and accept + upvoteFatherless

© 2022 - 2024 — McMap. All rights reserved.