Simultaneously animated cubes using KeyFrameTracks in ThreeJS - animation

I would like to display two different cubes animated via KeyFrameTracks. Following examplary KeyFrame Three.js code has been adopted. How can I integrate a second animated cube moved via KeyFrameTracks? Thx
// create an animation sequence with the tracks
// If a negative time value is passed, the duration will be calculated from the times of the passed tracks array
var clip = new THREE.AnimationClip( 'Action', 3, [ scaleKF, positionKF, quaternionKF, colorKF, opacityKF ] );
// setup the AnimationMixer
mixer = new THREE.AnimationMixer( mesh );
// create a ClipAction and set it to play
var clipAction = mixer.clipAction( clip );
clipAction.play();

The idea is to use AnimationObjectGroup. An instance of this class represents a group of objects that receives a shared animation state. After creating the group, you add the respective meshes to it. In the next step, you pass this group to the animation mixer as its root object.
const animationGroup = new THREE.AnimationObjectGroup();
animationGroup.add( mesh1 );
animationGroup.add( mesh2 );
const mixer = new THREE.AnimationMixer( animationGroup );
https://threejs.org/examples/misc_animation_groups
three.js R104

Related

threejs render text on or next to object

How can I put a text next or in front of it or on its surface with three.js?
If I plot a object like a box, I'd like to give this object a visible name (so similar to tooltip, but always staying visible). Would be great if text size is adjusting to distance like object size.
const geometry = new THREE.BoxGeometry( 1, 1, 1 );
const material = new THREE.MeshBasicMaterial( {color: 0x00ff00} );
const cube = new THREE.Mesh( geometry, material );
scene.add( cube );
I'm using three.js with react-force-graph to render a diagram. Objects within it are rendered with three.js
https://threejs.org/docs/#api/en/geometries/BoxGeometry.parameters
Two ways to draw text with three.js. First, create a div element, set its position (In your case, you need to write code to calculate the position relative to the canvas according to the position of camera and 3d object). Second, create a text texture.

ThreeJS: Play KeyFrameTracks of different animations

I have two cubes and one KeyFrameTrack per cube (with different changing time and position data for each cube). I would like to display the KeyFrameTracks with following code:
// mesh of cube one
mixer = new THREE.AnimationMixer( mesh );
// cube two
mixer1 = new THREE.AnimationMixer( mesh1 );
var clipAction = mixer.clipAction( clip );
var clipAction1 = mixer1.clipAction( clip1 );
clipAction.play();
clipAction1.play();
However, only the first „clip“ gets played. How can I play both clips at the same time?
Thank you.

three js recalculate vector 3 to child object

I have Vector3 in position.
I have scene childs:
planet = new THREE.Object3D();
city= new THREE.Object3D();
street= new THREE.Object3D();
scene.add(planet);
planet.add(city);
city.add(street);
how can i get correct world position of vector in each object(planet,city and street individually), with respect to position,scale and rotation of each object..
i try planet.worldToLocal(new THREE.Vector3( vector.x,vector.y,vector.z ) but it seem to work only from global to child object, not for recalculating from planet to city.
example:
planet.position.set(10,0,0);
city.position.set(10,0,0);
street.position.set(10,0,0);
if myVector is new THREE.Vector3(0,10,0), i need to get the same position in street object, that should be (30,10,0) how to get it by THREE functions??
You can get the world position of an object like so:
var position = object.getWorldPosition(); // creates a new THREE.Vector3()
or
var position = new THREE.Vector3();
object.getWorldPosition( position ); // reuses your existing THREE.Vector3()
Note: If you have modified the position/rotation/scale of any of the objects in the hierarchy since the last call to render(), then you will have to force an update to the world matrices by calling scene.updateMatrixWorld(). The renderer calls this for you, otherwise.
three.js r.71
I guess you want to use Vector3.add in combination with getWorldPosition():
planet.position.set(10,0,0);
city.position.set(10,0,0);
street.position.set(10,0,0);
myVector = new THREE.Vector3( 0, 10, 0 );
myVector.add( street.getWorldPosition() );
console.log( myVector ); // 30, 10, 0

How to find the scene position of an object, within a rotating parent object

Within my THREE scene i have an Object that rotates. The child object is positioned at (92,92,92) within the rotating Object, so it orbits the centre position (0,0,0) is a spherical path with my mouse movement. How can i find the global position of the child object in respect to the scene as it rotates. I'm fairly new to THREE.js and thankful for any support in advance.
My code:
ObjectParent = new THREE.Object3D();
scene.add( ObjectParent );
ObjectChild = new THREE.Object3D();
ObjectParent.add( ObjectChild );
ObjectChild.position.set(92,92,92);
Render:
ObjectParent.rotation.y -= (target.y + ObjectParent.rotation.y) * 0.08;
ObjectParent.rotation.x += (target.x - ObjectParent.rotation.x) * 0.07;
ObjectParent.updateMatrixWorld();
scene.updateMatrixWorld();
First of all, you usually do not need to call
ObjectParent.updateMatrixWorld();
scene.updateMatrixWorld();
inside your render loop. The renderer will do that for you.
To find the world position of a child object, you can use this pattern:
var vector = new THREE.Vector3();
...
vector.setFromMatrixPosition( child.matrixWorld );
The renderer should have previously updated the scene matrices for you. If you have changed a parent's position since the last rendering, you will have to first call
parent.updateMatrixWorld();
to update the relevant matrices.
It is a good idea to look at the three.js source code so you understand what these functions do.
three.js r.67

Three.js - move custom geometry to origin

I have some custom geometries obtained from a STEP file conversion and I use the mouse to rotate them. They rotate around the origin of the scene, but since they are far from it, they seem rotating on a virtual sphere. How can I move them to the origin so that they don't seem "floating" around (I mean that I'd like to reduce to zero the radius of the virtual sphere). This is the example I'd like to move. I've tried setting their position to (0, 0, 0) doing:
object.position.x = 0;
object.position.y = 0;
object.position.z = 0;
but it didin't work.
The typical solution to this problem is to translate the geometry right after it is created. You do that by applying a translation matrix to the geometry like so:
geometry.applyMatrix( new THREE.Matrix4().makeTranslation( distX, distY, distZ ) );
EDIT: You can simply do this, instead:
geometry.translate( distX, distY, distZ ); // three.js r.72
The function geometry.computeBoundingBox() may be of help to you in determining an amount to translate.
However, I see in your case, you have multiple geometries, so it it a bit more complicated, but doable. You will need to translate each geometry by the same amount.
EDIT
Tip: Instead of adding each object to the scene, create a parent object, add it to the scene, and then add the objects to the parent.
var parent;
parent = new THREE.Object3D();
scene.add( parent );
parent.add( object1 );
parent.add( object2 );
// and so on...
Then in your render function, just rotate the parent, not the individual objects.

Resources