Source: objects/AttachedPoint.js

import { BaseTickableObject3D } from './BaseTickableObject3D';

const __ = {
	private: Symbol('private'),
}

/**
 * @class AttachedPoint
 * The attached point.
 * @memberof THING
 * @extends THING.BaseTickableObject3D
 * @public
 */
class AttachedPoint extends BaseTickableObject3D {

	static defaultTagArray = ['Dummy'];

	/**
	 * The attached point object, it would ignore angels and scales from parent.
	 * @param {Object} param The initial parameters.
	 */
	constructor(param = {}) {
		super(param);

		// Before super class could set local position in constructor, so we need to define out of private field
		this._offset = this._offset || null;

		this[__.private] = {};
		let _private = this[__.private];

		_private.object = null;

		let rootNode = this._getRootNode();
		rootNode.add(this.node);

		// Auto initialize offset when user do not provide
		if (!this._offset) {
			this._offset = this.parent.worldToSelf(this.position);
		}
	}

	// #region Private

	_getRootNode() {
		let scene = this.app.scene;
		if (!scene) {
			return null;
		}

		return scene.rootObjects['attachedPoint'].node;
	}

	// #endregion

	// #region Overrides

	onLoadResource(options, resolve, reject) {
		resolve();
	}

	onUpdate(deltaTime) {
		this.position = this.parent.selfToWorld(this._offset);

		super.onUpdate(deltaTime);
	}

	// Attach always add in relative position mode
	onAddToParentNode(node, parentNode, options) {
		parentNode.add(node);
	}

	// #endregion

	// Override to ignore add node to object's parent, all attached points should be add to root node of scene
	onSetParent(parent) {
		super.onSetParent(parent, () => {
			// Do not set offset in initializing process
			if (this._offset) {
				this._offset = parent.worldToSelf(this.position);
			}
		});
	}

	/**
	 * Get/Set local(offset) position of the parent space.
	 * @type {Array<Number>}
	 * @public
	 */
	get localPosition() {
		return this._offset;
	}
	set localPosition(value) {
		this._offset = value.slice(0);
	}

	/**
	 * Check whether it's AttachedPoint type or inherit from it.
	 * @type {Boolean}
	 * @example
	 * let point = new THING.AttachedPoint();
	 * let ret = point.isAttachedPoint;
	 * // @expect(ret == true);
	 * @public
	 */
	get isAttachedPoint() {
		return true;
	}

}

export { AttachedPoint }