Source: resources/GeometryResource.js

import { Utils } from '../common/Utils'
import { RefCountObject } from '@uino/base-thing';

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

/**
 * @class GeometryResource
 * The geometry resource.
 * @memberof THING
 */
class GeometryResource extends RefCountObject {

	/**
	 * The geometry resource to build custom geometry info in scene.
	 * @param {Object} param The initial parameters.
	 */
	constructor(param = {}) {
		super(param);

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

		if (param['array']) {
			_private.vertexData = Utils.cloneObject(param['array'], false);
		}
		else {
			_private.vertexData = this._buildVertexBuffer(param);
		}

		_private.resource = Utils.createObject('GeometryResource');
		_private.resource.setVertexData(_private.vertexData);
	}

	// #region Private

	_buildVertexBuffer(param) {
		const attributes = [
			{ toName: 'positions', fromName: 'position', stride: 3 },
			{ toName: 'normals', fromName: 'normal', stride: 3 },
			{ toName: 'uvs', fromName: 'uv', stride: 2 },
			{ toName: 'uvs2', fromName: 'uv2', stride: 2 }
		];

		let vertexData = {
			vertexBuffer: [],
			attributes: {},
			indices: []
		};

		for (let i = 0; i < attributes.length; i++) {
			let fromName = attributes[i].fromName;
			let array = param[fromName];
			if (!array) {
				continue;
			}

			let stride = attributes[i].stride;

			vertexData.vertexBuffer.push({
				array,
				stride
			});

			let toName = attributes[i].toName;
			vertexData.attributes[toName] = vertexData.vertexBuffer.length - 1;
		}

		if (param['index']) {
			vertexData.indices = param['index'].slice(0);
		}

		return vertexData;
	}

	// #endregion

	refresh() {
		this.resource._geometry.attributes.a_Position.buffer.version++;
		// let positions = this.resource.getAttribute('a_Position');
		// this.resource.setAttribute('a_Position', positions);
	}

	// #region Accessor

	/**
	 * Get vertex data.
	 * @type {Object}
	 */
	get vertexData() {
		let _private = this[__.private];

		return _private.vertexData;
	}

	/**
	 * Get resource.
	 * @type {Object}
	 */
	get resource() {
		let _private = this[__.private];

		return _private.resource;
	}

	/**
	 * Get/Set position.
	 * @type {Array<Number>}
	 */
	get position() {
		return this.resource.getAttribute('a_Position');
	}
	set position(array) {
		this.resource.setAttribute('a_Position', new Float32Array(array));
	}

	/**
	 * Set uv.
	 * @type {Array<Number>}
	 */
	set uv(array) {
		this.resource.setAttribute('a_Uv', new Float32Array(array));
	}

	/**
	 * Set uv2.
	 * @type {Array<Number>}
	 * @private
	 */
	set uv2(array) {
		this.resource.setAttribute('a_Uv2', new Float32Array(array));
	}

	/**
	 * Set normal.
	 * @type {Array<Number>}
	 */
	set normal(array) {
		this.resource.setAttribute('a_Normal', new Float32Array(array));
	}

	// #endregion

	get isGeometryResource() {
		return true;
	}

}

export { GeometryResource }