import { Utils } from '../common/Utils'
import { MathUtils } from '../math/MathUtils';
import { BaseLine } from './BaseLine';
/**
* PolygonLine - 管状线
*
* 用于创建管线状物体,支持半径、拐角和 UV 流动。
*
* @class PolygonLine
* @memberof THING
* @extends THING.BaseLine
* @public
*
* @example
* const tube = new THING.PolygonLine({
* points: [[0, 0, 0], [5, 0, 0], [5, 0, 5]],
* radius: 0.3,
* style: { color: '#ff8800' },
* });
*/
class PolygonLine extends BaseLine {
static defaultTagArray = ['Line'];
/**
* 构造函数
* </br>注:设置管线的点的参数时,不支持重复点和折回(重复)的线。例如,从点1,点2,点3经过,又从点3折回点2,这样折回的管线是不支持的。
* @param {object} param 初始化参数
* @param {Array<number[]>} param.points 路径坐标的数组
* @param {number} [param.radius=0.5] 管线半径大小(单位米)
* @param {number} [param.cornerRadius=0.3] 拐角半径
* @param {number} [param.cornerSplit=10] 拐角分割面数,数值越大拐角越平滑
* @param {boolean} [param.frenet=true] 是否开启Frenet模式
* @param {number} [param.radialSegments=8] 管线精细度,数值越大拐角越精细
* @param {number} [param.startDegree=0] 起始角度值(沿着管线路径方向顺时针旋转的角度)
* @param {boolean} [param.uvScroll=false] 是否开启贴图流动
* @param {number[]} [param.uvScrollSpeed=[1,0]] 贴图流动速度
* @param {object} [param.style] 线样式
* @constructor
* @public
*/
constructor(param = {}) {
super(param);
}
// #region Overrides
onSetupResource(param) {
this._radius = Utils.parseNumber(param['radius'], 0.5);
this._cornerRadius = Utils.parseNumber(param['cornerRadius'], 0.3);
this._cornerSplit = Utils.parseNumber(param['cornerSplit'], 10);
this._frenet = Utils.parseBoolean(param['frenet'], true);
this._radialSegments = Utils.parseNumber(param['radialSegments'], 8);
this._startDegree = Utils.parseNumber(param['startDegree'], 0);
super.onSetupResource(param);
}
onCreateBodyNode(param) {
const node = Utils.createObject('PolygonLine', { app: this.app });
return node;
}
onSetupBodyNode(node) {
super.onSetupBodyNode(node);
node.setRadius(this._radius);
node.setCornerRadius(this._cornerRadius);
node.setCornerSplit(this._cornerSplit);
node.setFrenet(this._frenet);
node.setRadialSegments(this._radialSegments);
node.setStartRad(MathUtils.degToRad(this._startDegree));
}
onRefreshAttributes() {
let bodyNode = this.bodyNode;
bodyNode.setRadius(this._radius);
bodyNode.setCornerRadius(this._cornerRadius);
bodyNode.setCornerSplit(this._cornerSplit);
bodyNode.setFrenet(this._frenet);
bodyNode.setRadialSegments(this._radialSegments);
bodyNode.setStartRad(MathUtils.degToRad(this._startDegree));
}
onExportExternalData() {
let external = Object.assign({}, super.onExportExternalData());
Utils.setAttributeIfExist(external, 'radius', this);
Utils.setAttributeIfExist(external, 'cornerRadius', this);
Utils.setAttributeIfExist(external, 'cornerSplit', this);
Utils.setAttributeIfExist(external, 'frenet', this);
Utils.setAttributeIfExist(external, 'radialSegments', this);
Utils.setAttributeIfExist(external, 'startDegree', this);
return external;
}
setUv(uv) {
Utils.warn('PolygonLine.setUv is not supported.');
}
getUv() {
Utils.warn('PolygonLine.getUv is not supported.');
return [];
}
// #endregion
// #region Accessor
/**
* 获取/设置本地坐标系下线路面的朝向
* @type {Array<number>}
* @example
* // 获取朝向
* const facingDirection = this.facingDirection;
* // 设置朝向
* this.facingDirection = [0, 0, 1];
* @public
*/
get facingDirection() {
let target = [0, 0, 0];
return this.bodyNode.getUpDirection(target);
}
set facingDirection(value) {
this.bodyNode.setUpDirection(value);
}
/**
* 管线半径(单位:米)
* @default 0.5
* @type {number}
* @example
* // 获取管线半径
* const radius = this.radius;
* // 设置管线半径
* this.radius = 1.0;
* @public
*/
get radius() {
return this._radius;
}
set radius(value) {
this._radius = value;
this.bodyNode.setRadius(this._radius);
}
/**
* 管线转弯半径
* @default 0.3
* @type {number}
* @example
* // 获取管线转弯半径
* const cornerRadius = this.cornerRadius;
* // 设置管线转弯半径
* this.cornerRadius = 0.5;
* @public
*/
get cornerRadius() {
return this._cornerRadius;
}
set cornerRadius(value) {
this._cornerRadius = value;
this.bodyNode.setCornerRadius(this._cornerRadius);
}
/**
* 获取/设置拐角分割面数,数值越大拐角越平滑(必须是整数)
* @default 10
* @type {number}
* @example
* // 获取拐角分割面数
* const cornerSplit = this.cornerSplit;
* // 设置拐角分割面数
* this.cornerSplit = 20;
* @public
*/
get cornerSplit() {
return this._cornerSplit;
}
set cornerSplit(value) {
this._cornerSplit = MathUtils.toInteger(value);
this.bodyNode.setCornerSplit(this._cornerSplit);
}
/**
* 开启/关闭 Frenet 模式
* @default true
* @type {boolean}
* @public
*/
get frenet() {
return this._frenet;
}
set frenet(value) {
this._frenet = value;
this.bodyNode.setFrenet(this._frenet);
}
/**
* 获取/设置管线精细度,数值越大拐角越精细(必须是大于2的整数)
* @default 8
* @type {number}
* @example
* // 获取管线精细度
* const radialSegments = this.radialSegments;
* // 设置管线精细度
* this.radialSegments = 16;
* @public
*/
get radialSegments() {
return this._radialSegments;
}
set radialSegments(value) {
this._radialSegments = value;
this.bodyNode.setRadialSegments(this._radialSegments);
}
/**
* 获取/设置起始角度值(沿着管线路径方向顺时针旋转的角度)
* @default 0
* @type {number}
* @example
* // 获取起始角度值
* const startDegree = this.startDegree;
* // 设置起始角度值
* this.startDegree = 90;
* @public
*/
get startDegree() {
return this._startDegree;
}
set startDegree(value) {
this._startDegree = value;
this.bodyNode.setStartRad(MathUtils.degToRad(this._startDegree));
}
// #endregion
get isPolygonLine() {
return true;
}
}
export { PolygonLine }