forked from playcanvas/engine
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmorph-target.js
More file actions
132 lines (107 loc) · 4.47 KB
/
morph-target.js
File metadata and controls
132 lines (107 loc) · 4.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
import { BoundingBox } from '../shape/bounding-box.js';
import { BUFFER_STATIC, SEMANTIC_ATTR0, TYPE_FLOAT32 } from '../graphics/constants.js';
import { VertexBuffer } from '../graphics/vertex-buffer.js';
import { VertexFormat } from '../graphics/vertex-format.js';
/**
* @class
* @name MorphTarget
* @classdesc A Morph Target (also known as Blend Shape) contains deformation data to apply to existing mesh.
* Multiple morph targets can be blended together on a mesh. This is useful for effects that are hard to achieve with conventional animation and skinning.
* @param {object} options - Object for passing optional arguments.
* @param {ArrayBuffer} options.deltaPositions - An array of 3-dimensional vertex position offsets.
* @param {number} options.deltaPositionsType - A format to store position offsets inside {@link VertexBuffer}. Defaults to {@link TYPE_FLOAT32} if not provided.
* @param {ArrayBuffer} [options.deltaNormals] - An array of 3-dimensional vertex normal offsets.
* @param {number} options.deltaNormalsType - A format to store normal offsets inside {@link VertexBuffer}. Defaults to {@link TYPE_FLOAT32} if not provided.
* @param {string} [options.name] - Name.
* @param {BoundingBox} [options.aabb] - Bounding box. Will be automatically generated, if undefined.
* @param {number} [options.defaultWeight] - Default blend weight to use for this morph target.
*/
class MorphTarget {
constructor(options) {
if (arguments.length === 2) {
// #if _DEBUG
console.warn('DEPRECATED: Passing graphicsDevice to MorphTarget is deprecated, please remove the parameter.');
// #endif
options = arguments[1];
}
this.options = options;
this._name = options.name;
this._defaultWeight = options.defaultWeight || 0;
// bounds
this.aabb = options.aabb;
if (!this.aabb) {
this.aabb = new BoundingBox();
if (options.deltaPositions)
this.aabb.compute(options.deltaPositions);
}
// store delta positions, used by aabb evaluation
this.deltaPositions = options.deltaPositions;
}
/**
* @name MorphTarget#name
* @type {string}
* @readonly
* @description The name of the morph target.
*/
get name() {
return this._name;
}
/**
* @name MorphTarget#defaultWeight
* @type {number}
* @readonly
* @description The default weight of the morph target.
*/
get defaultWeight() {
return this._defaultWeight;
}
get morphPositions() {
return !!this._vertexBufferPositions || !!this.texturePositions;
}
get morphNormals() {
return !!this._vertexBufferNormals || !!this.textureNormals;
}
_postInit() {
// release original data
this.options = null;
}
_initVertexBuffers(graphicsDevice) {
var options = this.options;
this._vertexBufferPositions = this._createVertexBuffer(graphicsDevice, options.deltaPositions, options.deltaPositionsType);
this._vertexBufferNormals = this._createVertexBuffer(graphicsDevice, options.deltaNormals, options.deltaNormalsType);
// access positions from vertex buffer when needed
if (this._vertexBufferPositions) {
this.deltaPositions = this._vertexBufferPositions.lock();
}
}
_createVertexBuffer(device, data, dataType = TYPE_FLOAT32) {
if (data) {
// create vertex buffer with specified type (or float32), and semantic of ATTR0 which gets replaced at runtime with actual semantic
var formatDesc = [{ semantic: SEMANTIC_ATTR0, components: 3, type: dataType }];
return new VertexBuffer(device, new VertexFormat(device, formatDesc), data.length / 3, BUFFER_STATIC, data);
}
return null;
}
_setTexture(name, texture) {
this[name] = texture;
}
destroy() {
if (this._vertexBufferPositions) {
this._vertexBufferPositions.destroy();
this._vertexBufferPositions = null;
}
if (this._vertexBufferNormals) {
this._vertexBufferNormals.destroy();
this._vertexBufferNormals = null;
}
if (this.texturePositions) {
this.texturePositions.destroy();
this.texturePositions = null;
}
if (this.textureNormals) {
this.textureNormals.destroy();
this.textureNormals = null;
}
}
}
export { MorphTarget };