import { Object3D } from "./Object3D";
import { Utils } from "../common/Utils"
const __ = {
private: Symbol('private'),
}
const _defaultSize = {
length: 60,
width: 60,
density: 1
};
/**
* Grid - 网格对象
*
* 用于创建场景中的辅助网格,支持自定义平面、长度、宽度和密度。
* @class Grid
* @memberof THING
* @extends THING.Object3D
* @public
* @example
* const grid = new THING.Grid({
* workPlane: 'XZ',
* size: { length: 60, width: 60, density: 1 },
* });
*/
class Grid extends Object3D {
/**
* @typedef {object} GridWorkPlane 网格的平面参数
* @property {Array.<number>} position - 网格的位置,默认[0, 0, 0]
* @property {Array.<number>} quaternion - 网格的四元数,默认[0, 0, 0, 1]
* @property {number} precision - 网格的缩放值,默认0
*/
/**
* @typedef {object} GridSize 网格的大小参数
* @property {number} length - 网格的长度,默认60
* @property {number} width - 网格的宽度,默认60
* @property {number} density - 网格的密度,默认1
*/
/**
* @public
* 网格对象构造函数
* @param {object} param 参数
* @param {GridWorkPlane} param.workPlane - 网格的平面
* @param {GridSize} param.size - 网格的大小
*/
constructor(param) {
super(param);
this[__.private] = {};
let _private = this[__.private];
param = param || {};
_private.gridData = param.workPlane || { position: [0, 0, 0], quaternion: [0, 0, 0, 1], precision: 0 };
_private.size = param.size || _defaultSize;
let lines = Utils.createObject('LineSegments', { app: this.app });
lines.setAttribute('Pickable', false);
lines.getUserData()['isDebugNode'] = true;
_private.lines = lines;
this.node.add(lines);
_private.points = [];
_private.colors = [];
const compatibleRender = this.app.view._compatibleRender;
const centerColor = compatibleRender ? 73 / 255 : 73 / 255 / 1.5;
const outColor = compatibleRender ? 60 / 255 : 60 / 255 / 1.5;
_private.centerColor = [centerColor, centerColor, centerColor];
_private.outColor = [outColor, outColor, outColor];
_private.length = _private.size.length || _defaultSize.length;
_private.width = _private.size.width || _defaultSize.width;
_private.density = _private.size.density || _defaultSize.density;
_private.position = _private.gridData.position;
_private.quaternion = _private.gridData.quaternion;
this._updateLine();
}
onRemove() {
let _private = this[__.private];
_private.line.destroy();
_private.line = null;
super.onRemove();
}
_insertLine(p0, p1, c) {
let _private = this[__.private];
_private.points.push(p0);
_private.colors.push(c);
_private.points.push(p1);
_private.colors.push(c);
}
_updateLine() {
let _private = this[__.private];
_private.points = [];
_private.colors = [];
let _lengthValue = _private.length / 2;
let _widthValue = _private.width / 2;
this._insertLine([_lengthValue, 0, 0], [-_lengthValue, 0, 0], _private.centerColor);
for (let i = _private.density; i <= _private.width / 2; i += _private.density) {
this._insertLine([_lengthValue, 0, i], [-_lengthValue, 0, i], _private.outColor); // z+
this._insertLine([_lengthValue, 0, -i], [-_lengthValue, 0, -i], _private.outColor); // z-
}
this._insertLine([0, 0, _widthValue], [0, 0, -_widthValue], _private.centerColor);
for (let i = _private.density; i <= _private.length / 2; i += _private.density) {
this._insertLine([i, 0, _widthValue], [i, 0, -_widthValue], _private.outColor); // x+
this._insertLine([-i, 0, _widthValue], [-i, 0, -_widthValue], _private.outColor); // x-
}
_private.lines.setSize(_private.points.length);
_private.lines.setPoints(_private.points);
_private.lines.setColors(_private.colors);
}
/**
* 网格的长度
* @type {number}
* @public
*/
set length(number) {
let _private = this[__.private];
if (_private.length !== number) {
_private.length = number;
this._updateLine();
}
}
get length() {
let _private = this[__.private];
return _private.length;
}
/**
* 网格的宽度
* @type {number}
* @public
*/
set width(number) {
let _private = this[__.private];
if (_private.width !== number) {
_private.width = number;
this._updateLine();
}
}
get width() {
let _private = this[__.private];
return _private.width;
}
/**
* 网格的密度,每个网格的长度(数字必须大于0)
* @type {number}
* @public
*/
set density(number) {
let _private = this[__.private];
if (_private.density !== number) {
_private.density = number;
this._updateLine();
}
}
get density() {
let _private = this[__.private];
return _private.density;
}
}
export { Grid }