import { Utils } from '../common/Utils'
import { MathUtils } from '../math/MathUtils';
import { BaseDynamicPoints } from './BaseDynamicPoints';
let _originalQuat = [0, 0, 0, 1];
/**
* ExtrudeShape - 拉伸几何体
*
* 用于通过平面轮廓和高度的方式创建拉伸几何体。
* @class ExtrudeShape
* @memberof THING
* @extends THING.BaseDynamicPoints
* @public
* @example
* const shape = new THING.ExtrudeShape({
* selfPlanePoints: [[0, 0], [2, 0], [2, 2], [0, 2]],
* height: 3,
* });
*/
class ExtrudeShape extends BaseDynamicPoints {
static defaultTagArray = ['Geometry'];
/**
* 创建一个ExtrudeShape对象,用于在场景中通过高度创建多边形形状。
* @param {object} param 初始化参数
* @param {Array<Array<number>>} [param.selfPlanePoints] 自身空间中的平面点
* @param {Array<Array<Array<number>>>} [param.selfPlaneHoles] 自身空间中的平面孔洞
* @param {Array<Array<Array<number>>>} [param.selfHoles] 自身空间中的孔洞
* @param {Array<Array<Array<number>>>} [param.holes] 世界空间中的孔洞
* @param {number} [param.height] 拉伸高度
* @param {string} [param.visibleDirection] 可见方向,可选值:'Both'、'Top'、'Bottom'
* @constructor
* @public
*/
constructor(param = {}) {
super(param);
}
// #region Private Functions
/**
* Refresh holes.
* @private
*/
_refreshHoles() {
let selfPlaneHoles = this.selfPlaneHoles;
this.bodyNode.setHoles(selfPlaneHoles);
}
// #endregion
// #region Overrides
onSetupResource(param) {
// 读取点数据,写到参数里传给父类处理
const selfPlanePoints = param['selfPlanePoints'];
if (selfPlanePoints) {
param['selfPoints'] = convertPlanePoints(selfPlanePoints);
}
// 读取洞数据
const selfPlaneHoles = param['selfPlaneHoles'];
if (selfPlaneHoles) {
this._selfHoles = convertPlaneHolesPoints(selfPlaneHoles);
}
else if (param['selfHoles']) {
this._selfHoles = param['selfHoles'];
}
else if (param['holes']) {
this._selfHoles = param['holes'].map(hole => {
return hole.map(_hole => {
return this.worldToSelf(_hole);
});
});
}
else {
this._selfHoles = [];
}
this._height = Utils.parseNumber(param['height'], 0);
this._visibleDirection = param['visibleDirection'] || 'Both';
super.onSetupResource(param);
}
onCreateBodyNode(param) {
const node = Utils.createObject('ExtrudeShape', { app: this.app });
node.setQuaternion(_originalQuat);
return node;
}
onSetupBodyNode(node) {
super.onSetupBodyNode(node);
const holes = this.selfPlaneHoles;
if (holes) {
node.setHoles(holes);
}
if (this._height) {
node.setHeight(this._height);
}
if (this._visibleDirection) {
node.setVisibleDirection(this._visibleDirection);
}
}
onGetSelfPoints(selfPoints) {
return selfPoints.map(point => {
return [point[0], point[2]];
});
}
onExportExternalData() {
let external = Object.assign({}, super.onExportExternalData());
Utils.setAttributeIfExist(external, 'selfPlanePoints', this);
Utils.setAttributeIfExist(external, 'selfPlaneHoles', this);
Utils.setAttributeIfExist(external, 'selfHoles', this);
Utils.setAttributeIfExist(external, 'height', this);
Utils.setAttributeIfExist(external, 'visibleDirection', this);
return external;
}
// #endregion
// #region Accessor
/**
* Get/Set the plane points in self space.
* @type {Array<Array<number>>}
* @private
*/
get selfPlanePoints() {
return this.points.map(point => {
let selfPoint = this.worldToSelf(point);
return [selfPoint[0], selfPoint[2]];
});
}
set selfPlanePoints(value = []) {
if (!MathUtils.isClockWise(value)) {
const reversedArr = value.slice().reverse();
this.points = (reversedArr).map(point => {
return this.selfToWorld([point[0], 0, point[1]]);
});
}
else {
this.points = (value).map(point => {
return this.selfToWorld([point[0], 0, point[1]]);
});
}
}
/**
* Get/Set the plane holes in self space.
* @type {Array<Array<Array<number>>>}
* @private
*/
get selfPlaneHoles() {
return this._selfHoles.map(hole => {
return hole.map(_hole => {
return [_hole[0], _hole[2]];
});
});
}
set selfPlaneHoles(value) {
this._selfHoles = value.map(hole => {
return hole.map(_hole => {
return [_hole[0], 0, _hole[1]];
});
});
this._refreshHoles();
}
/**
* 获取/设置自身空间中的孔洞。
* @type {Array<Array<Array<number>>>}
* @public
*/
get selfHoles() {
return this._selfHoles;
}
set selfHoles(value = []) {
this._selfHoles = value.slice(0);
this._refreshHoles();
}
/**
* 获取/设置世界空间中的孔洞。
* @type {Array<Array<Array<number>>>}
* @public
*/
get holes() {
return this._selfHoles.map(hole => {
return hole.map(_hole => {
return this.selfToWorld(_hole);
});
});
}
set holes(value = []) {
this._selfHoles = value.map(hole => {
return hole.map(_hole => {
return this.worldToSelf(_hole);
});
});
this._refreshHoles();
}
/**
* 获取/设置高度。
* @type {number}
* @public
*/
get height() {
return this._height;
}
set height(value) {
this._height = value;
this.bodyNode.setHeight(value);
}
/**
* 获取/设置生成底部或顶部面的可见性。
* @public
* @type {THING.ExtrudeShapeDirection}
*/
set visibleDirection(value) {
this._visibleDirection = value;
this.bodyNode.setVisibleDirection(value);
}
get visibleDirection() {
return this._visibleDirection;
}
// #endregion
get isExtrudeShape() {
return true;
}
}
export { ExtrudeShape }
function convertPlanePoints(value) {
if (!MathUtils.isClockWise(value)) {
const reversedArr = value.slice().reverse();
return (reversedArr).map(point => {
return [point[0], 0, point[1]];
});
}
else {
return (value).map(point => {
return [point[0], 0, point[1]];
});
}
}
function convertPlaneHolesPoints(value) {
return value.map(hole => {
return hole.map(_hole => {
return [_hole[0], 0, _hole[1]];
});
});
}