-
Notifications
You must be signed in to change notification settings - Fork 0
/
scenegraph.js
79 lines (72 loc) · 2.33 KB
/
scenegraph.js
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
import {m4, setUniforms, setBuffersAndAttributes, drawBufferInfo} from './twgl-full.module.js';
export class Node {
constructor (data) {
this.children = [];
this.worldMatrix = m4.identity();
this.transforms = {
translation: [0, 0, 0],
rotation: [0, 0, 0, 1],
scale: [1, 1, 1],
};
// add custom properties
if (data) {
Object.assign(this, data);
}
}
render(gl, viewMatrix) {
const projectionMatrix = m4.multiply(viewMatrix, this.worldMatrix);
for (const primitive of this.primitives) {
gl.useProgram(primitive.programInfo.program);
setUniforms(primitive.programInfo, {u_matrix: projectionMatrix}, this.uniforms);
setBuffersAndAttributes(gl, primitive.programInfo, primitive.vertexArrayInfo);
drawBufferInfo(gl, primitive.vertexArrayInfo);
}
}
get transformMatrix() {
// in case we need some specific transform,
// give the object a localMatrix to replace the default
if (this.localMatrix) {return this.localMatrix};
let transMatrix = m4.translation(this.transforms.translation);
m4.multiply(transMatrix, m4.rotationFromQuaternion(this.transforms.rotation), transMatrix);
m4.scale(transMatrix, this.transforms.scale, transMatrix);
return transMatrix;
}
setParent(parent) {
if (this.parent) {
const index = this.parent.children.indexOf(this);
if (index >= 0) {
this.parent.children.splice(index, 1);
}
}
if (parent) {
parent.children.push(this);
}
this.parent = parent;
}
updateWorldMatrix(parentWorldMatrix) {
if (parentWorldMatrix) {
// a matrix was passed in so do the math and
// store the result in `this.worldMatrix`.
m4.multiply(parentWorldMatrix, this.transformMatrix, this.worldMatrix);
} else {
// no matrix was passed in so just copy.
m4.copy(this.transformMatrix, this.worldMatrix);
}
// now process all the children
this.children.forEach((child) => {
child.updateWorldMatrix(this.worldMatrix);
});
}
}
// walk down the tree, building an array of nodes that contain draw data
export function makeDrawList(node) {
let drawList = [];
if (node.drawable) {drawList.push(node)}
if (node.children)
{
for (const child of node.children) {
drawList.push(...makeDrawList(child));
}
}
return drawList;
}