How to get Fixed AxesViewer in Left Bottom

Hi,

How to get Fixed AxesViewer in Left Bottom ? When the camera angle changes, Axes need to change.

Thanks

Could you provide a repro in the Playground so that we can understand better what you want to achieve?

https://www.babylonjs-playground.com/#1SVBY1#2

In the above PG, Axes Viewer is not fixed in one place. It is keep on moving, when the object rotates. Is it possible to fix the Axes Viewer is Left Bottom ?

Thanks

You should use the camera.onViewMatrixChangedObservable observable instead of scene.onBeforeRenderObservable:

https://www.babylonjs-playground.com/#1SVBY1#3

Thanks for the reply.

https://playground.babylonjs.com/#QXHNNN#1

In the above PG, I have used the zoom to cursor point. Is it possible to set the fixed Axes Viewer?

You can use a 2nd fixed camera:

https://playground.babylonjs.com/#QXHNNN#2

The debug axis viewer is displayed by this 2nd camera and not by the first one. As this 2nd camera does not move / rotate, the viewer stays fixed at the same location on the screen. You simply need to copy the x/y/z orientation of the 1st camera to the axis of the viewer to get the result you want.

I have applied 2nd camera, still cannot able to get.

Attached code for ref. I have added the selected mesh on mouse click. Is it because of it?

import * as BABYLON from ‘@babylonjs/core’;
import * as BABYLON1 from ‘@babylonjs/core/Debug’;
//import ‘@babylonjs/core/Debug/debugLayer’;
import ‘@babylonjs/inspector’;

declare const window: any;

@Component({
selector: ‘3Dv’,
templateUrl: ‘./3Dv.html’,
styleUrls: [’./3Dv.less’]
})

export class ThreeDViewerComponent extends AppComponentBase implements OnInit, AfterViewInit, OnDestroy {

canvas: any;
engine: any;
selectedMesh: any;
highlightLayer: any;

constructor(
    injector: Injector,
    private ngZone: NgZone,
) {
    super(injector);
}

ngOnInit(): void {
    setTimeout(() => {
		this.initialize3dOptions();
    }, 100);
}

ngOnDestroy(): void {
    this.canvas = null;
    this.engine = null;
}


private initialize3dOptions() {
    let self = this;
    var renderCanvas = "renderCanvas_" + this.section.id;
		// Get the canvas element from the DOM.
		self.canvas = document.getElementById(renderCanvas) as HTMLCanvasElement;
		// Associate a Babylon Engine to it.
		self.engine = new BABYLON.Engine(self.canvas, true);

		const setTopBottomRatio = (camera) => {
			var renderCanvas = "renderCanvas_" + this.section.id
			const canvas = document.getElementById(renderCanvas) as HTMLCanvasElement;
			const ratio = canvas.height / canvas.width;
			camera.orthoTop = camera.orthoRight * ratio;
			camera.orthoBottom = camera.orthoLeft * ratio;
		};

		let zoomTarget = null;

		const resetCameraZoom = (camera) => {
			camera.setPosition(new BABYLON.Vector3(0, 0, -100));
			camera.target = new BABYLON.Vector3(0, 0, 0);
			camera.orthoLeft = -8;
			camera.orthoRight = 8;

			setTopBottomRatio(camera);
		};

		var createScene = function () {
			// Create our first scene.
			var scene = new BABYLON.Scene(self.engine);
			const axis = new BABYLON1.AxesViewer(scene, 1, 0);
			// This creates and positions a free camera (non-mesh)
			var camera = new BABYLON.ArcRotateCamera('Camera', -Math.PI, 0, -100, new BABYLON.Vector3(1, 2, -3), scene);
			camera.layerMask = 0x0FFFFFFF;
			resetCameraZoom(camera);
			let totalZoom = 0;

			const zoomWheel = (p, e, camera) => {
				const event = p.event;
				event.preventDefault();
				let delta = 0;
				delta = (Math.max(-1, Math.min(1, (event.wheelDelta || -event.detail || event.deltaY)))) * 0.2;
				return delta;
			}

			const zoom2DView = async (camera, delta, zoomTarget) => {
				const zoomingOut = delta < 0;

				if (zoomTarget) {
					const totalX = Math.abs(camera.orthoLeft - camera.orthoRight);
					const totalY = Math.abs(camera.orthoTop - camera.orthoBottom);
					const aspectRatio = totalY / totalX;
					{
						const fromCoord = camera.orthoLeft - zoomTarget.x;
						const ratio = fromCoord / totalX;
						camera.orthoLeft -= ratio * delta;
					}

					{
						const fromCoord = camera.orthoRight - zoomTarget.x;
						const ratio = fromCoord / totalX;
						camera.orthoRight -= ratio * delta;
					}

					{
						const fromCoord = camera.orthoTop - zoomTarget.y;
						const ratio = fromCoord / totalY;
						camera.orthoTop -= ratio * delta * aspectRatio;
					}

					{
						const fromCoord = camera.orthoBottom - zoomTarget.y;
						const ratio = fromCoord / totalY;
						camera.orthoBottom -= ratio * delta * aspectRatio;
					}

					// decrease pan sensitivity the closer the zoom level.
					camera.panningSensibility = 6250 / Math.abs(totalX / 2);
				}
			};

			const zoomFn1 = (p, e) => {
				const delta = zoomWheel(p, e, camera);
				const zoomTarget = BABYLON.Vector3.Unproject(
					new BABYLON.Vector3(scene.pointerX, scene.pointerY, 0),
					self.engine.getRenderWidth(),
					self.engine.getRenderHeight(),
					camera.getWorldMatrix(),
					camera.getViewMatrix(),
					camera.getProjectionMatrix()
				);
				if (delta > 0 && totalZoom < 14 || delta < 0) {
					totalZoom += delta;
					zoom2DView(camera, delta, zoomTarget);
				}
			};

			//var hlMesh = null;
			self.selectedMesh = null;
			// Add the highlight layer.
			//var hl = new BABYLON.HighlightLayer("hl1", scene);
			self.highlightLayer = new BABYLON.HighlightLayer("hl1", scene);

			scene.onPointerObservable.add(zoomFn1, BABYLON.PointerEventTypes.POINTERWHEEL);

			scene.onPointerObservable.add(() => {
				const zoomTarget = BABYLON.Vector3.Unproject(
					new BABYLON.Vector3(scene.pointerX, scene.pointerY, 0),
					self.engine.getRenderWidth(),
					self.engine.getRenderHeight(),
					camera.getWorldMatrix(),
					camera.getViewMatrix(),
					camera.getProjectionMatrix()
				);
				var pick = scene.pick(scene.pointerX, scene.pointerY);
				//if ((pick.hit) && pick.pickedMesh.highlightable) {
				if ((pick.hit) && pick.pickedMesh) {
					if (self.selectedMesh === null) {
						// gotcha!
						//hlMesh = (pick.pickedMesh.instanceOf ? pick.pickedMesh.instanceOf.clone() : pick.pickedMesh.clone("", null, false))
						self.selectedMesh = (pick.pickedMesh.clone("", null, false))

						self.selectedMesh.visibility = 1;

						self.selectedMesh.position = pick.pickedMesh.position.clone();
						self.selectedMesh.lastMesh = pick.pickedMesh;
						self.highlightLayer.addMesh(self.selectedMesh, BABYLON.Color3.Blue())
					} else {
						if (self.selectedMesh.lastMesh !== pick.pickedMesh) {
							self.highlightLayer.removeMesh(self.selectedMesh);
							self.selectedMesh.dispose();
							self.selectedMesh = null;
							self.selectedMesh = (pick.pickedMesh.clone("", null, false))

							self.selectedMesh.visibility = 1;

							self.selectedMesh.position = pick.pickedMesh.position.clone();
							self.selectedMesh.lastMesh = pick.pickedMesh;
							self.highlightLayer.addMesh(self.selectedMesh, BABYLON.Color3.Blue())
						}
					}
				} else if (self.selectedMesh !== null) {
					//self.highlightLayer.removeMesh(hlMesh);
					//hlMesh.dispose();
					//hlMesh = null;
				}
			}, BABYLON.PointerEventTypes.POINTERDOWN);

			camera.lowerRadiusLimit = camera.radius;
			camera.upperRadiusLimit = camera.radius;

			// This attaches the camera to the canvas
			camera.attachControl(self.canvas, true, false, 0);
			camera.mode = BABYLON.Camera.ORTHOGRAPHIC_CAMERA;

			// 2nd camera for the debug axis viewer
			var camera2 = new BABYLON.ArcRotateCamera('Camera2', 0, 0, -100, new BABYLON.Vector3(1, 2, -3), scene);
			resetCameraZoom(camera2);
			camera2.layerMask = 0x10000000;
			camera2.mode = BABYLON.Camera.ORTHOGRAPHIC_CAMERA;

			axis.xAxis.getChildMeshes().forEach((mesh) => {
				mesh.layerMask = 0x10000000;
			});
			axis.yAxis.getChildMeshes().forEach((mesh) => {
				mesh.layerMask = 0x10000000;
			});
			axis.zAxis.getChildMeshes().forEach((mesh) => {
				mesh.layerMask = 0x10000000;
			});

			camera2.setPosition(new BABYLON.Vector3(0, 0, -100));
			camera2.target = new BABYLON.Vector3(0, 0, 0);
			camera2.alpha += Math.PI;
			camera2.getViewMatrix(true);

			var p = camera2.position.clone();

			p.addInPlace(camera2.getDirection(new BABYLON.Vector3(0, 0, 15)));
			p.addInPlace(camera2.getDirection(new BABYLON.Vector3(0, 5, 0)));
			p.addInPlace(camera2.getDirection(new BABYLON.Vector3(2, 0, 0)));

			const setAxisViewer = (camera, position) => {
				axis.update(position,
					camera.getDirection(new BABYLON.Vector3(1, 0, 0)),
					camera.getDirection(new BABYLON.Vector3(0, 1, 0)),
					camera.getDirection(new BABYLON.Vector3(0, 0, 1))
				);
			}

			setAxisViewer(camera, p);
			scene.activeCameras.push(camera, camera2);


			var light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(0, 1, 0), scene);
			light.intensity = 0.7;
			BABYLON.SceneLoader.ShowLoadingScreen = false;
			var building = BABYLON.SceneLoader.Append("/assets/threedViewer/", "RAB.obj", scene, function (meshes) {
				scene.createDefaultCameraOrLight(true);
				scene.activeCamera.attachControl(self.canvas, false);
			});

			scene.getBoundingBoxRenderer().frontColor.set(1, 0, 0);
			scene.getBoundingBoxRenderer().backColor.set(1, 0, 0);

			camera.onViewMatrixChangedObservable.add(() => {
				setAxisViewer(camera, p);
			});

			var selected = null;
			var pointerMoved = false;

			scene.onPointerObservable.add(function (evt) {
				switch (evt.type) {
					case BABYLON.PointerEventTypes.POINTERDOWN:
						pointerMoved = false;
						break;

					case BABYLON.PointerEventTypes.POINTERUP:
						if (pointerMoved) return;
						if (selected) {
							selected.material.diffuseColor = BABYLON.Color3.White();
							selected = null;
						}
						if (evt.pickInfo.hit && evt.pickInfo.pickedMesh && evt.event.button === 0) {
							selected = evt.pickInfo.pickedMesh;
							//evt.pickInfo.pickedMesh.material.diffuseColor = BABYLON.Color3.Green();
						}
						break;

					case BABYLON.PointerEventTypes.POINTERMOVE:
						pointerMoved = true;
						break;

				}
			}, BABYLON.PointerEventTypes.POINTERDOWN + BABYLON.PointerEventTypes.POINTERUP + BABYLON.PointerEventTypes.POINTERMOVE);

			scene.registerBeforeRender(function () {
				var p = new BABYLON.Vector3;
				p.addInPlace(camera.position);
				p.addInPlace(camera.getDirection(new BABYLON.Vector3(0, 0, 20)));
				p.addInPlace(camera.getDirection(new BABYLON.Vector3(0, 7, 0)));
				p.addInPlace(camera.getDirection(new BABYLON.Vector3(5, 0, 0)));

				axis.xAxis.position = p.clone();
				axis.yAxis.position = p.clone();
				axis.zAxis.position = p.clone();
			});

			return scene;
		};

		var scene = createScene();
		
		self.engine.runRenderLoop(function () {
			scene.render();
			scene.executeWhenReady(function () { //When everything is done loading
				self.set3dHeight(10);
				self.loadingService.hide();
			});
		});
	}
}

}

Please create a repro in the Playground instead (https://playground.babylonjs.com/).

My PG above does not work for you? It is not what you are looking for?

I am looking for this only, but I have added the selected mesh on mouse click. Is it because of mouse click, Fixed Axes Viewer not working for me?

I don’t think so, try to make a repro in the Playground.