Satellite Three.js

Satellite : Mise en orbite d’un objet 3D autours d’une cible

Mise en orbite autours d’un axe fixe

Création de l’objet 3D

Dans un premier temps, créons un simple objet 3D dans notre scène. Dans cet exemple, une sphère. Il n’est pas nécessaire de lui attribuer une position pour le moment !

// sphere
const geometry = new THREE.SphereGeometry( 1, 32, 32 );
const material = new THREE.MeshPhongMaterial( { color: 0xffffff, flatShading: false } );
sphere = new THREE.Mesh( geometry, material );
scene.add( sphere );

Calcul de la position en orbite avec Cosinus, Sinus et Clock

Nous allons utiliser les fonctions mathématiques Cosinus et Sinus, respectivement Math.cos() et Math.sin() pour mettre en orbite notre objet 3D.

A chaque exécution de notre boucle principale, il est nécessaire de mettre à jour la position de l’objet en orbite en fonction du temps écoulé. Pour garder un œil sur la montre, nous utilisons la classe Three.JS Clock.

La méthode getDelta de la classe Clock est utilisée pour obtenir le nombre de secondes écoulées depuis la dernière exécution de la méthode.

La propriété elapsedTime de la classe Clock garde en mémoire le nombre total de secondes écoulées depuis le lancement de l’application. C’est cette valeur que nous allons utiliser pour calculer la position de l’objet en orbite en fonction du temps.

A chaque exécution de la boucle principale, nous calculons la position de l’objet en orbite :

function animate()
{
	//time tracking
	var delta = clock.getDelta();
	var elapsed = clock.elapsedTime;
	
	//sphere position
	sphere.position.x = Math.sin(elapsed/2) * 3;
	sphere.position.z = Math.cos(elapsed/2) * 3;

	[...]
}

Nous souhaitons faire graviter l’objet 3D autours de l’axe Y :

Nous calculons la position sur l’axe X avec Math.sin() du temps écoulé, puis, la position sur l’axe Z avec Math.cos() du temps écoulé.

Mise en orbite autours d’une cible en mouvement

Il est également possible d’appliquer ces concepts pour la mise en orbite autours d’une cible en mouvement !

Créons un deuxième objet 3D, ici un cube :

//satelite
const geometry_satelite = new THREE.BoxGeometry( 0.4, 0.4, 0.4 );
const material_satelite = new THREE.MeshNormalMaterial( {  flatShading: true } );
satellite = new THREE.Mesh( geometry_satelite, material_satelite );
scene.add( satellite );

Nous souhaitons faire orbiter ce nouvel objet autours de la sphère en mouvement de la partie précédente. Il est donc nécessaire d’inclure la position de cette dernière dans le calcul de position du satellite, a chaque exécution de la boucle principale.

function animate()
{
	//time tracking
	var delta = clock.getDelta();
	var elapsed = clock.elapsedTime;
	
	//sphere position
	sphere.position.x = Math.sin(elapsed/2) * 3;
	sphere.position.z = Math.cos(elapsed/2) * 3;
	
	//satellite
	satellite.position.x =  sphere.position.x + Math.sin(elapsed*2) * 2;
	satellite.position.z = sphere.position.z + Math.cos(elapsed*2) * 2;
	satellite.rotation.x += 0.4 * delta;
	satellite.rotation.y += 0.2 * delta;
	
	requestAnimationFrame( animate );
	controls.update(); // only required if controls.enableDamping = true, or if controls.autoRotate = true
	renderer.render( scene, camera );
}

Résultat final

See the Pen Gravitation by Thomas (@thomassifferlen) on CodePen.

Un commentaire

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *