I am looking for a way to orbit a moon around my planet that is orbiting my sun.
(All of these are 3d objects in three.js)
I have defined all my objects and currently have the earth rotating around my sun, but I am having difficulties getting the moon to rotate around the already rotating Earth.
sun = models['sun'];
earth = models['earth'];
moon = models['moon'];
let suns = new THREE.Group();
suns.add(sun);
let planets = new THREE.Group();
planets.add(earth);
let moons = new THREE.Group();
moons.add(moon);
scene.add(sun);
scene.add(earth);
scene.add(moon);
var orbit = 3;
var date = Date.now() * 0.0005;
earth.position.set(Math.cos(date) * orbit, 0, Math.sin(date) * orbit);
earth.rotation.y += 0.01*animation_speed;
moon.rotation.y += 0.01*animation_speed;
Expected: Earth rotates around Sun (static), while Moon rotates around Earth as it rotates around Sun.
Current: Earth rotates around Sun. Not sure what to do with moon...
it would be easy if you make a hierarchy of your objects, that way they rotate around their parents.
First note that your groups do not do anything at all: If you call suns.add(sun)
and then you call scene.add(sun)
, the second call removes the sun
from suns
and adds it to scene
, therefore your groups are empty. So in the following example, we will not use the groups.
F.e.
const sun = models['sun'];
const earth = models['earth'];
const moon = models['moon'];
const sunContainer = new THREE.Object3D
sunContainer.add(sun)
const earthContainer = new THREE.Object3D
earthContainer.add(earth)
const moonContainer = new THREE.Object3D
moonContainer.add(moon)
scene.add(sunContainer); // sunContainer is child of scene
sunContainer.add(earthContainer); // earthContainer is child of sunContainer
earthContainer.add(moonContainer); // moonContainer is child of earthContainer
var earthOrbitRadius = 3;
var moonOrbitRadius = 0.2;
// position them at their orbit radius (relative to their parents)
earthContainer.position.set(earthOrbitRadius, 0, 0);
moonContainer.position.set(moonOrbitRadius, 0, 0);
// each planet rotates around its poles
sun.rotation.y += 1*animation_speed;
earth.rotation.y += 1*animation_speed;
moon.rotation.y += 1*animation_speed;
// and each planet orbits around its parent
sunContainer.rotation.y += 0.1*animation_speed;
earthContainer.rotation.y += 0.1*animation_speed;
Now restore those bits back into your code, adjust the numbers as needed, and it should work similar to what want.
There's other ways to do it, that's just one way. To make planet rotation independent of orbit rotation, you could adjust the planet rotation with negative orbit rotation. Or, you could make the container orbit, then add sun, earth, and moon directly to scene instead of the containers, then copy the container positions to them, while they rotate independently. Or you could use a physics engine (Bullet Physics is built into Three.js). Or you can use pivot points.
By the way, it would help if you post working code. :)