123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200 |
- import { Vector3 } from "../Maths/math.vector.js";
- import { Color3, Color4 } from "../Maths/math.color.js";
- import { Mesh } from "../Meshes/mesh.js";
- import { Gizmo } from "./gizmo.js";
- import { UtilityLayerRenderer } from "../Rendering/utilityLayerRenderer.js";
- import { StandardMaterial } from "../Materials/standardMaterial.js";
- import { CreateBox } from "../Meshes/Builders/boxBuilder.js";
- import { CreateCylinder } from "../Meshes/Builders/cylinderBuilder.js";
- import { Matrix } from "../Maths/math.js";
- import { CreateLines } from "../Meshes/Builders/linesBuilder.js";
- import { PointerEventTypes } from "../Events/pointerEvents.js";
- import { Observable } from "../Misc/observable.js";
- /**
- * Gizmo that enables viewing a camera
- */
- export class CameraGizmo extends Gizmo {
- /**
- * Creates a CameraGizmo
- * @param gizmoLayer The utility layer the gizmo will be added to
- * @param gizmoColor Camera mesh color. Default is Gray
- * @param frustumLinesColor Frustum lines color. Default is White
- */
- constructor(gizmoLayer = UtilityLayerRenderer.DefaultUtilityLayer, gizmoColor, frustumLinesColor) {
- super(gizmoLayer);
- this._pointerObserver = null;
- /**
- * Event that fires each time the gizmo is clicked
- */
- this.onClickedObservable = new Observable();
- this._camera = null;
- this._invProjection = new Matrix();
- this._material = new StandardMaterial("cameraGizmoMaterial", this.gizmoLayer.utilityLayerScene);
- this._frustumLinesColor = frustumLinesColor;
- this._material.diffuseColor = gizmoColor ?? new Color3(0.5, 0.5, 0.5);
- this._material.specularColor = new Color3(0.1, 0.1, 0.1);
- this._pointerObserver = gizmoLayer.utilityLayerScene.onPointerObservable.add((pointerInfo) => {
- if (!this._camera) {
- return;
- }
- this._isHovered = !!(pointerInfo.pickInfo && this._rootMesh.getChildMeshes().indexOf(pointerInfo.pickInfo.pickedMesh) != -1);
- if (this._isHovered && pointerInfo.event.button === 0) {
- this.onClickedObservable.notifyObservers(this._camera);
- }
- }, PointerEventTypes.POINTERDOWN);
- }
- /** Gets or sets a boolean indicating if frustum lines must be rendered (true by default)) */
- get displayFrustum() {
- return this._cameraLinesMesh.isEnabled();
- }
- set displayFrustum(value) {
- this._cameraLinesMesh.setEnabled(value);
- }
- /**
- * The camera that the gizmo is attached to
- */
- set camera(camera) {
- this._camera = camera;
- this.attachedNode = camera;
- if (camera) {
- // Create the mesh for the given camera
- if (!this._customMeshSet) {
- if (this._cameraMesh) {
- this._cameraMesh.dispose();
- }
- this._cameraMesh = CameraGizmo._CreateCameraMesh(this.gizmoLayer.utilityLayerScene);
- this._cameraMesh.getChildMeshes(false).forEach((m) => {
- m.material = this._material;
- });
- this._cameraMesh.parent = this._rootMesh;
- }
- if (this._cameraLinesMesh) {
- this._cameraLinesMesh.dispose();
- }
- const linesColor = this._frustumLinesColor?.toColor4(1) ?? new Color4(1, 1, 1, 1);
- this._cameraLinesMesh = CameraGizmo._CreateCameraFrustum(this.gizmoLayer.utilityLayerScene, linesColor);
- this._cameraLinesMesh.parent = this._rootMesh;
- if (this.gizmoLayer.utilityLayerScene.activeCamera && this.gizmoLayer.utilityLayerScene.activeCamera.maxZ < camera.maxZ * 1.5) {
- this.gizmoLayer.utilityLayerScene.activeCamera.maxZ = camera.maxZ * 1.5;
- }
- if (!this.attachedNode.reservedDataStore) {
- this.attachedNode.reservedDataStore = {};
- }
- this.attachedNode.reservedDataStore.cameraGizmo = this;
- // Add lighting to the camera gizmo
- const gizmoLight = this.gizmoLayer._getSharedGizmoLight();
- gizmoLight.includedOnlyMeshes = gizmoLight.includedOnlyMeshes.concat(this._cameraMesh.getChildMeshes(false));
- this._update();
- }
- }
- get camera() {
- return this._camera;
- }
- /**
- * Gets the material used to render the camera gizmo
- */
- get material() {
- return this._material;
- }
- /**
- * @internal
- * Updates the gizmo to match the attached mesh's position/rotation
- */
- _update() {
- super._update();
- if (!this._camera) {
- return;
- }
- // frustum matrix
- this._camera.getProjectionMatrix().invertToRef(this._invProjection);
- this._cameraLinesMesh.setPivotMatrix(this._invProjection, false);
- this._cameraLinesMesh.scaling.x = 1 / this._rootMesh.scaling.x;
- this._cameraLinesMesh.scaling.y = 1 / this._rootMesh.scaling.y;
- this._cameraLinesMesh.scaling.z = 1 / this._rootMesh.scaling.z;
- // take care of coordinate system in camera scene to properly display the mesh with the good Y axis orientation in this scene
- this._cameraMesh.parent = null;
- this._cameraMesh.rotation.y = Math.PI * 0.5 * (this._camera.getScene().useRightHandedSystem ? 1 : -1);
- this._cameraMesh.parent = this._rootMesh;
- }
- /**
- * Disposes and replaces the current camera mesh in the gizmo with the specified mesh
- * @param mesh The mesh to replace the default mesh of the camera gizmo
- */
- setCustomMesh(mesh) {
- if (mesh.getScene() != this.gizmoLayer.utilityLayerScene) {
- // eslint-disable-next-line no-throw-literal
- throw "When setting a custom mesh on a gizmo, the custom meshes scene must be the same as the gizmos (eg. gizmo.gizmoLayer.utilityLayerScene)";
- }
- if (this._cameraMesh) {
- this._cameraMesh.dispose();
- }
- this._cameraMesh = mesh;
- this._cameraMesh.parent = this._rootMesh;
- this._customMeshSet = true;
- }
- /**
- * Disposes of the camera gizmo
- */
- dispose() {
- this.onClickedObservable.clear();
- this.gizmoLayer.utilityLayerScene.onPointerObservable.remove(this._pointerObserver);
- if (this._cameraMesh) {
- this._cameraMesh.dispose();
- }
- if (this._cameraLinesMesh) {
- this._cameraLinesMesh.dispose();
- }
- this._material.dispose();
- super.dispose();
- }
- static _CreateCameraMesh(scene) {
- const root = new Mesh("rootCameraGizmo", scene);
- const mesh = new Mesh(root.name, scene);
- mesh.parent = root;
- const box = CreateBox(root.name, { width: 1.0, height: 0.8, depth: 0.5 }, scene);
- box.parent = mesh;
- const cyl1 = CreateCylinder(root.name, { height: 0.5, diameterTop: 0.8, diameterBottom: 0.8 }, scene);
- cyl1.parent = mesh;
- cyl1.position.y = 0.3;
- cyl1.position.x = -0.6;
- cyl1.rotation.x = Math.PI * 0.5;
- const cyl2 = CreateCylinder(root.name, { height: 0.5, diameterTop: 0.6, diameterBottom: 0.6 }, scene);
- cyl2.parent = mesh;
- cyl2.position.y = 0.5;
- cyl2.position.x = 0.4;
- cyl2.rotation.x = Math.PI * 0.5;
- const cyl3 = CreateCylinder(root.name, { height: 0.5, diameterTop: 0.5, diameterBottom: 0.5 }, scene);
- cyl3.parent = mesh;
- cyl3.position.y = 0.0;
- cyl3.position.x = 0.6;
- cyl3.rotation.z = Math.PI * 0.5;
- root.scaling.scaleInPlace(CameraGizmo._Scale);
- mesh.position.x = -0.9;
- return root;
- }
- static _CreateCameraFrustum(scene, linesColor) {
- const root = new Mesh("rootCameraGizmo", scene);
- const mesh = new Mesh(root.name, scene);
- mesh.parent = root;
- for (let y = 0; y < 4; y += 2) {
- for (let x = 0; x < 4; x += 2) {
- let line = CreateLines("lines", { points: [new Vector3(-1 + x, -1 + y, -1), new Vector3(-1 + x, -1 + y, 1)], colors: [linesColor, linesColor] }, scene);
- line.parent = mesh;
- line.alwaysSelectAsActiveMesh = true;
- line.isPickable = false;
- line = CreateLines("lines", { points: [new Vector3(-1, -1 + x, -1 + y), new Vector3(1, -1 + x, -1 + y)], colors: [linesColor, linesColor] }, scene);
- line.parent = mesh;
- line.alwaysSelectAsActiveMesh = true;
- line.isPickable = false;
- line = CreateLines("lines", { points: [new Vector3(-1 + x, -1, -1 + y), new Vector3(-1 + x, 1, -1 + y)], colors: [linesColor, linesColor] }, scene);
- line.parent = mesh;
- line.alwaysSelectAsActiveMesh = true;
- line.isPickable = false;
- }
- }
- return root;
- }
- }
- // Static helper methods
- CameraGizmo._Scale = 0.05;
- //# sourceMappingURL=cameraGizmo.js.map
|