Group And Animate Meshes

Hi, I animate a cone (positions xyz, rotations xyz and scale xyz).
For now I create 4 meshes (external-cyan, base-white, internal-left-red, internal-right-texture) and animate them separately.

geometry.setAttribute(‘position’, new THREE.BufferAttribute( positions, 3));

It works, but now I would like to group these 4 meshes in one only object and animate the whole object in one shot e.g.

cone.rotation.x = rotX;

Can I merge the meshes in one and keep different materials on each single mesh (external, base, internal left and internal right)?

Furthermore I have to animate the cone angle and get geometries like the one here attached. This means that the “external” mesh geometry changes and the “base” mesh geometry changes too.
I guess I can use the vbo draw range method

geometry.setDrawRange = { start: 0, count: lastVertexIndex };

But If I merge the geometries in one only mesh, does it still work? Should I change the start/count index with a mere sum? How to animate the two surfaces (external and base) at the same time?

Which the best structure to give to my cone?

That’s what you get, merging 4 geometries (cone, circle, two triangles): https://jsfiddle.net/prisoner849/jan1zxvd/

изображение

1 Like

Thank you!
That’s a great improvement. Now I know how to group meshes.
I’m still asking myself how to animate the angle phiLength along the time. Let’s say I have a vector phiLengths[frame] and I get the single value phiLength a the frame x in the animate function.

How to animate the geometries g, cg and eg within the mesh o?
I think about something like

o.gs.g.phiLength = phiLengths[frame];
o.gs.cg.phiLength = phiLengths[frame];
o.gs.eg.applyAxisAngle = phiStart + phiLengths[frame];

or something like

o.gs.g.setDrawRange = { start: 0, count: lastVertexIndex calculated on phiLengths[frame]};

  1. You can re-build a geometry with the new parameters.
  2. Modify material shaders, passing angle parameters in uniforms and processing them there.

Should I re-build the geometry at any frame, which means 60 times per second?
I think this would slow down the rendering performance.

On my OpenGL application I just glDrawRangeElements of the VBO from-to index to draw just the geometry I need on that frame but the whole geometry stays stuck. So at any frame I just set a new “from-to” indexes. That’s really fast.

Is a way to archive this on Three.js?
I saw a similar approach with

geometry.setDrawRange = { start: 0, count: lastVertexIndex };

but how can I access the single geometry once they have been merged? Should I store a pointer for each single geometry before I merge it?

I would build a custom single geometry and used a modified material to control the angle of slice.

Merging BufferGeometries is a great thing, but as you can see it also involves some effort.

But then: 1.You can re-build a geometry with the new parameters.

A completely different approach is to create the entire geometry as a single custom geometry. Then you can make the vertices dynamic.

Examples from the Collection of examples from discourse.threejs.org

https://hofk.de/main/discourse.threejs/2018/SwingingPolygon/SwingingPolygon.html
https://hofk.de/main/discourse.threejs/2020/ColorWave/ColorWave.html

I also use this technique in the addon Addon to create special / extended geometries

Sorry, I couldn’t resist and it was fun to build this. :slight_smile:
A hand-crafted custom geometry + modified material: https://jsfiddle.net/prisoner849/qtds0713/

PS It’s not the ultimate solution. It’s just an idea/concept/option.

2 Likes

Yeah, it seems to run fast. Let me run some test with at least 50 objects like this one. Thanks.

Works well with InstancedMesh (1000 instances): https://jsfiddle.net/prisoner849/m2v4rfnc/

1 Like

Because you always can not resist, I have a lot of work. But I like to do it. :slightly_smiling_face:

This year you have contributed more than 40 basic examples to the Collection of examples from discourse.threejs.org .
:+1: :+1: :+1:

More than any other author.
:1st_place_medal:

You have helped many users with this. For this you deserve great thanks.

There are also excellent things from you in the extended examples.

Thanks, keep it up!

2 Likes

Thanks, Klaus!

:open_mouth:
Well, it’s all because of our great community :slight_smile:

Everyone is breathtaking
изображение

Wow! That’s great. But I can’t change the theta angle on this sample.
Anyway, my very best! :medal_sports:

In the last example, parameters for theta are set in an instanced buffer attribute theta, individually for each instance.

g.setAttribute("theta", new THREE.InstancedBufferAttribute(new Float32Array(theta), 2));