Add existing to tracked
This commit is contained in:
+214
@@ -0,0 +1,214 @@
|
||||
import Check from "../../Core/Check.js";
|
||||
import Frozen from "../../Core/Frozen.js";
|
||||
import defined from "../../Core/defined.js";
|
||||
import Matrix4 from "../../Core/Matrix4.js";
|
||||
import ModelArticulationStage from "./ModelArticulationStage.js";
|
||||
|
||||
/**
|
||||
* An in-memory representation of an articulation that affects nodes in the
|
||||
* {@link ModelSceneGraph}. This is defined in a model by the
|
||||
* <code>AGI_articulations</code> extension.
|
||||
*
|
||||
* @param {object} options An object containing the following options:
|
||||
* @param {ModelComponents.Articulation} options.articulation The articulation components from the 3D model.
|
||||
* @param {ModelSceneGraph} options.sceneGraph The scene graph this articulation belongs to.
|
||||
*
|
||||
* @alias ModelArticulation
|
||||
* @constructor
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
function ModelArticulation(options) {
|
||||
options = options ?? Frozen.EMPTY_OBJECT;
|
||||
|
||||
const articulation = options.articulation;
|
||||
const sceneGraph = options.sceneGraph;
|
||||
//>>includeStart('debug', pragmas.debug);
|
||||
Check.typeOf.object("options.articulation", articulation);
|
||||
Check.typeOf.object("options.sceneGraph", sceneGraph);
|
||||
//>>includeEnd('debug');
|
||||
|
||||
this._articulation = articulation;
|
||||
this._sceneGraph = sceneGraph;
|
||||
|
||||
this._name = articulation.name;
|
||||
this._runtimeStages = [];
|
||||
this._runtimeStagesByName = {};
|
||||
|
||||
// Will be populated as the runtime nodes are created
|
||||
this._runtimeNodes = [];
|
||||
|
||||
// Set to true so that the first call to
|
||||
// ModelSceneGraph.applyArticulations will work.
|
||||
this._dirty = true;
|
||||
|
||||
initialize(this);
|
||||
}
|
||||
|
||||
Object.defineProperties(ModelArticulation.prototype, {
|
||||
/**
|
||||
* The internal articulation that this runtime articulation represents.
|
||||
*
|
||||
* @memberof ModelArticulation.prototype
|
||||
* @type {ModelComponents.Articulation}
|
||||
* @readonly
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
articulation: {
|
||||
get: function () {
|
||||
return this._articulation;
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* The scene graph that this articulation belongs to.
|
||||
*
|
||||
* @memberof ModelArticulation.prototype
|
||||
* @type {ModelSceneGraph}
|
||||
* @readonly
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
sceneGraph: {
|
||||
get: function () {
|
||||
return this._sceneGraph;
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* The name of this articulation.
|
||||
*
|
||||
* @memberof ModelArticulation.prototype
|
||||
* @type {string}
|
||||
* @readonly
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
name: {
|
||||
get: function () {
|
||||
return this._name;
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* The runtime stages that belong to this articulation.
|
||||
*
|
||||
* @memberof ModelArticulation.prototype
|
||||
* @type {ModelArticulationStage[]}
|
||||
* @readonly
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
runtimeStages: {
|
||||
get: function () {
|
||||
return this._runtimeStages;
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* The runtime nodes that are affected by this articulation.
|
||||
*
|
||||
* @memberof ModelArticulation.prototype
|
||||
* @type {ModelRuntimeNode[]}
|
||||
* @readonly
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
runtimeNodes: {
|
||||
get: function () {
|
||||
return this._runtimeNodes;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
function initialize(runtimeArticulation) {
|
||||
const articulation = runtimeArticulation.articulation;
|
||||
|
||||
const stages = articulation.stages;
|
||||
const length = stages.length;
|
||||
|
||||
const runtimeStages = runtimeArticulation._runtimeStages;
|
||||
const runtimeStagesByName = runtimeArticulation._runtimeStagesByName;
|
||||
for (let i = 0; i < length; i++) {
|
||||
const stage = stages[i];
|
||||
const runtimeStage = new ModelArticulationStage({
|
||||
stage: stage,
|
||||
runtimeArticulation: runtimeArticulation,
|
||||
});
|
||||
|
||||
// Store the stages in an array to preserve the order in which
|
||||
// they appeared in the 3D model.
|
||||
runtimeStages.push(runtimeStage);
|
||||
|
||||
// Store the stages in a dictionary for retrieval by name.
|
||||
const stageName = stage.name;
|
||||
runtimeStagesByName[stageName] = runtimeStage;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current value of an articulation stage.
|
||||
*
|
||||
* @param {string} stageName The name of the articulation stage.
|
||||
* @param {number} value The numeric value of this stage of the articulation.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
ModelArticulation.prototype.setArticulationStage = function (stageName, value) {
|
||||
const stage = this._runtimeStagesByName[stageName];
|
||||
if (defined(stage)) {
|
||||
stage.currentValue = value;
|
||||
}
|
||||
};
|
||||
|
||||
const scratchArticulationMatrix = new Matrix4();
|
||||
const scratchNodeMatrix = new Matrix4();
|
||||
|
||||
/**
|
||||
* Applies the chain of articulation stages to the transform of each node that
|
||||
* participates in the articulation. This only recomputes the node transforms
|
||||
* if any stage in the articulation has been modified.
|
||||
* <p>
|
||||
* Note that this will overwrite any existing transformations on participating
|
||||
* nodes.
|
||||
* </p>
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
ModelArticulation.prototype.apply = function () {
|
||||
if (!this._dirty) {
|
||||
return;
|
||||
}
|
||||
this._dirty = false;
|
||||
|
||||
let articulationMatrix = Matrix4.clone(
|
||||
Matrix4.IDENTITY,
|
||||
scratchArticulationMatrix,
|
||||
);
|
||||
|
||||
let i;
|
||||
const stages = this._runtimeStages;
|
||||
const stagesLength = stages.length;
|
||||
|
||||
// Compute the result of the articulation stages...
|
||||
for (i = 0; i < stagesLength; i++) {
|
||||
const stage = stages[i];
|
||||
articulationMatrix = stage.applyStageToMatrix(articulationMatrix);
|
||||
}
|
||||
|
||||
// ...then apply it to the transforms of the affected nodes.
|
||||
const nodes = this._runtimeNodes;
|
||||
const nodesLength = nodes.length;
|
||||
for (i = 0; i < nodesLength; i++) {
|
||||
const node = nodes[i];
|
||||
const transform = Matrix4.multiplyTransformation(
|
||||
node.originalTransform,
|
||||
articulationMatrix,
|
||||
scratchNodeMatrix,
|
||||
);
|
||||
node.transform = transform;
|
||||
}
|
||||
};
|
||||
|
||||
export default ModelArticulation;
|
||||
Reference in New Issue
Block a user