-
Notifications
You must be signed in to change notification settings - Fork 46
/
skin.ts
53 lines (48 loc) · 1.84 KB
/
skin.ts
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
import { Joint } from "./joint"
import { Container3D } from "../container"
import { Mat4 } from "../math/mat4"
/**
* Represents a skin used for vertex skinning.
*/
export class Skin {
private _jointMatrices: Float32Array[] = []
private _jointNormalMatrices: Float32Array[] = []
private _transformIds: number[] = []
/** The joint normal matrices which has been calculated. */
jointNormalMatrices = new Float32Array(this.joints.length * 16)
/** The joint matrices which has been calculated. */
jointMatrices = new Float32Array(this.joints.length * 16)
/**
* Creates a new skin.
* @param parent The parent container node for the skin.
* @param joints The array of joints included in the skin.
*/
constructor(readonly parent: Container3D, readonly joints: Joint[]) {
for (let i = 0; i < joints.length; i++) {
this._transformIds.push(-1)
this._jointMatrices.push(
new Float32Array(this.jointMatrices.buffer, 16 * 4 * i, 16))
this._jointNormalMatrices.push(
new Float32Array(this.jointNormalMatrices.buffer, 16 * 4 * i, 16))
}
}
/**
* Calculates the joint matrices.
*/
calculateJointMatrices() {
for (let i = 0; i < this.joints.length; i++) {
if (this.joints[i].transform._worldID === this._transformIds[i]) {
// The joint transform hasn't changed, no need to calculate.
continue
}
this._transformIds[i] = this.joints[i].transform._worldID
Mat4.multiply(this.joints[i].worldTransform.array,
this.joints[i].inverseBindMatrix, this._jointMatrices[i])
Mat4.multiply(this.parent.transform.inverseWorldTransform.array,
this._jointMatrices[i], this._jointMatrices[i])
Mat4.invert(this._jointMatrices[i], this._jointNormalMatrices[i])
Mat4.transpose(
this._jointNormalMatrices[i], this._jointNormalMatrices[i])
}
}
}