Source: view/marker.js

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 };