Hey guys, I’ve been developing a small project in my spare time. Its an interactive solar system that is an almost 1:6 scale of ours. So it is still quite big. The structure of the solar system is quite simple it starts at a root object and parents and children reference each other. So If I move the root object all objects will move, If i select a child object with the mouse the object is brought to the camera and you can rotate around and zoom into the surface… This is how I utilize a floating origin point. Allowing for things like Shaders to function on all the planets and moons. It works great and is fast. However im having issues with controls and the scale to allow a user to navigate effectively.
What im currently trying to do is use the WASD keys to move the root object around the scene on the x, z axis (Forward, Back, Left and right if looking top down). That is working fine. However for navigation is cumbersome. As as soon as you rotate the camera the root objects movement reference is not updated and so If you rotate 45deg clockwise with the camera W is now Left. I’ve been trying to figure out how to keep WASD movement relative to the cameras view. So the A key will always move the root object to the left of the camera. W will always move up. But this should also take into consideration camera panning or ignore it. Im not sure how to go about it.
const moveSpeed = 1000000;
const keyMap: Record<string, boolean> = {
w: false,
a: false,
s: false,
d: false
};
const _camera = scene.activeCamera as BABYLON.ArcRotateCamera;
const movement = new BABYLON.Vector3(0,0,0);
const x = moveSpeed * Math.sin(rootObject.rotation.y);
const z = moveSpeed * Math.cos(rootObject.rotation.y);
if (keyMap['w']) {
movement.x = x;
movement.z = z;
}
if (keyMap['a']) {
movement.x = -x;
movement.z = -z;
}
if (keyMap['d']) {
// Ignore this.. was old method
movement.x = -Math.sin(camera.rotation.y);
movement.z = -Math.cos(camera.rotation.y);
}
if (keyMap['s']) {
// Ignore this.. was old method
movement.x = -Math.cos(camera.rotation.y);
movement.z = Math.sin(camera.rotation.y);
}
movement.normalize();
movement.scaleInPlace(scene.getEngine().getDeltaTime());
rootObject.position.addInPlace(movement);
Key presses been listened by the actionManager. And from the _camera onwards is inside a registerBeforeRender
Edit 2… So close now. W and S are consistent. If the camera is above the sphere it will always go to the top and if you pan the camera level with the sphere it will always move away from the camera. S does the opposite.