File

src/app/models/babylon-integration-waste-sorting.ts

Constructor

constructor(globalService: GlobalService, dataService: CabriDataService, ngZone: NgZone, page: WasteSortingPage, cd: ChangeDetectorRef)

Methods

initScene
initScene()

Populate scene a

Returns: void
addRenderingPipeline
addRenderingPipeline()
Returns: void
restartScene
restartScene()
Returns: void
changeDome
changeDome($event: any)
Returns: void
loadPhotodome
loadPhotodome(photoDome: PhotoDomeModel)
Returns: any
removeInstancedItemsFromScene
removeInstancedItemsFromScene()
Returns: void
createHilight
createHilight()
Returns: void
loadItemsScene
loadItemsScene(photoDomeItem: PhotoDomeItem[])
Returns: void
Public addCurrentMeshHighLight
addCurrentMeshHighLight(photoDomeItem: PhotoDomeItem, mesh: Mesh)
Returns: void
setCameraOrientation
setCameraOrientation(photoDome: PhotoDomeModel)
Returns: void
debug
debug()
Returns: void
showDebug
showDebug()
Returns: void
addMouseWheelEvent
addMouseWheelEvent()
Returns: void
fovAdjust
fovAdjust(delta: number)
Returns: void
addPickEvent
addPickEvent()
Returns: void
createCamera
createCamera()
Returns: void
placeObjectConstructedScene
placeObjectConstructedScene()
Returns: void
isAllPlacedMeshUsed
isAllPlacedMeshUsed()
Returns: boolean
createLight
createLight()
Returns: void
createPhotoDome
createPhotoDome()
Returns: any
activateAr
activateAr()
Returns: void
importAsset
importAsset()
Returns: any
importMesh
importMesh()
Returns: void
importImage
importImage()
Returns: void
importTexture
importTexture()
Returns: void
importFinish
importFinish(tasks: AbstractAssetTask[])
Returns: void
addCustomBehavior
addCustomBehavior(mesh: AbstractMesh, type: string)
Returns: void

Properties

alphaHilight
alphaHilight: number
assetsContainer
assetsContainer: AssetContainer
assetsManager
assetsManager: AssetsManager
banList
banList: string[]
camera
camera: UniversalCamera | ArcRotateCamera
camera2
camera2: ArcRotateCamera
cd
cd: ChangeDetectorRef
centerlight
centerlight: HemisphericLight
compostList
compostList: string[]
compostMeshs
compostMeshs: AbstractMesh[]
dataService
dataService: CabriDataService
displayNameList
displayNameList: { needle: string; displayName: string; }[]
dome
dome: PhotoDome
domeSelected
domeSelected: any
Default value: 0
domOverlayFeature
domOverlayFeature: WebXRDomOverlay
evCache
evCache: any
glassList
glassList: string[]
glassMeshs
glassMeshs: AbstractMesh[]
globalService
globalService: GlobalService
hilightLayer
hilightLayer: HighlightLayer
hitTest
hitTest: WebXRHitTest
images
images: any
lastCalled
lastCalled: number
light
light: PointLight
meshs
meshs: any
ngZone
ngZone: NgZone
page
page: WasteSortingPage
photoDome
photoDome: PhotoDomeModel
pipeline
pipeline: DefaultRenderingPipeline
placedMesh
placedMesh: AbstractMesh[]
placementPosition
placementPosition: { position: Vector3; rotation: Vector3; scale: Vector3; }[]
placementPositionNature
placementPositionNature: { position: Vector3; rotation: Vector3; scale: Vector3; }[]
prevDiff
prevDiff: number
recycleList
recycleList: string[]
recycleMeshs
recycleMeshs: AbstractMesh[]
scrapList
scrapList: string[]
scrapMeshs
scrapMeshs: AbstractMesh[]
textures
textures: any
xr
xr: WebXRDefaultExperience
xrAnchor
xrAnchor: WebXRAnchorSystem
xrBackgroundRemover
xrBackgroundRemover: WebXRBackgroundRemover
xrPlaneDetection
xrPlaneDetection: WebXRPlaneDetector
import { NgZone, ChangeDetectorRef } from "@angular/core";
import {
	AbstractAssetTask,
	AbstractMesh,
	ArcRotateCamera,
	AssetContainer,
	AssetsManager,
	ImageAssetTask,
	Matrix,
	MeshAssetTask,
	MultiMaterial,
	PhotoDome,
	PointLight,
	Texture,
	TextureAssetTask,
	Tools,
	UniversalCamera,
	Vector3,
	WebXRAnchorSystem,
	WebXRBackgroundRemover,
	WebXRDefaultExperience,
	WebXRDomOverlay,
	WebXRFeatureName,
	WebXRHitTest,
	WebXRPlaneDetector,
	HemisphericLight,
	WebXRSessionManager,
	ArcRotateCameraPointersInput,
	Mesh,
	PointerEventTypes,
	Color4,
	GlowLayer,
	HighlightLayer,
	Color3,
	DefaultRenderingPipeline,
	ScreenshotTools,
	PointerTouch
} from "@babylonjs/core";
import { WasteSortingPage } from "../page/waste-sorting/waste-sorting.page";
import { CabriDataService } from "../services/cabri-data.service";
import { GlobalService } from "../services/global.service";
import { BabylonIntegration } from "./babylon-integration";
//not remove load for inspector
import("@babylonjs/core/Debug/debugLayer");
import("@babylonjs/inspector");
import { AppUtils } from "../app-utils";
import { IonSegment } from "@ionic/angular";
import { PhotoDomeItem, PhotoDomeModel } from "./photodome";
import { OseDifficulty } from "./enums/oseDifficulty";

export class BabylonIntegrationWasteSorting extends BabylonIntegration {
	camera: UniversalCamera | ArcRotateCamera;
	dome: PhotoDome;
	assetsManager: AssetsManager;
	assetsContainer: AssetContainer;
	textures: Map<string, Texture>;
	images: Map<string, HTMLImageElement>;
	meshs: Map<string, AbstractMesh>;
	light: PointLight;
	xr: WebXRDefaultExperience;
	compostList = ["banana", "egg_", "apple", "corn"];
	recycleList = ["paper", "box", "can_", "plastic", "holder"];
	glassList = ["bottle_of"];
	scrapList = ["metal", "Pneu","Europalette"];
	banList = ["cracked", "plastic_coctail_cup", "paper_list"];

	displayNameList = [
		{ needle: "banana", displayName: "cette peau de banane" },
		{ needle: "egg_", displayName: "cette coquille d'oeuf" },
		{ needle: "holder_6_eggs", displayName: "cette boîte à œufs" },
		{ needle: "apple", displayName: "ce trognon de Pomme" },
		{ needle: "wine", displayName: "cette bouteille en verre" },
		{ needle: "beer", displayName: "cette bouteille en verre" },
		{ needle: "tube", displayName: "ce tube de sauce" },
		{ needle: "shreds_paper", displayName: "ce bout de papier" },
		{ needle: "holder_paper", displayName: "cette boîte de mouchoir" },
		{ needle: "a4_paper", displayName: "cette feuille de papier" },
		{ needle: "toilet_paper", displayName: "ce papier toilette" },
		{ needle: "bag_paper", displayName: "ce sac en papier" },
		{ needle: "corn", displayName: "cet épi de maïs" },
		{ needle: "box_milk", displayName: "cette boîte de lait" },
		{ needle: "box", displayName: "cette boîte" },
		{ needle: "soda_can", displayName: "cette bouteille en plastique" },
		{ needle: "plastic_bottle", displayName: "cette bouteille en plastique" },
		{ needle: "plastic_canister", displayName: "ce bidon en plastique" },
		{ needle: "plastic_jar", displayName: "ce pot en plastique" },
		{ needle: "cup_head", displayName: "ce capuchon en plastique" },
		{ needle: "plastic_cup", displayName: "ce verre en plastique" },
		{ needle: "plate", displayName: "ce plateau" },
		{ needle: "tin_can", displayName: "cette boîte de conserve" },
		{ needle: "can", displayName: "cette canette" },
		{ needle: "metal_scrap", displayName: "ce pied de biche" },
		{ needle: "metal_tap", displayName: "ce robinet" },
		{ needle: "Pneu", displayName: "ce pneu" }
	];

	placementPosition = [
		{ position: new Vector3(13.19, -7.51, 11.64), rotation: new Vector3(0, 0, 0), scale: new Vector3(5, 5, 5) },
		{ position: new Vector3(1.878, -2.48, 16.402), rotation: new Vector3(0, 0, 0), scale: new Vector3(3, 3, 3) },
		{ position: new Vector3(-3.582, -5.582, 17.85), rotation: new Vector3(0, 0, 0), scale: new Vector3(3, 3, 3) },
		{ position: new Vector3(-9.945, -8.615, -10.173), rotation: new Vector3(0, 0, 0), scale: new Vector3(8, 8, 8) },
		{ position: new Vector3(17.054, -5.125, -2.623), rotation: new Vector3(0, 0, 0), scale: new Vector3(8, 8, 8) },
		{ position: new Vector3(17.736, -7.712, -1.226), rotation: new Vector3(0, 0, 0), scale: new Vector3(3, 3, 3) },
		{ position: new Vector3(-5.153, -5.819, -17.602), rotation: new Vector3(0, 0, 0), scale: new Vector3(3, 3, 3) },
		{ position: new Vector3(-2.709, -11.006, 16.302), rotation: new Vector3(0, 0, 0), scale: new Vector3(8, 8, 8) },
		{ position: new Vector3(8.646, -11.465, -10.284), rotation: new Vector3(0, 0, 0), scale: new Vector3(6, 6, 6) },
		{ position: new Vector3(-15.615, -7.268, 3.27), rotation: new Vector3(0, 0, 0), scale: new Vector3(3.5, 3.5, 3.5) }
	];

	placementPositionNature = [
		{ position: new Vector3(1.225, -2.48, 15.343), rotation: new Vector3(0, 0, 0), scale: new Vector3(4, 4, 4) },
		{ position: new Vector3(5.26, -6.73, 15.15), rotation: new Vector3(0, 0, 0), scale: new Vector3(4, 4, 4) },
		{ position: new Vector3(-13.403, -14.056, -1.071), rotation: new Vector3(0, 0, 0), scale: new Vector3(14, 14, 14) },
		{ position: new Vector3(1.712, -7.725, -17.861), rotation: new Vector3(0, 0, 0), scale: new Vector3(5, 5, 5) },
		{ position: new Vector3(-11.574, -4.161, -14.3), rotation: new Vector3(0, 0, 0), scale: new Vector3(3, 3, 3) },
		{ position: new Vector3(10.266, -3.006, -16.095), rotation: new Vector3(0, 0, 0), scale: new Vector3(3, 3, 3) },
		{ position: new Vector3(0.42, -12.511, 14.508), rotation: new Vector3(0, 0, 0), scale: new Vector3(8, 8, 8) },
		{ position: new Vector3(-10.604, -8.419, 13.609), rotation: new Vector3(0, 0, 0), scale: new Vector3(4.5, 4.5, 4.5) },
		{ position: new Vector3(-6.174, -13.508, -13.08), rotation: new Vector3(0, 0, 0), scale: new Vector3(7, 7, 7) },
		{ position: new Vector3(-16.42, -8.419, 5.729), rotation: new Vector3(0, 0, 0), scale: new Vector3(4.5, 4.5, 4.5) }
	];
	compostMeshs: AbstractMesh[];
	recycleMeshs: AbstractMesh[];
	glassMeshs: AbstractMesh[];
	scrapMeshs: AbstractMesh[];
	xrAnchor: WebXRAnchorSystem;
	xrPlaneDetection: WebXRPlaneDetector;
	xrBackgroundRemover: WebXRBackgroundRemover;
	hitTest: WebXRHitTest;
	domOverlayFeature: WebXRDomOverlay;
	placedMesh: AbstractMesh[];
	domeSelected: any = "0";
	camera2: ArcRotateCamera;
	photoDome: PhotoDomeModel;
	hilightLayer: HighlightLayer;
	alphaHilight: number;
	evCache: any;
	prevDiff: number;
	centerlight: HemisphericLight;
	pipeline: DefaultRenderingPipeline;
	lastCalled: number;

	constructor(
		public globalService: GlobalService,
		public dataService: CabriDataService,
		public ngZone: NgZone,
		public page: WasteSortingPage,
		public cd?: ChangeDetectorRef
	) {
		super(globalService, dataService, ngZone, cd);
		this.placedMesh = [];
	}
	/**
	 * Populate scene a
	 */
	async initScene() {
		this.createCamera();
		this.createLight();
		this.createHilight();
		this.addRenderingPipeline();
		await this.importAsset();
		this.assetsContainer.addAllToScene();
		await this.activateAr();
		/*if (!this.xrPlaneDetection) {*/
		console.log("this.page.currentPhotodome", this.page.currentPhotodome);
		if (this.page.currentPhotodome) {
			await this.loadPhotodome(this.page.currentPhotodome);
		} else {
			await this.createPhotoDome();
			this.placeObjectConstructedScene();
		}
		/*}*/
		this.debug();
	}

	addRenderingPipeline() {
		this.pipeline = new DefaultRenderingPipeline("defaultPipeline", true, this.scene, [this.scene.activeCamera]);
		if (!this.globalService.lowPerformanceMode) {
			this.pipeline.fxaaEnabled = true;
			this.pipeline.samples = 4;
		}
		this.pipeline.glowLayerEnabled = true;
		this.pipeline.glowLayer.intensity = 0.5;
		this.pipeline.imageProcessingEnabled = false;
	}

	async restartScene() {
		this.placedMesh.forEach(mesh => {
			mesh.isVisible = false;
		});
		this.placeObjectConstructedScene();
	}

	async changeDome($event: CustomEvent<IonSegment>) {
		console.log($event);
		this.domeSelected = $event.detail.value;
		this.dome.dispose();
		await this.createPhotoDome();
		this.restartScene();
	}

	loadPhotodome(photoDome: PhotoDomeModel): Promise<void> {
		return new Promise((resolve, reject) => {
			if (!this.globalService.globalLoading) {
				this.engine.displayLoadingUI();
			}
			this.removeInstancedItemsFromScene();

			if (this.dome) {
				this.dome.dispose();
			}
			this.photoDome = photoDome;
			this.dome = new PhotoDome(
				photoDome.name,
				photoDome.srcImg,
				{
					resolution: 32,
					size: 40
				},
				this.scene
			);
			this.dome.imageMode = PhotoDome.MODE_MONOSCOPIC;
			console.error(photoDome);
			this.loadItemsScene(photoDome.photoDomeItems);
			this.page.totalWastes = photoDome.photoDomeItems.length;

			this.dome.onLoadObservable.addOnce(() => {
				this.setCameraOrientation(photoDome);
				this.engine.hideLoadingUI();
				resolve();
			});
		});
	}

	removeInstancedItemsFromScene() {
		this.placedMesh.forEach(mesh => {
			mesh.dispose();
		});
		this.placedMesh = [];
	}
	createHilight() {
		this.hilightLayer = new HighlightLayer("hl2", this.scene, { camera: this.camera, mainTextureRatio: 1 });
		this.hilightLayer.blurHorizontalSize = 1;
		this.hilightLayer.blurVerticalSize = 1;
		this.alphaHilight = 0;
		this.scene.registerBeforeRender(() => {
			this.hilightLayer.blurHorizontalSize = 1 + Math.cos(this.alphaHilight) * 0.5;
			this.hilightLayer.blurVerticalSize = 1 + Math.sin(this.alphaHilight / 3) * 0.5;
			this.alphaHilight += 0.04;
		});
	}
	loadItemsScene(photoDomeItem: PhotoDomeItem[]) {
		photoDomeItem.forEach(item => {
			const mesh = this.scene.getMeshByName(item.originalMeshName) as Mesh;
			const behavior = mesh.getBehaviorByName("custom");
			if (this.page.difficultySelected === OseDifficulty.easy) {
				this.addCurrentMeshHighLight(item, mesh);
			}
			const clone = mesh.createInstance(mesh.name + 1);
			if (behavior) {
				clone.addBehavior(behavior);
			}
			clone.position.x = item.position.x;
			clone.position.y = item.position.y;
			clone.position.z = item.position.z;
			clone.rotation.x = item.rotation.x;
			clone.rotation.y = item.rotation.y;
			clone.rotation.z = item.rotation.z;
			clone.scaling.x = item.scale.x;
			clone.scaling.y = item.scale.y;
			clone.scaling.z = item.scale.z;
			clone.isVisible = true;
			item.meshId = clone.uniqueId;
			this.placedMesh.push(clone);
			this.assetsContainer.meshes.push(clone);
		});
	}

	public addCurrentMeshHighLight(photoDomeItem: PhotoDomeItem, mesh: Mesh) {
		if (photoDomeItem.type === "waste" && this.hilightLayer) {
			this.hilightLayer.addMesh(mesh, new Color3(1, 0.51, 0));
		}
	}

	setCameraOrientation(photoDome: PhotoDomeModel) {
		if (photoDome.cameraAlpha && photoDome.cameraBeta) {
			if (this.camera instanceof ArcRotateCamera) {
				this.camera.alpha = photoDome.cameraAlpha;
				this.camera.beta = photoDome.cameraBeta;
			}
		}
	}

	debug() {
		this.meshs.get("floor").setEnabled(false);
		// this.showDebug();
	}

	showDebug() {
		if (this.scene.debugLayer.isVisible()) {
			this.scene.debugLayer.hide();
		} else {
			this.scene.debugLayer.show();
		}
	}

	addMouseWheelEvent() {
		this.scene.onPointerObservable.add(pointerInfo => {
			// prevent all default (native chrome pinch zoom)
			pointerInfo.event.preventDefault();
			switch (pointerInfo.type) {
				case PointerEventTypes.POINTERWHEEL:
					this.fovAdjust((pointerInfo.event as any).wheelDelta);
					break;
			}
		});
		if (this.camera instanceof ArcRotateCamera) {
			const pointers = this.camera.inputs.attached.pointers as ArcRotateCameraPointersInput;
			pointers.onMultiTouch = (
				pointA: PointerTouch,
				pointB: PointerTouch,
				previousPinchSquaredDistance: number,
				pinchSquaredDistance: number,
				previousMultiTouchPanPosition: PointerTouch,
				multiTouchPanPosition: PointerTouch
			) => {
				this.fovAdjust(pinchSquaredDistance - previousPinchSquaredDistance);
			};
		}
	}

	fovAdjust(delta: number) {
		if (delta > 0) {
			if (this.camera.fov - 0.05 > 0.14) {
				this.camera.fov -= 0.05;
			}
		} else {
			if (this.camera.fov + 0.05 < 1) {
				this.camera.fov += 0.05;
			}
		}
	}

	addPickEvent() {
		//
		// Gestion des clicks
		//
		this.lastCalled = new Date().getTime();
		this.scene.onPointerDown = async (evt, pickResult) => {
			const now = new Date().getTime();
			//debounce
			if (now - this.lastCalled > 500 /* half a second */) {
				this.lastCalled = now;
				const meshBlacklist = ["floor", "testdome_mesh", this.photoDome?.name + "_mesh"];
				if (pickResult && meshBlacklist.indexOf(pickResult.pickedMesh.id) === -1) {
					this.page?.audioService?.playSelectSound();
					const createSelectedWaste = (pickResult, image?) => {
						return {
							idExercise: this.page.exerciseId,
							type: (pickResult.pickedMesh.getBehaviorByName("custom") as any).type,
							name: (pickResult.pickedMesh.getBehaviorByName("custom") as any).displayName,
							mesh: pickResult.pickedMesh,
							image: image || null
						};
					};
					if (this.page.difficultySelected === OseDifficulty.easy) {
						this.page.selectedWaste = {
							...createSelectedWaste(pickResult)
						};
					} else {
						console.log(evt);
						console.log(pickResult);
						let dataImg;
						try {							
							this.camera2.minZ = 0;
							this.camera2.maxZ = 50;
							this.camera2.zoomOn([pickResult.pickedMesh], true);
							this.camera2.alpha = (this.camera as ArcRotateCamera).alpha;
							this.camera2.beta = (this.camera as ArcRotateCamera).beta;
							//const light2 = new HemisphericLight("camera2-flash", this.camera.position, this.scene);
							let quality = 1;
							let size = 800;
							if (this.globalService.isMobile) {
								quality = 0.4;
								size = 200;
							}
							dataImg = await ScreenshotTools.CreateScreenshotUsingRenderTargetAsync(
								this.engine,
								this.camera2,
								size,
								"image/png",
								1,
								false,
								undefined,
								false,
								false,
								false,
								quality
							);
						/**
						 * An alternative approach is to zoom the camera into the mesh target before taking a screenshot of the canvas(toDataURL)
						 *  and then revert to the original camera position without being visible by user.
						 */
						// let originalState = {
						// 	position: this.camera.position.clone(),
						// 	target: this.camera.target.clone(),
						// 	fov:this?.camera.fov,
						// 	minZ:this.camera.minZ,
						// 	maxZ:this.camera.maxZ
						// };
						// this.camera.minZ = 0;
						// this.camera.maxZ = 50;
						// this.camera.fov = 0.8;
						// (this.camera as ArcRotateCamera).zoomOn([pickResult.pickedMesh], true);
						// this.scene.render();		

						// this.scene.onAfterRenderObservable.addOnce(() => {
						// const dataImg2 = this.engine.getRenderingCanvas().toDataURL("image/png")
						// this.page.selectedWaste = {
						// 	...createSelectedWaste(pickResult, dataImg2)
						// };

						// this.camera.minZ = originalState.minZ;
						// this.camera.maxZ = originalState.maxZ;
						// this.camera.fov = originalState.fov;
						// this.camera.position = originalState.position;
						// this.camera.setTarget(originalState.target);
						// this.scene.render();
						// })
						} catch (error) {
							console.log("can't generate screenshoot from scene");
						}

						this.page.selectedWaste = {
							...createSelectedWaste(pickResult, dataImg)
						};

					}
				}
			}
		};
	}
	createCamera() {
		//this.camera = new UniversalCamera("UniversalCamera", new Vector3(0, 0, -10), this.scene);
		//outside angular zone camera declaration attach control by defaut an so declare event listener
		this.ngZone.runOutsideAngular(() => {
			this.camera = new ArcRotateCamera("Camera", -Math.PI / 2, Math.PI / 2, 5, Vector3.Zero(), this.scene);
			this.camera.setTarget(Vector3.Zero());
			this.camera.attachControl(this.canvas, true);

			this.camera2 = new ArcRotateCamera("camera-screenshot", -Math.PI / 2, Math.PI / 2, 1.55, Vector3.Zero(), this.scene);
			this.camera2.layerMask = this.camera.layerMask;
			this.camera2.minZ = 0;
			this.camera2.maxZ = 50;
		});

		this.camera.inputs.attached.mousewheel.detachControl();
		//remove pinch zone interaction
		(this.camera.inputs.attached.pointers as ArcRotateCameraPointersInput).pinchZoom = false;
		(this.camera.inputs.attached.pointers as ArcRotateCameraPointersInput).multiTouchPanAndZoom = false;
		(this.camera.inputs.attached.pointers as ArcRotateCameraPointersInput).multiTouchPanning = false;
		//specify use button to only left button to remove right mouse action
		(this.camera.inputs.attached.pointers as ArcRotateCameraPointersInput).buttons = [0];
	}

	placeObjectConstructedScene() {
		let suffleRecycleMeshs = this.recycleMeshs.slice();
		let suffleGlassMeshs = this.glassMeshs.slice();
		let suffleCompostMeshs = this.compostMeshs.slice();
		this.placedMesh = [];

		const placements = this.domeSelected === "0" ? this.placementPosition : this.placementPositionNature;

		placements.forEach((placement, index) => {
			const indexTurn = index + 1;
			let selectedMesh: AbstractMesh = null;
			if (indexTurn % 3 === 0) {
				AppUtils.shuffleArray(suffleRecycleMeshs);
				selectedMesh = suffleRecycleMeshs.pop();
			} else if (indexTurn % 2 === 0) {
				AppUtils.shuffleArray(suffleGlassMeshs);
				selectedMesh = suffleGlassMeshs.pop();
			} else if (indexTurn % 1 === 0) {
				AppUtils.shuffleArray(suffleCompostMeshs);
				selectedMesh = suffleCompostMeshs.pop();
			}
			selectedMesh.position = placement.position;
			selectedMesh.rotation = placement.rotation;
			selectedMesh.scaling = placement.scale;
			selectedMesh.isVisible = true;
			this.placedMesh.push(selectedMesh);
		});
	}

	isAllPlacedMeshUsed(): boolean {
		return this.placedMesh.every(mesh => {
			return mesh.isVisible === false;
		});
	}

	createLight() {
		this.light = new PointLight("bulb", new Vector3(0, 40, 0), this.scene);
		this.light.intensity = 9000;
		this.centerlight = new HemisphericLight("centerbulb", new Vector3(0, 0, 0), this.scene);
		this.centerlight.intensity = 0.3;
	}

	createPhotoDome(): Promise<void> {
		return new Promise((resolve, reject) => {
			/*this.dome = new PhotoDome(
				"testdome",
				"assets/babylon/wasteSorting/sidexside.jpg",
				{
					resolution: 32,
					size: 40
				},
				this.scene
			);
			this.dome.imageMode = PhotoDome.MODE_SIDEBYSIDE;*/
			this.dome = new PhotoDome(
				"testdome",
				"assets/babylon/wasteSorting/nature.jpg",
				{
					resolution: 32,
					size: 40
				},
				this.scene
			);
			this.dome.imageMode = PhotoDome.MODE_MONOSCOPIC;
			this.dome.onLoadObservable.addOnce(() => {
				resolve();
			});
		});
	}

	async activateAr() {
		await this.ngZone.runOutsideAngular(async () => {
			try {
				const supportedAr = await WebXRSessionManager.IsSessionSupportedAsync("immersive-ar");
				const supportedVr = await WebXRSessionManager.IsSessionSupportedAsync("immersive-vr");
				if (supportedAr) {
					this.xr = await this.scene.createDefaultXRExperienceAsync({
						uiOptions: {
							sessionMode: "immersive-ar"
						},
						optionalFeatures: true
					});
				} else if (supportedVr) {
					this.xr = await this.scene.createDefaultXRExperienceAsync({
						uiOptions: {
							sessionMode: "immersive-vr"
						},
						optionalFeatures: true
					});
				}
				//this.xr?.pointerSelection.attach();
			} catch (error) {
				console.error(error);
			}
			/*try {
				//this.xrAnchor = this.xr?.baseExperience.featuresManager.enableFeature(WebXRAnchorSystem, 'latest') as WebXRAnchorSystem;
			} catch (error) {
				console.error(error);
			}*/
			try {
				this.xrPlaneDetection = this.xr?.baseExperience.featuresManager.enableFeature(WebXRPlaneDetector, 1) as WebXRPlaneDetector;
			} catch (error) {
				console.error(error);
			}
			try {
				this.xrBackgroundRemover = this.xr?.baseExperience.featuresManager.enableFeature(WebXRBackgroundRemover, "latest", {
					environmentHelperRemovalFlags: {
						skyBox: true,
						ground: true
					}
				}) as WebXRBackgroundRemover;
			} catch (error) {
				// alert(error);
				console.error(error);
			}
			try {
				this.domOverlayFeature = this.xr?.baseExperience.featuresManager.enableFeature(WebXRFeatureName.DOM_OVERLAY, 1, {
					element: ".overlayAr" // domOverlayRef.current
				}) as WebXRDomOverlay;
			} catch (error) {}
		});
	}

	/********************************************* IMPORT ************************************************/
	importAsset(): Promise<void> {
		this.assetsManager = new AssetsManager(this.scene);
		this.assetsContainer = new AssetContainer(this.scene);
		//this.assetsManager.useDefaultLoadingScreen=false;
		this.assetsManager.autoHideLoadingUI = false;
		this.importTexture();
		this.importImage();
		this.importMesh();
		this.assetsManager.onFinish = this.importFinish.bind(this);
		return this.assetsManager.loadAsync();
	}

	importMesh() {
		const mMeshs = [
			{ name: "waste", url: "/assets/babylon/wasteSorting/scenes/", filename: "Demo0.gltf" },
			{ name: "waste", url: "/assets/babylon/wasteSorting/scenes/", filename: "Pneu.gltf" },
			{ name: "waste", url: "/assets/babylon/wasteSorting/scenes/", filename: "Europalette.babylon" }
			
		];

		mMeshs.forEach(mesh => {
			this.assetsManager.addMeshTask(mesh.name, null, mesh.url, mesh.filename);
		});
	}

	importImage() {
		const images = [
			/*{
				name: "dome",
				url: "assets/babylon/wasteSorting/PANO_20230111_095151_1.jpg"
			}*/
		];

		images.forEach(image => {
			this.assetsManager.addImageTask(image.name, image.url);
		});
	}

	importTexture() {
		const textureMap = [
			/*
			{ name: "parking", url: "assets/babylon/justePoint/textures/parking.png" },
			{ name: "parkingR", url: "assets/babylon/justePoint/textures/parkingR.png" }
        */
		];

		textureMap.forEach(texture => {
			this.assetsManager.addTextureTask(texture.name, texture.url);
		});
	}

	importFinish(tasks: AbstractAssetTask[]) {
		this.textures = new Map<string, Texture>();
		this.images = new Map<string, HTMLImageElement>();
		this.meshs = new Map<string, AbstractMesh>();
		this.recycleMeshs = [];
		this.compostMeshs = [];
		this.scrapMeshs = [];
		this.glassMeshs = [];
		tasks.forEach(task => {
			if (task.isCompleted) {
				if (task instanceof MeshAssetTask) {
					const lTask = task as MeshAssetTask;
					this.assetsContainer.meshes = this.assetsContainer.meshes.concat(lTask.loadedMeshes);
					lTask.loadedMeshes.forEach(mesh => {
						mesh.rotation = new Vector3(0, 0, 0);
						this.meshs.set(mesh.name, mesh);
						//mesh.setEnabled(false);
						mesh.isVisible = false;
						if (
							!this.banList.find(elem => {
								return mesh.name.includes(elem);
							})
						) {
							if (
								this.recycleList.find(elem => {
									return mesh.name.includes(elem);
								})
							) {
								this.addCustomBehavior(mesh, "yellow");
								this.recycleMeshs.push(mesh);
							}
							if (
								this.glassList.find(elem => {
									return mesh.name.includes(elem);
								})
							) {
								this.addCustomBehavior(mesh, "glass");
								this.glassMeshs.push(mesh);
							}
							if (
								this.compostList.find(elem => {
									return mesh.name.includes(elem);
								})
							) {
								this.addCustomBehavior(mesh, "compost");
								this.compostMeshs.push(mesh);
							}
							if (
								this.scrapList.find(elem => {
									return mesh.name.includes(elem);
								})
							) {
								this.addCustomBehavior(mesh, "scrap");
								this.scrapMeshs.push(mesh);
							}
						}
						if (mesh.material) {
							if (mesh.material instanceof MultiMaterial) {
								this.assetsContainer.multiMaterials.push(mesh.material as MultiMaterial);
							} else {
								this.assetsContainer.materials.push(mesh.material);
								this.assetsContainer.textures = this.assetsContainer.textures.concat(mesh.material.getActiveTextures());
							}
						}
					});
				} else if (task instanceof ImageAssetTask) {
					const lTask = task as ImageAssetTask;
					this.images.set(task.name, lTask.image);
				} else if (task instanceof TextureAssetTask) {
					const lTask = task as TextureAssetTask;
					this.assetsContainer.textures.push(lTask.texture);
					this.textures.set(lTask.name, lTask.texture);
				} else {
					console.error("Task Not Handle", task);
				}
			} else {
				console.error(task.errorObject);
			}
		});
	}

	addCustomBehavior(mesh: AbstractMesh, type: string) {
		const displayNameFind = this.displayNameList.find(elem => {
			return mesh.name.includes(elem.needle);
		});
		const displayName = displayNameFind ? displayNameFind.displayName : null;
		const customBehavior = { name: "custom", type, displayName, init: () => {}, attach: () => {}, detach: () => {} };
		mesh.addBehavior(customBehavior);
		// console.error(mesh.name+" : "+(mesh.getBehaviorByName("custom") as any).displayName);
	}

	/******************************************END IMPORT ************************************************/
}

results matching ""

    No results matching ""