I'm trying to make a blender-esk orientation view that looks like this using Three JS:
My plan is to take the camera rotation and rotate 3 vector points (representing the X,Y and Z bubbles in the picture). Then once I have those points I can use the X and Y coordinates to draw circles on a canvas and draw lines to connect them to the center. I can then use the Z direction to determine what should be drawn on top of what.
Currently I'm using a 2nd three.js scene to visualize the position of these X, Y and Z points as I try different ways to rotate the group of vertices to have it match the camera's orientation. I'm struggling with this part and I've tried a bunch of things that haven't worked.
Here is a JS Fiddle for where I'm currently at:
https://jsfiddle.net/j9mcL0x4/4/ (doesn't load in Brave but works in Chrome)
As you pan the camera around, it moves the 3 cubes in the 2nd scene but I cannot get it to rotate correctly.
The X, Y and Z points are represented by a group of Vector3's as such:
this.ref = [
[new THREE.Vector3(1,0,0), 0xFF0000],
[new THREE.Vector3(0,1,0), 0x00FF00],
[new THREE.Vector3(0,0,1), 0x0000FF],
]
I then create each cube and add it to a group:
this.group = new THREE.Group();
for(var pos of this.ref) {
var geometry = new THREE.BoxGeometry(.25,.25,.25);
var material = new THREE.MeshBasicMaterial({
color: pos[1]
});
var cube = new THREE.Mesh(geometry, material);
cube.position.copy(pos[0]);
this.group.add(cube);
}
this.scene.add(this.group);
Then in my animate function, I'm trying to calculate the rotation for the group to get it to be in the same orientation as the main view:
var quaternion = new THREE.Quaternion();
camera.getWorldQuaternion( quaternion );
let rotation = new THREE.Euler();
rotation.setFromQuaternion(quaternion);
var dir = new THREE.Vector3();
dir.subVectors( camera.position, controls.target ).normalize();
orientationHelper.group.rotation.set(dir.x, dir.y, dir.z);
orientationHelper.animate();
What I have is completely wrong but here are some things I've tried:
- Calculate a point in front of the camera, then use that to make the group look in that direction using the lookAt function
- I'm using orbit controls which has a target that the camera is focused on. I've tried subtracting the camera position vector and the target vector to get the look direction but this failed to work (what's currently in the jsfiddle)
- I've tried using just the camera local rotation (and tried negating it)
Note I could rotate the camera in the 2nd scene to match the camera in the main view but I really want to rotate the vectors themselves. This is so I can take those points and project them onto a basic canvas to draw 6 circles and 3 lines. I feel like this will be much easier than trying to use sprites in 3d and Three JS cannot easily draw thick lines without creating rectangular meshes for it.
Here are some examples of what I want the output to look like:
Update
This problem was solved by Rabbid76 and if anyone is interested in using a Blender Style orientation cube for their project, you can find the full source code here:
https://github.com/jrj2211/three-orientation-gizmo/
Or download it with npm:


