import { InheritType } from '../const';
import { Utils } from '../common/Utils';
import { MathUtils } from '../math/MathUtils';
import { BaseTickableObject3D } from './BaseTickableObject3D';
const GROUND_FLOW_TYPE = {
"Center": 0,
"Linear": 1
}
const GROUND_FLOW_TYPE_REVERSE = {};
for (let key in GROUND_FLOW_TYPE) {
GROUND_FLOW_TYPE_REVERSE[GROUND_FLOW_TYPE[key]] = key;
}
/**
* EffectGroundObject - 特效地面对象
*
* 用于创建带有特效效果的地面对象,支持自定义颜色和流动颜色。
*
* @class EffectGroundObject
* @memberof THING
* @extends THING.BaseTickableObject3D
* @public
*/
class EffectGroundObject extends BaseTickableObject3D {
/**
* 特效地面对象的构造函数。
* @param {object} param 初始化参数
* @param {string} param.url 地面图片的URL
* @param {string} param.maskUrl 遮罩图片的URL
* @param {string} param.color 地面颜色
* @param {string} param.flowColor 流动颜色
*/
constructor(param = {}) {
super(param);
this._initParam(param);
}
/**
* Get type.
* @returns {string} 类型。
*/
getType() {
return 'EffectGroundObject';
}
_initParam(param) {
param.url = param.url && Utils.resolveURL(param.url);
param.maskUrl = param.maskUrl && Utils.resolveURL(param.maskUrl);
param.alphaMap = param.alphaMap && Utils.resolveURL(param.alphaMap);
param.color = param.color && Utils.parseColor(param.color);
param.groundFlowType = param['groundFlowType'] === undefined ? 0 : GROUND_FLOW_TYPE[param['groundFlowType']];
if (param.flowColor) {
param.flowColor = Utils.parseColor(param.flowColor);
param.flowColor.length = 3;
}
}
hasResource() {
return true;
}
/**
* When load reosurce.
* @param {object} options The options to load.
* @param {Function} resolve The promise resolve callback function.
* @param {Function} reject The promise reject callback function.
* @private
*/
onLoadRenderableResource(options, resolve, reject) {
const node = Utils.createObject('EffectGroundObjectNode', { external: { uScene: this.node._uScene, param: options }});
this.level.config.ignoreStyle = true; // skip level outline
this._node = node;
this.body.setNode(node);
this.bounding.inheritType = InheritType.Jump;
this.updateGround(this.parent);
this.pickable = false;
resolve();
}
onUpdate(deltaTime) {
if (this._node && !this._node.groundReflect) {
this._node.update(deltaTime);
}
}
/**
* 更新地面父对象并计算位置。
* @param {THING.Object3D} target 根据目标的边界框计算和更新特效地面的位置和缩放。
* @public
* @example
* const building = app.query('.Building')[0];
* effectGround.updateGround(building);
*/
updateGround(target) {
if (!this._node) { return; }
if (target) {
this.parent = target;
const bbx = target.getOBB(true, false);
const radius = bbx.halfSize[1] + 0.2 - this._node.groundClearance;
const rDis = MathUtils.scaleVector(target.up, radius);
let pos = MathUtils.subVector(bbx.center, rDis);
pos[0] += this._node.groundOffsetX;
pos[2] += this._node.groundOffsetY;
this.position = [pos[0], pos[1], pos[2]];
let scaleFactor = MathUtils.scaleVector([bbx.radius * 2, 1, bbx.radius * 2], this._node.sizeFactor); // use box's diameter
this.scale = [scaleFactor[0], scaleFactor[1], scaleFactor[2]];
this.angles = target.angles;
}
else if (!target) {
this.position = [this._node.groundOffsetX, this._node.groundClearance, this._node.groundOffsetY];
this.scale = [this._node.sizeFactor, 1, this._node.sizeFactor];
}
}
/**
* 设置特效地面是否具有反射效果。
* @param {boolean} value 是否具有反射效果。
* @public
*/
set groundReflect(value) {
this._node.groundReflect = value;
if (this.groundReflect) {
this.updateGround(this.parent);
}
}
/**
* 获取特效地面是否具有反射效果。
* @type {boolean}
* @public
*/
get groundReflect() {
return this._node.groundReflect;
}
/**
* 设置尺寸因子。
* @param {number} value 尺寸因子。
* @public
*/
set sizeFactor(value) {
this._node.sizeFactor = value;
this.updateGround(this.parent);
}
/**
* 获取尺寸因子。
* @type {number}
* @public
*/
get sizeFactor() {
return this._node.sizeFactor;
}
/**
* 设置地面图片的URL。
* @param {string} value 地面图片的URL。
* @public
*/
set imageUrl(value) {
value = Utils.resolveURL(value);
this._url = this._node.imageUrl = value;
}
/**
* 获取地面图片的URL。
* @type {string}
* @public
*/
get imageUrl() {
return this._node.imageUrl;
}
/**
* 设置遮罩图片的URL。
* @param {string} value 遮罩图片的URL。
* @public
*/
set maskUrl(value) {
value = Utils.resolveURL(value);
this._node.maskUrl = value;
}
/**
* 获取遮罩图片的URL。
* @type {string}
* @public
*/
get maskUrl() {
return this._node.maskUrl;
}
/**
* 设置不透明度。
* @param {number} value 不透明度。
* @public
*/
set opacityValue(value) {
this._node.opacityValue = value;
}
/**
* 获取不透明度。
* @type {number}
* @public
*/
get opacityValue() {
return this._node.opacityValue;
}
/**
* 设置发光强度因子。
* @param {number} value 发光强度因子。
* @public
*/
set glowFactorValue(value) {
this._node.glowFactorValue = value;
}
/**
* 获取发光强度因子。
* @type {number}
* @public
*/
get glowFactorValue() {
return this._node.glowFactorValue;
}
/**
* 设置纹理UV重复因子。
* @param {number} value 纹理UV重复因子。
* @public
*/
set repeatFactorValue(value) {
this._node.repeatFactorValue = value;
}
/**
* 获取纹理UV重复因子。
* @type {number}
* @public
*/
get repeatFactorValue() {
return this._node.repeatFactorValue;
}
/**
* 设置纹理在U轴上的重复因子。
* @param {number} value 纹理在U轴上的重复因子。
* @public
*/
set repeatFactorValueX(value) {
this._node.repeatFactorValueX = value;
}
/**
* 获取纹理在U轴上的重复因子。
* @type {number}
* @public
*/
get repeatFactorValueX() {
return this._node.repeatFactorValueX;
}
/**
* 设置纹理在V轴上的重复因子。
* @param {number} value 纹理在V轴上的重复因子。
* @public
*/
set repeatFactorValueY(value) {
this._node.repeatFactorValueY = value;
}
/**
* 获取纹理在V轴上的重复因子。
* @type {number}
* @public
*/
get repeatFactorValueY() {
return this._node.repeatFactorValueY;
}
/**
* 设置地面颜色。
* @param {string} value 地面颜色。
* @public
*/
set groundColorValue(value) {
const colorArray = Utils.parseColor(value);
this._node.groundColorValue = colorArray;
}
/**
* 获取地面颜色。
* @type {string}
* @public
*/
get groundColorValue() {
const value = Utils.toColorHexString(this._node.groundColorValue);
return value;
}
/**
* 设置流动颜色。
* @param {string} value 流动颜色。
* @public
*/
set flowColorValue(value) {
const colorArray = Utils.parseColor(value);
colorArray.length = 3;
this._node.flowColorValue = colorArray;
}
/**
* 获取流动颜色。
* @type {string}
* @public
*/
get flowColorValue() {
const value = Utils.toColorHexString(this._node.flowColorValue);
return value;
}
/**
* 设置流动动画速度。
* @param {number} value 流动动画速度。
* @public
*/
set animationSpeed(value) {
this._node.animationSpeed = value;
}
/**
* 获取流动动画速度。
* @type {number}
* @public
*/
get animationSpeed() {
return this._node.animationSpeed;
}
/**
* 设置地面高度。
* @param {number} value 地面高度。
* @public
*/
set groundClearance(value) {
this._node.groundClearance = value;
this.updateGround(this.parent);
}
/**
* 获取地面高度。
* @type {number}
* @public
*/
get groundClearance() {
return this._node.groundClearance;
}
set groundOffsetX(value) {
this._node.groundOffsetX = value;
this.updateGround(this.parent);
}
get groundOffsetX() {
return this._node.groundOffsetX;
}
set groundOffsetY(value) {
this._node.groundOffsetY = value;
this.updateGround(this.parent);
}
get groundOffsetY() {
return this._node.groundOffsetY;
}
/**
* 获取地面类型。
* @type {string}
* @public
*/
get groundType() {
return this._node.groundType;
}
/**
* 设置透明贴图。
* @type {string}
* @public
*/
set alphaMap(value) {
value = Utils.resolveURL(value);
this._node.alphaMapUrl = value;
}
/**
* 获取透明贴图路径。
* @type {string}
* @public
*/
get alphaMap() {
return this._node.alphaMapUrl;
}
set groundFlowType(value) {
const flowType = GROUND_FLOW_TYPE[value];
if (Utils.isValid(flowType)) {
this._node.groundFlowType = flowType;
}
}
get groundFlowType() {
return GROUND_FLOW_TYPE_REVERSE[this._node.groundFlowType];
}
set groundFlowAngle(value) {
this._node.groundFlowAngle = value;
}
get groundFlowAngle() {
return this._node.groundFlowAngle;
}
set receiveShadow(value) {
this._node.receiveShadow = value;
}
get receiveShadow() {
return this._node.receiveShadow;
}
set unlitSSR(value) {
this._node.unlitSSR = value;
}
get unlitSSR() {
return this._node.unlitSSR;
}
dispose() {
this._node.dispose();
}
copy(source) {
this._node.copy(source);
}
}
export { EffectGroundObject }