I am attempting to create a Blender-inspired orientation view using Three JS, as shown in the image linked below:
https://i.sstatic.net/7Ru4H.png
My approach involves rotating three vector points (representing X, Y, and Z bubbles) based on the camera rotation. I then plan to use these points to draw circles on a canvas, connecting them with lines to the center. The Z direction will determine the drawing order.
Currently, I am utilizing a secondary Three.js scene to visualize the position of these points while experimenting with different rotations to align them with the camera's orientation. So far, I have encountered challenges and attempted various strategies that have not yielded the desired results.
A demonstration of my current progress is available in this JS Fiddle:
https://jsfiddle.net/j9mcL0x4/4/ (works in Chrome but not loading in Brave)
While panning the camera, the movement affects the 3 cubes in the second scene, but I haven't been able to achieve the correct rotation.
The X, Y, and Z points are represented by a group of Vector3 objects structured as follows:
this.ref = [
[new THREE.Vector3(1,0,0), 0xFF0000],
[new THREE.Vector3(0,1,0), 0x00FF00],
[new THREE.Vector3(0,0,1), 0x0000FF],
]
To represent each cube, I construct it 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);
In my animate function, I am working on computing the necessary rotation for the group to align with 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();
My current implementation is incorrect, and I have experimented with several approaches, including:
- Calculating a point in front of the camera to direct the group using lookAt()
- Utilizing orbit controls target to determine the viewing direction
- Working with camera local rotation
Note Rather than rotating the camera in the second scene to match the primary view, I aim to rotate the vectors themselves. This would enable me to project these points onto a basic canvas for drawing circles and lines more efficiently than using sprites in 3D.
Examples of the desired output include:
https://i.sstatic.net/ALTfD.png
https://i.sstatic.net/voC7s.png
Update
Rabbid76 has successfully resolved this issue. For those interested in implementing a Blender Style orientation cube in their projects, the complete source code can be accessed here:
https://github.com/jrj2211/three-orientation-gizmo/
Alternatively, the package can be downloaded via npm: