You can create a self defined indexed BufferGeometry and then position the vertices as time dependent as you like.
https://threejs.org/docs/index.html#api/en/core/BufferGeometry
To apply changes
https://threejs.org/docs/index.html#manual/en/introduction/How-to-update-things
A simple example without time changes
https://hofk.de/main/discourse.threejs/2017/Indexed%20BufferGeometry/Indexed%20BufferGeometry.html
another
https://hofk.de/main/discourse.threejs/2019/ColorStripeChanging/ColorStripeChanging.html
From these examples you might be able to use parts.
From the Collection of examples from discourse.threejs.org
https://hofk.de/main/discourse.threejs/2017/index2017.html
https://hofk.de/main/discourse.threejs/2017/Round-edged%20box%203/Round-edged%20box%203.html
https://hofk.de/main/discourse.threejs/2017/Round-edged%20box%202/Round-edged%20box%202.html
https://hofk.de/main/discourse.threejs/2019/ShapeWithOutline/ShapeWithOutline.html
https://hofk.de/main/threejs/sandboxthreeg/MagicBoxTHREEg.html example No. 7, 15 are dynamic
A code snippet from my program where the verices are updated.
Beforehand you calculate the coordinates as desired.
g.faceIndices = new Uint32Array( faceCount * 3 );
g.vertices = new Float32Array( vertexCount * 3 );
g.setIndex( new THREE.BufferAttribute( g.faceIndices, 1 ) );
g.setAttribute( 'position', new THREE.BufferAttribute( g.vertices, 3 ).setDynamic( true ) );
…
function xyzSet( x, y, z ) {
posIdx = vIdx * 3; // (vIdx vertex index)
g.vertices[ posIdx ] = x; // set vertex position
g.vertices[ posIdx + 1 ] = y;
g.vertices[ posIdx + 2 ] = z;
}
g.attributes.position.needsUpdate = true;
g.attributes.normal.needsUpdate = true;
adapted from https://hofk.de/main/threejs/sandboxthreef/