bg2e-js 2.3.11 → 2.3.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bg2e-js.js +356 -326
- package/dist/bg2e-js.js.map +1 -1
- package/package.json +56 -56
- package/src/app/AppController.ts +39 -39
- package/src/app/Bg2KeyboardEvent.ts +54 -54
- package/src/app/Bg2MouseEvent.ts +82 -82
- package/src/app/Bg2TouchEvent.ts +18 -18
- package/src/app/Canvas.ts +108 -108
- package/src/app/EventBase.ts +10 -10
- package/src/app/MainLoop.ts +273 -273
- package/src/app/index.ts +24 -24
- package/src/base/Color.ts +134 -134
- package/src/base/Environment.ts +183 -183
- package/src/base/Light.ts +192 -192
- package/src/base/Material.ts +620 -620
- package/src/base/PolyList.ts +365 -365
- package/src/base/Texture.ts +620 -620
- package/src/base/index.ts +81 -81
- package/src/db/Bg2LoaderPlugin.ts +143 -143
- package/src/db/DBPluginApi.ts +48 -48
- package/src/db/Loader.ts +116 -116
- package/src/db/LoaderPlugin.ts +34 -34
- package/src/db/MtlParser.ts +7 -7
- package/src/db/ObjLoaderPlugin.ts +54 -54
- package/src/db/ObjParser.ts +252 -252
- package/src/db/ObjWriterPlugin.ts +18 -18
- package/src/db/VitscnjLoaderPlugin.ts +112 -112
- package/src/db/Writer.ts +52 -52
- package/src/db/WriterPlugin.ts +22 -22
- package/src/db/index.ts +44 -44
- package/src/debug/DebugRenderer.ts +173 -173
- package/src/debug/WebGLTextureViewer.ts +75 -75
- package/src/debug/index.ts +6 -6
- package/src/index.html +11 -11
- package/src/index.ts +33 -33
- package/src/manipulation/SelectionBuffer.ts +81 -81
- package/src/manipulation/SelectionHighlight.ts +105 -84
- package/src/manipulation/SelectionIdAssignVisitor.ts +96 -96
- package/src/manipulation/SelectionManager.ts +196 -188
- package/src/manipulation/SelectionMode.ts +6 -6
- package/src/math/Mat3.ts +259 -259
- package/src/math/Mat4.ts +710 -710
- package/src/math/MatrixStrategy.ts +25 -25
- package/src/math/Quat.ts +65 -65
- package/src/math/Vec.ts +753 -753
- package/src/math/constants.ts +46 -46
- package/src/math/functions.ts +103 -103
- package/src/math/index.ts +74 -74
- package/src/phsics/joint.ts +137 -137
- package/src/primitives/arrow.ts +57 -57
- package/src/primitives/cone.ts +138 -138
- package/src/primitives/cube.ts +60 -60
- package/src/primitives/cylinder.ts +216 -216
- package/src/primitives/index.ts +13 -13
- package/src/primitives/plane.ts +31 -31
- package/src/primitives/sphere.ts +809 -809
- package/src/react/useBg2e.ts +69 -69
- package/src/render/BRDFIntegrationMap.ts +4 -4
- package/src/render/Environment.ts +135 -135
- package/src/render/FrameBuffer.ts +35 -35
- package/src/render/MaterialRenderer.ts +34 -34
- package/src/render/Pipeline.ts +108 -108
- package/src/render/PolyListRenderer.ts +47 -47
- package/src/render/RenderBuffer.ts +197 -197
- package/src/render/RenderQueue.ts +198 -198
- package/src/render/RenderState.ts +116 -116
- package/src/render/Renderer.ts +248 -248
- package/src/render/SceneAppController.ts +250 -250
- package/src/render/SceneRenderer.ts +387 -387
- package/src/render/Shader.ts +32 -32
- package/src/render/ShadowRenderer.ts +176 -176
- package/src/render/SkyCube.ts +105 -105
- package/src/render/SkySphere.ts +117 -117
- package/src/render/TextureMergerRenderer.ts +70 -70
- package/src/render/TextureRenderer.ts +34 -34
- package/src/render/index.ts +67 -67
- package/src/render/webgl/FrameBuffer.ts +9 -9
- package/src/render/webgl/MaterialRenderer.ts +112 -112
- package/src/render/webgl/Pipeline.ts +88 -88
- package/src/render/webgl/PolyListRenderer.ts +260 -260
- package/src/render/webgl/RenderBuffer.ts +226 -226
- package/src/render/webgl/Renderer.ts +262 -262
- package/src/render/webgl/SceneRenderer.ts +67 -67
- package/src/render/webgl/ShaderProgram.ts +424 -424
- package/src/render/webgl/ShadowRenderer.ts +6 -6
- package/src/render/webgl/SkyCube.ts +15 -15
- package/src/render/webgl/SkySphere.ts +15 -15
- package/src/render/webgl/State.ts +152 -152
- package/src/render/webgl/TextureRenderer.ts +167 -167
- package/src/render/webgl/VertexBuffer.ts +137 -137
- package/src/render/webgl/index.ts +35 -35
- package/src/scene/Camera.ts +458 -458
- package/src/scene/Chain.ts +44 -44
- package/src/scene/ChainJoint.ts +58 -58
- package/src/scene/Component.ts +177 -177
- package/src/scene/ComponentMap.ts +106 -106
- package/src/scene/Drawable.ts +154 -154
- package/src/scene/EnvironmentComponent.ts +141 -141
- package/src/scene/FindNodeVisitor.ts +59 -59
- package/src/scene/LightComponent.ts +154 -154
- package/src/scene/MatrixState.ts +46 -46
- package/src/scene/Node.ts +328 -328
- package/src/scene/NodeVisitor.ts +15 -15
- package/src/scene/OrbitCameraController.ts +450 -450
- package/src/scene/SmoothOrbitCameraController.ts +99 -99
- package/src/scene/Transform.ts +73 -73
- package/src/scene/index.ts +60 -60
- package/src/shaders/BasicDiffuseColorShader.ts +111 -111
- package/src/shaders/BasicPBRLightShader.ts +276 -276
- package/src/shaders/DebugRenderShader.ts +97 -97
- package/src/shaders/DepthRenderShader.ts +127 -127
- package/src/shaders/IrradianceMapCubeShader.ts +115 -115
- package/src/shaders/PBRLightIBLShader.ts +486 -486
- package/src/shaders/PickSelectionShader.ts +101 -101
- package/src/shaders/PresentDebugFramebufferShader.ts +118 -118
- package/src/shaders/PresentTextureShader.ts +99 -99
- package/src/shaders/SelectionHighlightShader.ts +143 -127
- package/src/shaders/ShaderFunction.ts +318 -318
- package/src/shaders/SkyCubeShader.ts +93 -93
- package/src/shaders/SkySphereShader.ts +102 -102
- package/src/shaders/SpecularMapCubeShader.ts +164 -164
- package/src/shaders/TextureMergerShader.ts +171 -171
- package/src/shaders/index.ts +36 -36
- package/src/shaders/webgl/color_correction.glsl +47 -47
- package/src/shaders/webgl/constants.glsl +6 -6
- package/src/shaders/webgl/index.ts +70 -70
- package/src/shaders/webgl/normal_map.glsl +9 -9
- package/src/shaders/webgl/pbr.glsl +173 -173
- package/src/shaders/webgl/uniforms.glsl +91 -91
- package/src/shaders/webgl_shader_lib.ts +213 -213
- package/src/tools/BinaryResourceProvider.ts +14 -14
- package/src/tools/ImageResourceProvider.ts +66 -66
- package/src/tools/MaterialModifier.ts +446 -446
- package/src/tools/Resource.ts +203 -203
- package/src/tools/ResourceProvider.ts +69 -69
- package/src/tools/TextResourceProvider.ts +24 -24
- package/src/tools/TextureCache.ts +51 -51
- package/src/tools/TextureResourceDatabase.ts +100 -100
- package/src/tools/UserAgent.ts +362 -362
- package/src/tools/VideoResourceProvider.ts +50 -50
- package/src/tools/WriteStrategy.ts +22 -22
- package/src/tools/base64.ts +11 -11
- package/src/tools/crypto.ts +19 -19
- package/src/tools/endiantess.ts +13 -13
- package/src/tools/image.ts +18 -18
- package/src/tools/index.ts +41 -41
- package/src/tools/processType.ts +39 -39
- package/src/vite-env.d.ts +12 -12
package/src/scene/Node.ts
CHANGED
|
@@ -1,328 +1,328 @@
|
|
|
1
|
-
import Mat4 from '../math/Mat4';
|
|
2
|
-
import ComponentMap from './ComponentMap';
|
|
3
|
-
import Component from './Component';
|
|
4
|
-
import Renderer from '../render/Renderer';
|
|
5
|
-
import Camera from './Camera';
|
|
6
|
-
import Transform from './Transform';
|
|
7
|
-
import Drawable from './Drawable';
|
|
8
|
-
import LightComponent from './LightComponent';
|
|
9
|
-
|
|
10
|
-
export function bindRenderer(node: Node, renderer: Renderer): void {
|
|
11
|
-
(node as any)._bindedRenderer = renderer;
|
|
12
|
-
node.components.forEach(comp => {
|
|
13
|
-
comp.bindRenderer(renderer);
|
|
14
|
-
});
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export async function init(node: Node): Promise<void> {
|
|
18
|
-
for (const i in node.components.array) {
|
|
19
|
-
const comp = node.components.array[i];
|
|
20
|
-
if (!(comp as any)._initialized) {
|
|
21
|
-
await comp.init();
|
|
22
|
-
(comp as any)._initialized = true;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
(node as any)._sceneChanged = false;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export default class Node {
|
|
29
|
-
private _name: string;
|
|
30
|
-
private _enabled: boolean;
|
|
31
|
-
private _steady: boolean;
|
|
32
|
-
private _components: ComponentMap;
|
|
33
|
-
private _parent: Node | null;
|
|
34
|
-
private _children: Node[];
|
|
35
|
-
private _bindedRenderer?: Renderer;
|
|
36
|
-
private _sceneChanged: boolean = false;
|
|
37
|
-
|
|
38
|
-
private _postRedisplayFrames: number = 0;
|
|
39
|
-
|
|
40
|
-
constructor(name: string = "") {
|
|
41
|
-
this._name = name;
|
|
42
|
-
this._enabled = true;
|
|
43
|
-
this._steady = false;
|
|
44
|
-
|
|
45
|
-
this._components = new ComponentMap(this);
|
|
46
|
-
|
|
47
|
-
this._parent = null;
|
|
48
|
-
this._children = [];
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
get name(): string { return this._name; }
|
|
52
|
-
set name(n: string) { this._name = n; }
|
|
53
|
-
|
|
54
|
-
get enabled(): boolean { return this._enabled; }
|
|
55
|
-
set enabled(e: boolean) { this._enabled = e; }
|
|
56
|
-
|
|
57
|
-
get steady(): boolean { return this._steady; }
|
|
58
|
-
set steady(s: boolean) { this._steady = s; }
|
|
59
|
-
|
|
60
|
-
get components(): ComponentMap { return this._components; }
|
|
61
|
-
|
|
62
|
-
get parent(): Node | null { return this._parent; }
|
|
63
|
-
get children(): Node[] { return this._children; }
|
|
64
|
-
|
|
65
|
-
clone(cloneChildren: boolean = false): Node {
|
|
66
|
-
const newNode = new Node();
|
|
67
|
-
newNode.assign(this, cloneChildren);
|
|
68
|
-
return newNode;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
assign(other: Node, cloneChildren: boolean = false): void {
|
|
72
|
-
this._name = other.name + "-copy";
|
|
73
|
-
this._enabled = other.enabled;
|
|
74
|
-
this._steady = other.steady;
|
|
75
|
-
this._components.assign(other._components);
|
|
76
|
-
if (cloneChildren) {
|
|
77
|
-
this._children = [];
|
|
78
|
-
other._children.forEach(c => {
|
|
79
|
-
this._children.push(c.clone(cloneChildren));
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
destroy(): void {
|
|
85
|
-
this._components.empty();
|
|
86
|
-
this.emptyChildren();
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
async deserialize(sceneData: any, loader: any): Promise<void> {
|
|
90
|
-
throw new Error("Node.deserialize() not implemented");
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
async serialize(sceneData: any, writer: any): Promise<void> {
|
|
94
|
-
throw new Error("Node.serialice() not implemented");
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
addComponent(component: Component): Component {
|
|
98
|
-
this.components.add(component);
|
|
99
|
-
this.setSceneChanged();
|
|
100
|
-
return component;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
component(typeId: string): Component | undefined {
|
|
104
|
-
return this.components.find(typeId);
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
removeComponent(component: Component | string): void {
|
|
108
|
-
this.components.remove(component);
|
|
109
|
-
this.setSceneChanged();
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
addedToNode(node: Node): void {
|
|
113
|
-
// Override in subclasses if needed
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
removedFromNode(node: Node): void {
|
|
117
|
-
// Override in subclasses if needed
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
// This attribute returns true if a node or component
|
|
121
|
-
// has been added or removed to this node or any child node
|
|
122
|
-
get sceneChanged(): boolean {
|
|
123
|
-
return this._sceneChanged;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
setSceneChanged(): void {
|
|
127
|
-
this._sceneChanged = true;
|
|
128
|
-
if (this._parent) {
|
|
129
|
-
this._parent.setSceneChanged();
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
addChild(node: Node): void {
|
|
134
|
-
if (node._parent) {
|
|
135
|
-
node._parent.removeChild(node);
|
|
136
|
-
}
|
|
137
|
-
node._parent = this;
|
|
138
|
-
this._children.push(node);
|
|
139
|
-
node.addedToNode(this);
|
|
140
|
-
|
|
141
|
-
// If this node has been binded to a renderer, we need to bind
|
|
142
|
-
// the same renderer to any node that is added as child
|
|
143
|
-
if (this._bindedRenderer) {
|
|
144
|
-
bindRenderer(node, this._bindedRenderer);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
this.setSceneChanged();
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
removeChild(node: Node): void {
|
|
151
|
-
if (node._parent === this) {
|
|
152
|
-
node._parent = null;
|
|
153
|
-
node.removedFromNode(this);
|
|
154
|
-
const index = this._children.indexOf(node);
|
|
155
|
-
if (index !== -1) {
|
|
156
|
-
this._children.splice(index, 1);
|
|
157
|
-
this.setSceneChanged();
|
|
158
|
-
}
|
|
159
|
-
else {
|
|
160
|
-
console.warn(`Scene inconsistency found removing node '${ node.name }' from node '${ this.name }'. The parent node is valid, but the child is not present in the children array.`);
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
else {
|
|
164
|
-
throw new Error(`Node.removeChild() - the specified node is not a child of this node.`);
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
emptyChildren(): void {
|
|
169
|
-
this._children.forEach(ch => {
|
|
170
|
-
ch._parent = null;
|
|
171
|
-
ch.removedFromNode(this);
|
|
172
|
-
});
|
|
173
|
-
this._children = [];
|
|
174
|
-
this.setSceneChanged();
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
haveChild(node: Node): boolean {
|
|
178
|
-
return this._children.indexOf(node) !== -1;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
isAncientOf(node: Node): boolean {
|
|
182
|
-
const isNodeAncient = (node: Node | null, ancient: Node): boolean => {
|
|
183
|
-
if (!node || !ancient) {
|
|
184
|
-
return false;
|
|
185
|
-
}
|
|
186
|
-
else if (node._parent === ancient) {
|
|
187
|
-
return true;
|
|
188
|
-
}
|
|
189
|
-
else {
|
|
190
|
-
return isNodeAncient(node._parent, ancient);
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
return isNodeAncient(this, node);
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
// Visitor functions
|
|
197
|
-
accept(nodeVisitor: any): void {
|
|
198
|
-
if (!nodeVisitor.ignoreDisabled || this.enabled) {
|
|
199
|
-
nodeVisitor.visit(this);
|
|
200
|
-
this._children.forEach(ch => ch.accept(nodeVisitor));
|
|
201
|
-
nodeVisitor.didVisit(this);
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
acceptReverse(nodeVisitor: any): void {
|
|
206
|
-
if (!nodeVisitor.ignoreDisabled || this.enabled) {
|
|
207
|
-
if (this._parent) {
|
|
208
|
-
this._parent.acceptReverse(nodeVisitor);
|
|
209
|
-
}
|
|
210
|
-
nodeVisitor.visit(this);
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
async asyncAccept(nodeVisitor: any): Promise<void> {
|
|
215
|
-
if (!nodeVisitor.ignoreDisabled || this.enabled) {
|
|
216
|
-
await nodeVisitor.asyncVisit(this);
|
|
217
|
-
for (const ch in this._children) {
|
|
218
|
-
await this._children[ch].asyncAccept(nodeVisitor);
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
// Used by components to require a redraw of the scene for a certain number of frames.
|
|
224
|
-
// This is needed, for example, when a component changes the material of a drawable,
|
|
225
|
-
// so the change is reflected inmediately in the screen, or when a component generates
|
|
226
|
-
// an animation that needs to be updated for a certain number of frames.
|
|
227
|
-
get postRedisplayFrames(): number {
|
|
228
|
-
return this._postRedisplayFrames;
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
set postRedisplayFrames(frames: number) {
|
|
232
|
-
this._postRedisplayFrames = frames;
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
// Most usual components
|
|
236
|
-
get transform(): Transform | undefined {
|
|
237
|
-
return this.component("Transform") as Transform;
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
get lightComponent(): LightComponent | undefined {
|
|
241
|
-
return this.component("Light") as LightComponent;
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
get drawable(): Drawable | undefined {
|
|
245
|
-
return this.component("Drawable") as Drawable;
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
get camera(): Camera | undefined {
|
|
249
|
-
return this.component("Camera") as Camera;
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
frame(delta: number, modelMatrix: Mat4, renderQueue: any): void {
|
|
253
|
-
const willUpdateComponents: Component[] = [];
|
|
254
|
-
const updateComponents: Component[] = [];
|
|
255
|
-
const drawComponents: Component[] = [];
|
|
256
|
-
this._components.forEach(comp => {
|
|
257
|
-
if (comp.requireWillUpdate) {
|
|
258
|
-
willUpdateComponents.push(comp);
|
|
259
|
-
}
|
|
260
|
-
if (comp.requireUpdate) {
|
|
261
|
-
updateComponents.push(comp);
|
|
262
|
-
}
|
|
263
|
-
if (comp.requireDraw) {
|
|
264
|
-
drawComponents.push(comp);
|
|
265
|
-
}
|
|
266
|
-
});
|
|
267
|
-
|
|
268
|
-
willUpdateComponents.forEach(comp => (comp as any).willUpdate(delta));
|
|
269
|
-
updateComponents.forEach(comp => (comp as any).update(delta, modelMatrix));
|
|
270
|
-
drawComponents.forEach(comp => (comp as any).draw(renderQueue, modelMatrix));
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
keyDown(evt: any): void {
|
|
274
|
-
this._components.forEach(comp => {
|
|
275
|
-
comp.keyDown(evt);
|
|
276
|
-
});
|
|
277
|
-
}
|
|
278
|
-
keyUp(evt: any): void {
|
|
279
|
-
this._components.forEach(comp => {
|
|
280
|
-
comp.keyUp(evt);
|
|
281
|
-
});
|
|
282
|
-
}
|
|
283
|
-
mouseUp(evt: any): void {
|
|
284
|
-
this._components.forEach(comp => {
|
|
285
|
-
comp.mouseUp(evt);
|
|
286
|
-
});
|
|
287
|
-
}
|
|
288
|
-
mouseDown(evt: any): void {
|
|
289
|
-
this._components.forEach(comp => {
|
|
290
|
-
comp.mouseDown(evt);
|
|
291
|
-
});
|
|
292
|
-
}
|
|
293
|
-
mouseMove(evt: any): void {
|
|
294
|
-
this._components.forEach(comp => {
|
|
295
|
-
comp.mouseMove(evt);
|
|
296
|
-
});
|
|
297
|
-
}
|
|
298
|
-
mouseOut(evt: any): void {
|
|
299
|
-
this._components.forEach(comp => {
|
|
300
|
-
comp.mouseOut(evt);
|
|
301
|
-
});
|
|
302
|
-
}
|
|
303
|
-
mouseDrag(evt: any): void {
|
|
304
|
-
this._components.forEach(comp => {
|
|
305
|
-
comp.mouseDrag(evt);
|
|
306
|
-
});
|
|
307
|
-
}
|
|
308
|
-
mouseWheel(evt: any): void {
|
|
309
|
-
this._components.forEach(comp => {
|
|
310
|
-
comp.mouseWheel(evt);
|
|
311
|
-
});
|
|
312
|
-
}
|
|
313
|
-
touchStart(evt: any): void {
|
|
314
|
-
this._components.forEach(comp => {
|
|
315
|
-
comp.touchStart(evt);
|
|
316
|
-
});
|
|
317
|
-
}
|
|
318
|
-
touchMove(evt: any): void {
|
|
319
|
-
this._components.forEach(comp => {
|
|
320
|
-
comp.touchMove(evt);
|
|
321
|
-
});
|
|
322
|
-
}
|
|
323
|
-
touchEnd(evt: any): void {
|
|
324
|
-
this._components.forEach(comp => {
|
|
325
|
-
comp.touchEnd(evt);
|
|
326
|
-
});
|
|
327
|
-
}
|
|
328
|
-
}
|
|
1
|
+
import Mat4 from '../math/Mat4';
|
|
2
|
+
import ComponentMap from './ComponentMap';
|
|
3
|
+
import Component from './Component';
|
|
4
|
+
import Renderer from '../render/Renderer';
|
|
5
|
+
import Camera from './Camera';
|
|
6
|
+
import Transform from './Transform';
|
|
7
|
+
import Drawable from './Drawable';
|
|
8
|
+
import LightComponent from './LightComponent';
|
|
9
|
+
|
|
10
|
+
export function bindRenderer(node: Node, renderer: Renderer): void {
|
|
11
|
+
(node as any)._bindedRenderer = renderer;
|
|
12
|
+
node.components.forEach(comp => {
|
|
13
|
+
comp.bindRenderer(renderer);
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export async function init(node: Node): Promise<void> {
|
|
18
|
+
for (const i in node.components.array) {
|
|
19
|
+
const comp = node.components.array[i];
|
|
20
|
+
if (!(comp as any)._initialized) {
|
|
21
|
+
await comp.init();
|
|
22
|
+
(comp as any)._initialized = true;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
(node as any)._sceneChanged = false;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export default class Node {
|
|
29
|
+
private _name: string;
|
|
30
|
+
private _enabled: boolean;
|
|
31
|
+
private _steady: boolean;
|
|
32
|
+
private _components: ComponentMap;
|
|
33
|
+
private _parent: Node | null;
|
|
34
|
+
private _children: Node[];
|
|
35
|
+
private _bindedRenderer?: Renderer;
|
|
36
|
+
private _sceneChanged: boolean = false;
|
|
37
|
+
|
|
38
|
+
private _postRedisplayFrames: number = 0;
|
|
39
|
+
|
|
40
|
+
constructor(name: string = "") {
|
|
41
|
+
this._name = name;
|
|
42
|
+
this._enabled = true;
|
|
43
|
+
this._steady = false;
|
|
44
|
+
|
|
45
|
+
this._components = new ComponentMap(this);
|
|
46
|
+
|
|
47
|
+
this._parent = null;
|
|
48
|
+
this._children = [];
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
get name(): string { return this._name; }
|
|
52
|
+
set name(n: string) { this._name = n; }
|
|
53
|
+
|
|
54
|
+
get enabled(): boolean { return this._enabled; }
|
|
55
|
+
set enabled(e: boolean) { this._enabled = e; }
|
|
56
|
+
|
|
57
|
+
get steady(): boolean { return this._steady; }
|
|
58
|
+
set steady(s: boolean) { this._steady = s; }
|
|
59
|
+
|
|
60
|
+
get components(): ComponentMap { return this._components; }
|
|
61
|
+
|
|
62
|
+
get parent(): Node | null { return this._parent; }
|
|
63
|
+
get children(): Node[] { return this._children; }
|
|
64
|
+
|
|
65
|
+
clone(cloneChildren: boolean = false): Node {
|
|
66
|
+
const newNode = new Node();
|
|
67
|
+
newNode.assign(this, cloneChildren);
|
|
68
|
+
return newNode;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
assign(other: Node, cloneChildren: boolean = false): void {
|
|
72
|
+
this._name = other.name + "-copy";
|
|
73
|
+
this._enabled = other.enabled;
|
|
74
|
+
this._steady = other.steady;
|
|
75
|
+
this._components.assign(other._components);
|
|
76
|
+
if (cloneChildren) {
|
|
77
|
+
this._children = [];
|
|
78
|
+
other._children.forEach(c => {
|
|
79
|
+
this._children.push(c.clone(cloneChildren));
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
destroy(): void {
|
|
85
|
+
this._components.empty();
|
|
86
|
+
this.emptyChildren();
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
async deserialize(sceneData: any, loader: any): Promise<void> {
|
|
90
|
+
throw new Error("Node.deserialize() not implemented");
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
async serialize(sceneData: any, writer: any): Promise<void> {
|
|
94
|
+
throw new Error("Node.serialice() not implemented");
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
addComponent(component: Component): Component {
|
|
98
|
+
this.components.add(component);
|
|
99
|
+
this.setSceneChanged();
|
|
100
|
+
return component;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
component(typeId: string): Component | undefined {
|
|
104
|
+
return this.components.find(typeId);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
removeComponent(component: Component | string): void {
|
|
108
|
+
this.components.remove(component);
|
|
109
|
+
this.setSceneChanged();
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
addedToNode(node: Node): void {
|
|
113
|
+
// Override in subclasses if needed
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
removedFromNode(node: Node): void {
|
|
117
|
+
// Override in subclasses if needed
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// This attribute returns true if a node or component
|
|
121
|
+
// has been added or removed to this node or any child node
|
|
122
|
+
get sceneChanged(): boolean {
|
|
123
|
+
return this._sceneChanged;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
setSceneChanged(): void {
|
|
127
|
+
this._sceneChanged = true;
|
|
128
|
+
if (this._parent) {
|
|
129
|
+
this._parent.setSceneChanged();
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
addChild(node: Node): void {
|
|
134
|
+
if (node._parent) {
|
|
135
|
+
node._parent.removeChild(node);
|
|
136
|
+
}
|
|
137
|
+
node._parent = this;
|
|
138
|
+
this._children.push(node);
|
|
139
|
+
node.addedToNode(this);
|
|
140
|
+
|
|
141
|
+
// If this node has been binded to a renderer, we need to bind
|
|
142
|
+
// the same renderer to any node that is added as child
|
|
143
|
+
if (this._bindedRenderer) {
|
|
144
|
+
bindRenderer(node, this._bindedRenderer);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
this.setSceneChanged();
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
removeChild(node: Node): void {
|
|
151
|
+
if (node._parent === this) {
|
|
152
|
+
node._parent = null;
|
|
153
|
+
node.removedFromNode(this);
|
|
154
|
+
const index = this._children.indexOf(node);
|
|
155
|
+
if (index !== -1) {
|
|
156
|
+
this._children.splice(index, 1);
|
|
157
|
+
this.setSceneChanged();
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
console.warn(`Scene inconsistency found removing node '${ node.name }' from node '${ this.name }'. The parent node is valid, but the child is not present in the children array.`);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
throw new Error(`Node.removeChild() - the specified node is not a child of this node.`);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
emptyChildren(): void {
|
|
169
|
+
this._children.forEach(ch => {
|
|
170
|
+
ch._parent = null;
|
|
171
|
+
ch.removedFromNode(this);
|
|
172
|
+
});
|
|
173
|
+
this._children = [];
|
|
174
|
+
this.setSceneChanged();
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
haveChild(node: Node): boolean {
|
|
178
|
+
return this._children.indexOf(node) !== -1;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
isAncientOf(node: Node): boolean {
|
|
182
|
+
const isNodeAncient = (node: Node | null, ancient: Node): boolean => {
|
|
183
|
+
if (!node || !ancient) {
|
|
184
|
+
return false;
|
|
185
|
+
}
|
|
186
|
+
else if (node._parent === ancient) {
|
|
187
|
+
return true;
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
return isNodeAncient(node._parent, ancient);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
return isNodeAncient(this, node);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// Visitor functions
|
|
197
|
+
accept(nodeVisitor: any): void {
|
|
198
|
+
if (!nodeVisitor.ignoreDisabled || this.enabled) {
|
|
199
|
+
nodeVisitor.visit(this);
|
|
200
|
+
this._children.forEach(ch => ch.accept(nodeVisitor));
|
|
201
|
+
nodeVisitor.didVisit(this);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
acceptReverse(nodeVisitor: any): void {
|
|
206
|
+
if (!nodeVisitor.ignoreDisabled || this.enabled) {
|
|
207
|
+
if (this._parent) {
|
|
208
|
+
this._parent.acceptReverse(nodeVisitor);
|
|
209
|
+
}
|
|
210
|
+
nodeVisitor.visit(this);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
async asyncAccept(nodeVisitor: any): Promise<void> {
|
|
215
|
+
if (!nodeVisitor.ignoreDisabled || this.enabled) {
|
|
216
|
+
await nodeVisitor.asyncVisit(this);
|
|
217
|
+
for (const ch in this._children) {
|
|
218
|
+
await this._children[ch].asyncAccept(nodeVisitor);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// Used by components to require a redraw of the scene for a certain number of frames.
|
|
224
|
+
// This is needed, for example, when a component changes the material of a drawable,
|
|
225
|
+
// so the change is reflected inmediately in the screen, or when a component generates
|
|
226
|
+
// an animation that needs to be updated for a certain number of frames.
|
|
227
|
+
get postRedisplayFrames(): number {
|
|
228
|
+
return this._postRedisplayFrames;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
set postRedisplayFrames(frames: number) {
|
|
232
|
+
this._postRedisplayFrames = frames;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// Most usual components
|
|
236
|
+
get transform(): Transform | undefined {
|
|
237
|
+
return this.component("Transform") as Transform;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
get lightComponent(): LightComponent | undefined {
|
|
241
|
+
return this.component("Light") as LightComponent;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
get drawable(): Drawable | undefined {
|
|
245
|
+
return this.component("Drawable") as Drawable;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
get camera(): Camera | undefined {
|
|
249
|
+
return this.component("Camera") as Camera;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
frame(delta: number, modelMatrix: Mat4, renderQueue: any): void {
|
|
253
|
+
const willUpdateComponents: Component[] = [];
|
|
254
|
+
const updateComponents: Component[] = [];
|
|
255
|
+
const drawComponents: Component[] = [];
|
|
256
|
+
this._components.forEach(comp => {
|
|
257
|
+
if (comp.requireWillUpdate) {
|
|
258
|
+
willUpdateComponents.push(comp);
|
|
259
|
+
}
|
|
260
|
+
if (comp.requireUpdate) {
|
|
261
|
+
updateComponents.push(comp);
|
|
262
|
+
}
|
|
263
|
+
if (comp.requireDraw) {
|
|
264
|
+
drawComponents.push(comp);
|
|
265
|
+
}
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
willUpdateComponents.forEach(comp => (comp as any).willUpdate(delta));
|
|
269
|
+
updateComponents.forEach(comp => (comp as any).update(delta, modelMatrix));
|
|
270
|
+
drawComponents.forEach(comp => (comp as any).draw(renderQueue, modelMatrix));
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
keyDown(evt: any): void {
|
|
274
|
+
this._components.forEach(comp => {
|
|
275
|
+
comp.keyDown(evt);
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
keyUp(evt: any): void {
|
|
279
|
+
this._components.forEach(comp => {
|
|
280
|
+
comp.keyUp(evt);
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
mouseUp(evt: any): void {
|
|
284
|
+
this._components.forEach(comp => {
|
|
285
|
+
comp.mouseUp(evt);
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
mouseDown(evt: any): void {
|
|
289
|
+
this._components.forEach(comp => {
|
|
290
|
+
comp.mouseDown(evt);
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
mouseMove(evt: any): void {
|
|
294
|
+
this._components.forEach(comp => {
|
|
295
|
+
comp.mouseMove(evt);
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
mouseOut(evt: any): void {
|
|
299
|
+
this._components.forEach(comp => {
|
|
300
|
+
comp.mouseOut(evt);
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
mouseDrag(evt: any): void {
|
|
304
|
+
this._components.forEach(comp => {
|
|
305
|
+
comp.mouseDrag(evt);
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
mouseWheel(evt: any): void {
|
|
309
|
+
this._components.forEach(comp => {
|
|
310
|
+
comp.mouseWheel(evt);
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
touchStart(evt: any): void {
|
|
314
|
+
this._components.forEach(comp => {
|
|
315
|
+
comp.touchStart(evt);
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
touchMove(evt: any): void {
|
|
319
|
+
this._components.forEach(comp => {
|
|
320
|
+
comp.touchMove(evt);
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
touchEnd(evt: any): void {
|
|
324
|
+
this._components.forEach(comp => {
|
|
325
|
+
comp.touchEnd(evt);
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
}
|