@babylonjs/core
Version:
Getting started? Play directly with the Babylon.js API using our [playground](https://playground.babylonjs.com/). It also contains a lot of samples to learn how to use it.
370 lines • 12.6 kB
JavaScript
import { __decorate } from "../tslib.es6.js";
import { Observable } from "../Misc/observable.js";
import { EngineStore } from "../Engines/engineStore.js";
import { VertexBuffer } from "../Buffers/buffer.js";
import { serialize } from "../Misc/decorators.js";
import { SerializationHelper } from "../Misc/decorators.serialization.js";
import { GetClass } from "../Misc/typeStore.js";
/**
* Defines a target to use with MorphTargetManager
* @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/morphTargets
*/
export class MorphTarget {
/**
* Gets or sets the influence of this target (ie. its weight in the overall morphing)
*/
get influence() {
return this._influence;
}
set influence(influence) {
if (this._influence === influence) {
return;
}
const previous = this._influence;
this._influence = influence;
if (this.onInfluenceChanged.hasObservers()) {
this.onInfluenceChanged.notifyObservers(previous === 0 || influence === 0);
}
}
/**
* Gets or sets the animation properties override
*/
get animationPropertiesOverride() {
if (!this._animationPropertiesOverride && this._scene) {
return this._scene.animationPropertiesOverride;
}
return this._animationPropertiesOverride;
}
set animationPropertiesOverride(value) {
this._animationPropertiesOverride = value;
}
/**
* Creates a new MorphTarget
* @param name defines the name of the target
* @param influence defines the influence to use
* @param scene defines the scene the morphtarget belongs to
*/
constructor(
/** defines the name of the target */
name, influence = 0, scene = null) {
this.name = name;
/**
* Gets or sets the list of animations
*/
this.animations = [];
this._positions = null;
this._normals = null;
this._tangents = null;
this._uvs = null;
this._uv2s = null;
this._colors = null;
this._uniqueId = 0;
/**
* Observable raised when the influence changes
*/
this.onInfluenceChanged = new Observable();
/** @internal */
this._onDataLayoutChanged = new Observable();
this._animationPropertiesOverride = null;
this.id = name;
this._scene = scene || EngineStore.LastCreatedScene;
this.influence = influence;
if (this._scene) {
this._uniqueId = this._scene.getUniqueId();
}
}
/**
* Gets the unique ID of this manager
*/
get uniqueId() {
return this._uniqueId;
}
/**
* Gets a boolean defining if the target contains position data
*/
get hasPositions() {
return !!this._positions;
}
/**
* Gets a boolean defining if the target contains normal data
*/
get hasNormals() {
return !!this._normals;
}
/**
* Gets a boolean defining if the target contains tangent data
*/
get hasTangents() {
return !!this._tangents;
}
/**
* Gets a boolean defining if the target contains texture coordinates data
*/
get hasUVs() {
return !!this._uvs;
}
/**
* Gets a boolean defining if the target contains texture coordinates 2 data
*/
get hasUV2s() {
return !!this._uv2s;
}
get hasColors() {
return !!this._colors;
}
/**
* Gets the number of vertices stored in this target
*/
get vertexCount() {
return this._positions
? this._positions.length / 3
: this._normals
? this._normals.length / 3
: this._tangents
? this._tangents.length / 3
: this._uvs
? this._uvs.length / 2
: this._uv2s
? this._uv2s.length / 2
: this._colors
? this._colors.length / 4
: 0;
}
/**
* Affects position data to this target
* @param data defines the position data to use
*/
setPositions(data) {
const hadPositions = this.hasPositions;
this._positions = data;
if (hadPositions !== this.hasPositions) {
this._onDataLayoutChanged.notifyObservers(undefined);
}
}
/**
* Gets the position data stored in this target
* @returns a FloatArray containing the position data (or null if not present)
*/
getPositions() {
return this._positions;
}
/**
* Affects normal data to this target
* @param data defines the normal data to use
*/
setNormals(data) {
const hadNormals = this.hasNormals;
this._normals = data;
if (hadNormals !== this.hasNormals) {
this._onDataLayoutChanged.notifyObservers(undefined);
}
}
/**
* Gets the normal data stored in this target
* @returns a FloatArray containing the normal data (or null if not present)
*/
getNormals() {
return this._normals;
}
/**
* Affects tangent data to this target
* @param data defines the tangent data to use
*/
setTangents(data) {
const hadTangents = this.hasTangents;
this._tangents = data;
if (hadTangents !== this.hasTangents) {
this._onDataLayoutChanged.notifyObservers(undefined);
}
}
/**
* Gets the tangent data stored in this target
* @returns a FloatArray containing the tangent data (or null if not present)
*/
getTangents() {
return this._tangents;
}
/**
* Affects texture coordinates data to this target
* @param data defines the texture coordinates data to use
*/
setUVs(data) {
const hadUVs = this.hasUVs;
this._uvs = data;
if (hadUVs !== this.hasUVs) {
this._onDataLayoutChanged.notifyObservers(undefined);
}
}
/**
* Gets the texture coordinates data stored in this target
* @returns a FloatArray containing the texture coordinates data (or null if not present)
*/
getUVs() {
return this._uvs;
}
/**
* Affects texture coordinates 2 data to this target
* @param data defines the texture coordinates 2 data to use
*/
setUV2s(data) {
const hadUV2s = this.hasUV2s;
this._uv2s = data;
if (hadUV2s !== this.hasUV2s) {
this._onDataLayoutChanged.notifyObservers(undefined);
}
}
/**
* Gets the texture coordinates 2 data stored in this target
* @returns a FloatArray containing the texture coordinates 2 data (or null if not present)
*/
getUV2s() {
return this._uv2s;
}
/**
* Affects color data to this target
* @param data defines the color data to use
*/
setColors(data) {
const hadColors = this.hasColors;
this._colors = data;
if (hadColors !== this.hasColors) {
this._onDataLayoutChanged.notifyObservers(undefined);
}
}
/**
* Gets the color data stored in this target
* @returns a FloatArray containing the color data (or null if not present)
*/
getColors() {
return this._colors;
}
/**
* Clone the current target
* @returns a new MorphTarget
*/
clone() {
const newOne = SerializationHelper.Clone(() => new MorphTarget(this.name, this.influence, this._scene), this);
newOne._positions = this._positions;
newOne._normals = this._normals;
newOne._tangents = this._tangents;
newOne._uvs = this._uvs;
newOne._uv2s = this._uv2s;
newOne._colors = this._colors;
return newOne;
}
/**
* Serializes the current target into a Serialization object
* @returns the serialized object
*/
serialize() {
const serializationObject = {};
serializationObject.name = this.name;
serializationObject.influence = this.influence;
serializationObject.positions = Array.prototype.slice.call(this.getPositions());
if (this.id != null) {
serializationObject.id = this.id;
}
if (this.hasNormals) {
serializationObject.normals = Array.prototype.slice.call(this.getNormals());
}
if (this.hasTangents) {
serializationObject.tangents = Array.prototype.slice.call(this.getTangents());
}
if (this.hasUVs) {
serializationObject.uvs = Array.prototype.slice.call(this.getUVs());
}
if (this.hasUV2s) {
serializationObject.uv2s = Array.prototype.slice.call(this.getUV2s());
}
if (this.hasColors) {
serializationObject.colors = Array.prototype.slice.call(this.getColors());
}
// Animations
SerializationHelper.AppendSerializedAnimations(this, serializationObject);
return serializationObject;
}
/**
* Returns the string "MorphTarget"
* @returns "MorphTarget"
*/
getClassName() {
return "MorphTarget";
}
// Statics
/**
* Creates a new target from serialized data
* @param serializationObject defines the serialized data to use
* @param scene defines the hosting scene
* @returns a new MorphTarget
*/
static Parse(serializationObject, scene) {
const result = new MorphTarget(serializationObject.name, serializationObject.influence);
result.setPositions(serializationObject.positions);
if (serializationObject.id != null) {
result.id = serializationObject.id;
}
if (serializationObject.normals) {
result.setNormals(serializationObject.normals);
}
if (serializationObject.tangents) {
result.setTangents(serializationObject.tangents);
}
if (serializationObject.uvs) {
result.setUVs(serializationObject.uvs);
}
if (serializationObject.uv2s) {
result.setUV2s(serializationObject.uv2s);
}
if (serializationObject.colors) {
result.setColors(serializationObject.colors);
}
// Animations
if (serializationObject.animations) {
for (let animationIndex = 0; animationIndex < serializationObject.animations.length; animationIndex++) {
const parsedAnimation = serializationObject.animations[animationIndex];
const internalClass = GetClass("BABYLON.Animation");
if (internalClass) {
result.animations.push(internalClass.Parse(parsedAnimation));
}
}
if (serializationObject.autoAnimate && scene) {
scene.beginAnimation(result, serializationObject.autoAnimateFrom, serializationObject.autoAnimateTo, serializationObject.autoAnimateLoop, serializationObject.autoAnimateSpeed || 1.0);
}
}
return result;
}
/**
* Creates a MorphTarget from mesh data
* @param mesh defines the source mesh
* @param name defines the name to use for the new target
* @param influence defines the influence to attach to the target
* @returns a new MorphTarget
*/
static FromMesh(mesh, name, influence) {
if (!name) {
name = mesh.name;
}
const result = new MorphTarget(name, influence, mesh.getScene());
result.setPositions(mesh.getVerticesData(VertexBuffer.PositionKind));
if (mesh.isVerticesDataPresent(VertexBuffer.NormalKind)) {
result.setNormals(mesh.getVerticesData(VertexBuffer.NormalKind));
}
if (mesh.isVerticesDataPresent(VertexBuffer.TangentKind)) {
result.setTangents(mesh.getVerticesData(VertexBuffer.TangentKind));
}
if (mesh.isVerticesDataPresent(VertexBuffer.UVKind)) {
result.setUVs(mesh.getVerticesData(VertexBuffer.UVKind));
}
if (mesh.isVerticesDataPresent(VertexBuffer.UV2Kind)) {
result.setUV2s(mesh.getVerticesData(VertexBuffer.UV2Kind));
}
if (mesh.isVerticesDataPresent(VertexBuffer.ColorKind)) {
result.setColors(mesh.getVerticesData(VertexBuffer.ColorKind));
}
return result;
}
}
__decorate([
serialize()
], MorphTarget.prototype, "id", void 0);
//# sourceMappingURL=morphTarget.js.map