@cesium/engine
Version:
CesiumJS is a JavaScript library for creating 3D globes and 2D maps in a web browser without a plugin.
262 lines (243 loc) • 7.11 kB
JavaScript
import ArticulationStageType from "../../Core/ArticulationStageType.js";
import Cartesian3 from "../../Core/Cartesian3.js";
import CesiumMath from "../../Core/Math.js";
import Check from "../../Core/Check.js";
import Frozen from "../../Core/Frozen.js";
import Matrix3 from "../../Core/Matrix3.js";
import Matrix4 from "../../Core/Matrix4.js";
const articulationEpsilon = CesiumMath.EPSILON16;
/**
* An in-memory representation of an articulation stage belonging to a
* {@link ModelArticulation}.
*
* @param {object} options An object containing the following options:
* @param {ModelComponents.ArticulationStage} options.stage The articulation stage components from the 3D model.
* @param {ModelArticulation} options.runtimeArticulation The runtime articulation that this stage belongs to.
*
* @alias ModelArticulationStage
* @constructor
*
* @private
*/
function ModelArticulationStage(options) {
options = options ?? Frozen.EMPTY_OBJECT;
const stage = options.stage;
const runtimeArticulation = options.runtimeArticulation;
//>>includeStart('debug', pragmas.debug);
Check.typeOf.object("options.stage", stage);
Check.typeOf.object("options.runtimeArticulation", runtimeArticulation);
//>>includeEnd('debug');
this._stage = stage;
this._runtimeArticulation = runtimeArticulation;
this._name = stage.name;
this._type = stage.type;
this._minimumValue = stage.minimumValue;
this._maximumValue = stage.maximumValue;
this._currentValue = stage.initialValue;
}
Object.defineProperties(ModelArticulationStage.prototype, {
/**
* The internal articulation stage that this runtime stage represents.
*
* @memberof ModelArticulationStage.prototype
* @type {ModelComponents.ArticulationStage}
* @readonly
*
* @private
*/
stage: {
get: function () {
return this._stage;
},
},
/**
* The runtime articulation that this stage belongs to.
*
* @memberof ModelArticulationStage.prototype
* @type {ModelArticulation}
* @readonly
*
* @private
*/
runtimeArticulation: {
get: function () {
return this._runtimeArticulation;
},
},
/**
* The name of this articulation stage.
*
* @memberof ModelArticulationStage.prototype
* @type {string}
* @readonly
*
* @private
*/
name: {
get: function () {
return this._name;
},
},
/**
* The type of this articulation stage. This specifies which of the
* node's properties is modified by the stage's value.
*
* @memberof ModelArticulationStage.prototype
* @type {ArticulationStageType}
* @readonly
*
* @private
*/
type: {
get: function () {
return this._type;
},
},
/**
* The minimum value of this articulation stage.
*
* @memberof ModelArticulationStage.prototype
* @type {number}
* @readonly
*
* @private
*/
minimumValue: {
get: function () {
return this._minimumValue;
},
},
/**
* The maximum value of this articulation stage.
*
* @memberof ModelArticulationStage.prototype
* @type {number}
* @readonly
*
* @private
*/
maximumValue: {
get: function () {
return this._maximumValue;
},
},
/**
* The current value of this articulation stage.
*
* @memberof ModelArticulationStage.prototype
* @type {number}
*
* @private
*/
currentValue: {
get: function () {
return this._currentValue;
},
set: function (value) {
//>>includeStart('debug', pragmas.debug);
Check.typeOf.number("value", value);
//>>includeEnd('debug');
value = CesiumMath.clamp(value, this.minimumValue, this.maximumValue);
if (
!CesiumMath.equalsEpsilon(
this._currentValue,
value,
articulationEpsilon,
)
) {
this._currentValue = value;
this.runtimeArticulation._dirty = true;
}
},
},
});
const scratchArticulationCartesian = new Cartesian3();
const scratchArticulationRotation = new Matrix3();
/**
* Modifies a Matrix4 by applying a transformation for a given value of a stage.
* Note that the <code>result</code> parameter is not just a container for the
* returned value. The incoming value of <code>result</code> is part of the
* computation itself. Various stages of an articulation can be multiplied
* together, so their transformations are all merged into a composite Matrix4
* representing them all.
*
* @param {Matrix4} result The matrix to be modified.
* @returns {Matrix4} The transformed matrix as requested by the articulation stage.
*
* @private
*/
ModelArticulationStage.prototype.applyStageToMatrix = function (result) {
//>>includeStart('debug', pragmas.debug);
Check.typeOf.object("result", result);
//>>includeEnd('debug');
const type = this.type;
const value = this.currentValue;
const cartesian = scratchArticulationCartesian;
let rotation;
switch (type) {
case ArticulationStageType.XROTATE:
rotation = Matrix3.fromRotationX(
CesiumMath.toRadians(value),
scratchArticulationRotation,
);
result = Matrix4.multiplyByMatrix3(result, rotation, result);
break;
case ArticulationStageType.YROTATE:
rotation = Matrix3.fromRotationY(
CesiumMath.toRadians(value),
scratchArticulationRotation,
);
result = Matrix4.multiplyByMatrix3(result, rotation, result);
break;
case ArticulationStageType.ZROTATE:
rotation = Matrix3.fromRotationZ(
CesiumMath.toRadians(value),
scratchArticulationRotation,
);
result = Matrix4.multiplyByMatrix3(result, rotation, result);
break;
case ArticulationStageType.XTRANSLATE:
cartesian.x = value;
cartesian.y = 0.0;
cartesian.z = 0.0;
result = Matrix4.multiplyByTranslation(result, cartesian, result);
break;
case ArticulationStageType.YTRANSLATE:
cartesian.x = 0.0;
cartesian.y = value;
cartesian.z = 0.0;
result = Matrix4.multiplyByTranslation(result, cartesian, result);
break;
case ArticulationStageType.ZTRANSLATE:
cartesian.x = 0.0;
cartesian.y = 0.0;
cartesian.z = value;
result = Matrix4.multiplyByTranslation(result, cartesian, result);
break;
case ArticulationStageType.XSCALE:
cartesian.x = value;
cartesian.y = 1.0;
cartesian.z = 1.0;
result = Matrix4.multiplyByScale(result, cartesian, result);
break;
case ArticulationStageType.YSCALE:
cartesian.x = 1.0;
cartesian.y = value;
cartesian.z = 1.0;
result = Matrix4.multiplyByScale(result, cartesian, result);
break;
case ArticulationStageType.ZSCALE:
cartesian.x = 1.0;
cartesian.y = 1.0;
cartesian.z = value;
result = Matrix4.multiplyByScale(result, cartesian, result);
break;
case ArticulationStageType.UNIFORMSCALE:
result = Matrix4.multiplyByUniformScale(result, value, result);
break;
default:
break;
}
return result;
};
export default ModelArticulationStage;