import { v4 as uuid } from '../../node_modules/uuid/dist/esm-browser/index.js';
import { copyProps, checkPropTypes, UUIDRegex } from '../lib.js';
import { Raycaster, Scene, Vector3 } from '../../node_modules/three/build/three.module.js';
import { CSS2DObject } from '../../node_modules/three/examples/jsm/renderers/CSS2DRenderer.js';
import { EventEmitter } from '../event_emitter.js';
import { Project } from '../project.js';
import { View } from './view.js';
import { BlockInstance } from '../configurator/block_instance.js';
/**
* @class Marker
* @event Marker#occlusionchange
*/
class Marker extends EventEmitter {
/**
* @param {Object} settings
* @param {Vector3} settings.position
* @param {HTMLElement} settings.HTMLElement
* @param {View} settings.view
* @param {BlockInstance} [settings.blockInstance]
*/
constructor(settings) {
super();
checkPropTypes(
settings,
{
position: Vector3,
HTMLElement: HTMLElement,
view: View
},
{
blockInstance: BlockInstance
}
);
this.addEvent('occlusionchange');
this.id = uuid();
if (settings.blockInstance) {
this._blockInstance = settings.blockInstance;
}
this._position = settings.position;
this.view = settings.view;
this.HTMLElement = settings.HTMLElement;
this.CSS2DObject = new CSS2DObject(this.HTMLElement);
this.CSS2DObject.position.copy(this._position);
this.CSS2DObject.name = 'marker';
this.CSS2DObject.visible = true;
this.relinkObject3D();
}
/** @type {UUID} */
id;
/** @type {HTMLElement} */
HTMLElement;
/** @type {Vector3} */
_position;
get position() {
return this._position;
}
/** @type {number} */
_distance;
get distance() {
return this._distance;
}
/** @type {boolean} */
_occlusion;
get occlusion() {
return this._occlusion;
}
/**
*
*/
relinkObject3D() {
// console.warn(this.label, 'relink');
if (this._blockInstance) {
const BISceneObject = this.view.scene.getObjectByName(this._blockInstance.id);
//Directly get the sceneObject from the content.main[quality]
//const BISceneObject = this._blockInstance._content.main[ this._blockInstance._loadingQuality ]
// console.log(BISceneObject)
if (!BISceneObject) {
console.warn(`Could not find scene object for ${this._blockInstance.label}`);
return this.clear();
}
else {
this.sceneParent = BISceneObject;
}
}
else {
this.sceneParent = this.view.scene;
}
this.sceneParent.add(this.CSS2DObject);
// console.log(this.CSS2DObject)
}
update() {
const direction = this.view.perspectiveCamera.position.clone().sub(this._position).normalize();
this.view.rayCaster.set(
this._position,
direction
);
this._distance = this._position.distanceTo(this.view.perspectiveCamera.position);
const intersections = this.view.rayCaster.intersectObjects(this.view.scene.children, true);
const occlusion = intersections.length > 0 ? true : false;
if (occlusion !== this._occlusion) {
this._occlusion = occlusion;
this.emit('occlusionchange', this.occlusion);
}
}
clear() {
this.sceneParent.remove(this.CSS2DObject);
}
}
export { Marker };