bg2e-js 2.1.2 → 2.2.0

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.
Files changed (147) hide show
  1. package/dist/bg2e-js.js +7031 -6989
  2. package/dist/bg2e-js.js.map +1 -1
  3. package/package.json +20 -2
  4. package/src/app/AppController.ts +39 -0
  5. package/src/app/Bg2KeyboardEvent.ts +54 -0
  6. package/src/app/Bg2MouseEvent.ts +82 -0
  7. package/src/app/Bg2TouchEvent.ts +18 -0
  8. package/src/app/Canvas.ts +108 -0
  9. package/src/app/EventBase.ts +10 -0
  10. package/src/app/MainLoop.ts +273 -0
  11. package/src/app/index.ts +25 -0
  12. package/src/base/Color.ts +134 -0
  13. package/src/base/Environment.ts +183 -0
  14. package/src/base/Light.ts +192 -0
  15. package/src/base/Material.ts +616 -0
  16. package/src/base/PolyList.ts +365 -0
  17. package/src/base/Texture.ts +620 -0
  18. package/src/base/index.ts +81 -0
  19. package/src/db/Bg2LoaderPlugin.ts +129 -0
  20. package/src/db/DBPluginApi.ts +48 -0
  21. package/src/db/Loader.ts +116 -0
  22. package/src/db/LoaderPlugin.ts +34 -0
  23. package/src/db/MtlParser.ts +7 -0
  24. package/src/db/ObjLoaderPlugin.ts +55 -0
  25. package/src/db/ObjParser.ts +252 -0
  26. package/src/db/ObjWriterPlugin.ts +19 -0
  27. package/src/db/VitscnjLoaderPlugin.ts +100 -0
  28. package/src/db/Writer.ts +52 -0
  29. package/src/db/WriterPlugin.ts +22 -0
  30. package/src/db/index.ts +44 -0
  31. package/src/debug/DebugRenderer.ts +173 -0
  32. package/src/debug/WebGLTextureViewer.ts +75 -0
  33. package/src/debug/index.ts +7 -0
  34. package/src/index.html +11 -0
  35. package/src/index.ts +33 -0
  36. package/src/manipulation/SelectionBuffer.ts +82 -0
  37. package/src/manipulation/SelectionHighlight.ts +85 -0
  38. package/src/manipulation/SelectionIdAssignVisitor.ts +97 -0
  39. package/src/manipulation/SelectionManager.ts +166 -0
  40. package/src/manipulation/SelectionMode.ts +6 -0
  41. package/src/math/Mat3.ts +259 -0
  42. package/src/math/Mat4.ts +706 -0
  43. package/src/math/MatrixStrategy.ts +25 -0
  44. package/src/math/Quat.ts +65 -0
  45. package/src/math/Vec.ts +753 -0
  46. package/src/math/constants.ts +47 -0
  47. package/src/math/functions.ts +103 -0
  48. package/src/math/index.ts +74 -0
  49. package/src/phsics/joint.ts +137 -0
  50. package/src/primitives/arrow.ts +58 -0
  51. package/src/primitives/cone.ts +138 -0
  52. package/src/primitives/cube.ts +60 -0
  53. package/src/primitives/cylinder.ts +216 -0
  54. package/src/primitives/index.ts +13 -0
  55. package/src/primitives/plane.ts +31 -0
  56. package/src/primitives/sphere.ts +809 -0
  57. package/src/render/BRDFIntegrationMap.ts +4 -0
  58. package/src/render/Environment.ts +136 -0
  59. package/src/render/FrameBuffer.ts +35 -0
  60. package/src/render/MaterialRenderer.ts +34 -0
  61. package/src/render/Pipeline.ts +109 -0
  62. package/src/render/PolyListRenderer.ts +47 -0
  63. package/src/render/RenderBuffer.ts +197 -0
  64. package/src/render/RenderQueue.ts +199 -0
  65. package/src/render/RenderState.ts +116 -0
  66. package/src/render/Renderer.ts +248 -0
  67. package/src/render/SceneAppController.ts +238 -0
  68. package/src/render/SceneRenderer.ts +373 -0
  69. package/src/render/Shader.ts +32 -0
  70. package/src/render/ShadowRenderer.ts +176 -0
  71. package/src/render/SkyCube.ts +106 -0
  72. package/src/render/SkySphere.ts +118 -0
  73. package/src/render/TextureMergerRenderer.ts +70 -0
  74. package/src/render/TextureRenderer.ts +34 -0
  75. package/src/render/index.ts +67 -0
  76. package/src/render/webgl/FrameBuffer.ts +10 -0
  77. package/src/render/webgl/MaterialRenderer.ts +113 -0
  78. package/src/render/webgl/Pipeline.ts +89 -0
  79. package/src/render/webgl/PolyListRenderer.ts +260 -0
  80. package/src/render/webgl/RenderBuffer.ts +227 -0
  81. package/src/render/webgl/Renderer.ts +262 -0
  82. package/src/render/webgl/SceneRenderer.ts +68 -0
  83. package/src/render/webgl/ShaderProgram.ts +424 -0
  84. package/src/render/webgl/ShadowRenderer.ts +6 -0
  85. package/src/render/webgl/SkyCube.ts +16 -0
  86. package/src/render/webgl/SkySphere.ts +16 -0
  87. package/src/render/webgl/State.ts +152 -0
  88. package/src/render/webgl/TextureRenderer.ts +167 -0
  89. package/src/render/webgl/VertexBuffer.ts +137 -0
  90. package/src/render/webgl/index.ts +35 -0
  91. package/src/scene/Camera.ts +458 -0
  92. package/src/scene/Chain.ts +44 -0
  93. package/src/scene/ChainJoint.ts +58 -0
  94. package/src/scene/Component.ts +173 -0
  95. package/src/scene/ComponentMap.ts +107 -0
  96. package/src/scene/Drawable.ts +154 -0
  97. package/src/scene/EnvironmentComponent.ts +142 -0
  98. package/src/scene/FindNodeVisitor.ts +60 -0
  99. package/src/scene/LightComponent.ts +155 -0
  100. package/src/scene/MatrixState.ts +46 -0
  101. package/src/scene/Node.ts +314 -0
  102. package/src/scene/NodeVisitor.ts +15 -0
  103. package/src/scene/OrbitCameraController.ts +450 -0
  104. package/src/scene/SmoothOrbitCameraController.ts +99 -0
  105. package/src/scene/Transform.ts +73 -0
  106. package/src/scene/index.ts +57 -0
  107. package/src/shaders/BasicDiffuseColorShader.ts +111 -0
  108. package/src/shaders/BasicPBRLightShader.ts +277 -0
  109. package/src/shaders/DebugRenderShader.ts +98 -0
  110. package/src/shaders/DepthRenderShader.ts +91 -0
  111. package/src/shaders/IrradianceMapCubeShader.ts +116 -0
  112. package/src/shaders/PBRLightIBLShader.ts +487 -0
  113. package/src/shaders/PickSelectionShader.ts +101 -0
  114. package/src/shaders/PresentDebugFramebufferShader.ts +118 -0
  115. package/src/shaders/PresentTextureShader.ts +99 -0
  116. package/src/shaders/SelectionHighlightShader.ts +127 -0
  117. package/src/shaders/ShaderFunction.ts +318 -0
  118. package/src/shaders/SkyCubeShader.ts +94 -0
  119. package/src/shaders/SkySphereShader.ts +102 -0
  120. package/src/shaders/SpecularMapCubeShader.ts +165 -0
  121. package/src/shaders/TextureMergerShader.ts +171 -0
  122. package/src/shaders/index.ts +37 -0
  123. package/src/shaders/webgl/color_correction.glsl +47 -0
  124. package/src/shaders/webgl/constants.glsl +6 -0
  125. package/src/shaders/webgl/index.ts +70 -0
  126. package/src/shaders/webgl/normal_map.glsl +9 -0
  127. package/src/shaders/webgl/pbr.glsl +173 -0
  128. package/src/shaders/webgl/uniforms.glsl +91 -0
  129. package/src/shaders/webgl_shader_lib.ts +213 -0
  130. package/src/tools/BinaryResourceProvider.ts +14 -0
  131. package/src/tools/ImageResourceProvider.ts +66 -0
  132. package/src/tools/MaterialModifier.ts +276 -0
  133. package/src/tools/Resource.ts +203 -0
  134. package/src/tools/ResourceProvider.ts +69 -0
  135. package/src/tools/TextResourceProvider.ts +24 -0
  136. package/src/tools/TextureCache.ts +52 -0
  137. package/src/tools/TextureResourceDatabase.ts +100 -0
  138. package/src/tools/UserAgent.ts +362 -0
  139. package/src/tools/VideoResourceProvider.ts +50 -0
  140. package/src/tools/WriteStrategy.ts +22 -0
  141. package/src/tools/base64.ts +11 -0
  142. package/src/tools/crypto.ts +19 -0
  143. package/src/tools/endiantess.ts +13 -0
  144. package/src/tools/image.ts +18 -0
  145. package/src/tools/index.ts +41 -0
  146. package/src/tools/processType.ts +38 -0
  147. package/src/vite-env.d.ts +12 -0
@@ -0,0 +1,450 @@
1
+ import Color from "../base/Color";
2
+ import Vec from "../math/Vec";
3
+ import { ProjectionStrategy, OrthographicProjectionStrategy } from "./Camera";
4
+ import Component from "./Component";
5
+ import { SpecialKey } from "../app/Bg2KeyboardEvent";
6
+ import MouseEvent, {
7
+ leftMouseButton,
8
+ middleMouseButton,
9
+ rightMouseButton
10
+ } from "../app/Bg2MouseEvent";
11
+ import { degreesToRadians } from "../math/functions";
12
+
13
+ export const Action = {
14
+ NONE: 0,
15
+ ROTATE: 1,
16
+ PAN: 2,
17
+ ZOOM: 3
18
+ } as const;
19
+
20
+ interface ButtonState {
21
+ left: boolean;
22
+ middle: boolean;
23
+ right: boolean;
24
+ }
25
+
26
+ export function getOrbitAction(cameraCtrl: OrbitCameraController): number | undefined {
27
+ const left = leftMouseButton();
28
+ const middle = middleMouseButton();
29
+ const right = rightMouseButton();
30
+
31
+ switch (true) {
32
+ case left === cameraCtrl._rotateButtons.left &&
33
+ middle === cameraCtrl._rotateButtons.middle &&
34
+ right === cameraCtrl._rotateButtons.right:
35
+ return Action.ROTATE;
36
+ case left === cameraCtrl._panButtons.left &&
37
+ middle === cameraCtrl._panButtons.middle &&
38
+ right === cameraCtrl._panButtons.right:
39
+ return Action.PAN;
40
+ case left === cameraCtrl._zoomButtons.left &&
41
+ middle === cameraCtrl._zoomButtons.middle &&
42
+ right === cameraCtrl._zoomButtons.right:
43
+ return Action.ZOOM;
44
+ }
45
+ }
46
+
47
+ export default class OrbitCameraController extends Component {
48
+ _rotateButtons: ButtonState;
49
+ _panButtons: ButtonState;
50
+ _zoomButtons: ButtonState;
51
+
52
+ _rotation: Vec;
53
+ _distance: number;
54
+ _center: Vec;
55
+ _rotationSpeed: number;
56
+ _forward: number;
57
+ _left: number;
58
+ _wheelSpeed: number;
59
+ _minFocus: number;
60
+
61
+ _minPitch: number;
62
+ _maxPitch: number;
63
+ _minDistance: number;
64
+ _maxDistance: number;
65
+
66
+ _maxX: number;
67
+ _minX: number;
68
+ _minY: number;
69
+ _maxY: number;
70
+ _maxZ: number;
71
+ _minZ: number;
72
+
73
+ _displacementSpeed: number;
74
+
75
+ _enabled: boolean;
76
+
77
+ // Non-serializable attributes
78
+ _keys: Record<string, boolean>;
79
+ _lastTouch: any[];
80
+ _mouseButtonPressed?: boolean;
81
+ _lastPos?: Vec;
82
+ _viewWidth?: number;
83
+
84
+ constructor(id: string | null = null) {
85
+ super(id ?? "OrbitCameraController");
86
+
87
+ this._rotateButtons = { left: true, middle: false, right: false };
88
+ this._panButtons = { left: false, middle: false, right: true };
89
+ this._zoomButtons = { left: false, middle: true, right: false };
90
+
91
+ this._rotation = new Vec([0, 0]);
92
+ this._distance = 5;
93
+ this._center = new Vec([0, 0, 0]);
94
+ this._rotationSpeed = 0.2;
95
+ this._forward = 0;
96
+ this._left = 0;
97
+ this._wheelSpeed = 1;
98
+ this._minFocus = 2;
99
+
100
+ this._minPitch = -85.0;
101
+ this._maxPitch = 85.0;
102
+ this._minDistance = 0.4;
103
+ this._maxDistance = 24.0;
104
+
105
+ this._maxX = 45;
106
+ this._minX = -45;
107
+ this._minY = -45;
108
+ this._maxY = 45;
109
+ this._maxZ = 45;
110
+ this._minZ = -45;
111
+
112
+ this._displacementSpeed = 0.1;
113
+
114
+ this._enabled = true;
115
+
116
+ // Non-serializable attributes
117
+ this._keys = {};
118
+ this._lastTouch = [];
119
+ }
120
+
121
+ clone(): OrbitCameraController {
122
+ const result = new OrbitCameraController();
123
+ result.assign(this);
124
+ return result;
125
+ }
126
+
127
+ assign(other: OrbitCameraController): void {
128
+ this._rotateButtons.left = other._rotateButtons.left;
129
+ this._rotateButtons.middle = other._rotateButtons.middle;
130
+ this._rotateButtons.right = other._rotateButtons.right;
131
+
132
+ this._panButtons.left = other._panButtons.left;
133
+ this._panButtons.middle = other._panButtons.middle;
134
+ this._panButtons.right = other._panButtons.right;
135
+
136
+ this._zoomButtons.left = other._zoomButtons.left;
137
+ this._zoomButtons.middle = other._zoomButtons.middle;
138
+ this._zoomButtons.right = other._zoomButtons.right;
139
+
140
+ this._rotation = new Vec(other.rotation);
141
+ this._distance = other.distance;
142
+ this._center = new Vec(other.center);
143
+ this._rotationSpeed = other.rotationSpeed;
144
+ this._forward = other.forward;
145
+ this._left = other.left;
146
+ this._wheelSpeed = other.wheelSpeed;
147
+ this._minFocus = other.minCameraFocus;
148
+ this._minPitch = other.minPitch;
149
+ this._maxPitch = other.maxPitch;
150
+ this._minDistance = other.minDistance;
151
+ this._maxDistance = other.maxDistance;
152
+ this._maxX = other.maxX;
153
+ this._minX = other.minX;
154
+ this._minY = other.minY;
155
+ this._maxY = other.maxY;
156
+ this._maxZ = other.maxZ;
157
+ this._minZ = other.minZ;
158
+ this._displacementSpeed = other.displacementSpeed;
159
+ this._enabled = other.enabled;
160
+ }
161
+
162
+ get rotation(): Vec { return this._rotation; }
163
+ set rotation(r: Vec) { this._rotation = r; }
164
+ get distance(): number { return this._distance; }
165
+ set distance(d: number) { this._distance = d; }
166
+ get center(): Vec { return this._center; }
167
+ set center(c: Vec) { this._center = c; }
168
+ get rotationSpeed(): number { return this._rotationSpeed; }
169
+ set rotationSpeed(rs: number) { this._rotationSpeed = rs; }
170
+ get forward(): number { return this._forward; }
171
+ set forward(f: number) { this._forward = f; }
172
+ get left(): number { return this._left; }
173
+ set left(l: number) { this._left = l; }
174
+ get wheelSpeed(): number { return this._wheelSpeed; }
175
+ set wheelSpeed(w: number) { this._wheelSpeed = w; }
176
+
177
+ get viewWidth(): number | undefined { return this._viewWidth; }
178
+
179
+ get minCameraFocus(): number { return this._minFocus; }
180
+ set minCameraFocus(f: number) { this._minFocus = f; }
181
+ get minPitch(): number { return this._minPitch; }
182
+ set minPitch(p: number) { this._minPitch = p; }
183
+ get maxPitch(): number { return this._maxPitch; }
184
+ set maxPitch(p: number) { this._maxPitch = p; }
185
+ get minDistance(): number { return this._minDistance; }
186
+ set minDistance(d: number) { this._minDistance = d; }
187
+ get maxDistance(): number { return this._maxDistance; }
188
+ set maxDistance(d: number) { this._maxDistance = d; }
189
+
190
+ get minX(): number { return this._minX; }
191
+ get maxX(): number { return this._maxX; }
192
+ get minY(): number { return this._minY; }
193
+ get maxY(): number { return this._maxY; }
194
+ get minZ(): number { return this._minZ; }
195
+ get maxZ(): number { return this._maxZ; }
196
+
197
+ set minX(val: number) { this._minX = val; }
198
+ set maxX(val: number) { this._maxX = val; }
199
+ set minY(val: number) { this._minY = val; }
200
+ set maxY(val: number) { this._maxY = val; }
201
+ set minZ(val: number) { this._minZ = val; }
202
+ set maxZ(val: number) { this._maxZ = val; }
203
+
204
+ get displacementSpeed(): number { return this._displacementSpeed; }
205
+ set displacementSpeed(s: number) { this._displacementSpeed = s; }
206
+
207
+ get enabled(): boolean { return this._enabled; }
208
+ set enabled(e: boolean) { this._enabled = e; }
209
+
210
+ setRotateButtons(left: boolean, middle: boolean, right: boolean): void {
211
+ this._rotateButtons = { left: left, middle: middle, right: right };
212
+ }
213
+
214
+ setPanButtons(left: boolean, middle: boolean, right: boolean): void {
215
+ this._panButtons = { left: left, middle: middle, right: right };
216
+ }
217
+
218
+ setZoomButtons(left: boolean, middle: boolean, right: boolean): void {
219
+ this._zoomButtons = { left: left, middle: middle, right: right };
220
+ }
221
+
222
+ async deserialize(sceneData: any, loader: any): Promise<void> {
223
+ this._rotateButtons = sceneData.rotateButtons || this._rotateButtons;
224
+ this._panButtons = sceneData.panButtons || this._panButtons;
225
+ this._zoomButtons = sceneData.zoomButtons || this._zoomButtons;
226
+ this._rotation = new Vec(sceneData.rotation) || this._rotation;
227
+ this._distance = sceneData.distance !== undefined ? sceneData.distance : this._distance;
228
+ this._center = new Vec(sceneData.center) || this._center;
229
+ this._rotationSpeed = sceneData.rotationSpeed !== undefined ? sceneData.rotationSpeed : this._rotationSpeed;
230
+ this._forward = sceneData.forward !== undefined ? sceneData.forward : this._forward;
231
+ this._left = sceneData.left !== undefined ? sceneData.left : this._left;
232
+ this._wheelSpeed = sceneData.wheelSpeed !== undefined ? sceneData.wheelSpeed : this._wheelSpeed;
233
+ this._minFocus = sceneData.minFocus !== undefined ? sceneData.minFocus : this._minFocus;
234
+ this._minPitch = sceneData.minPitch !== undefined ? sceneData.minPitch : this._minPitch;
235
+ this._maxPitch = sceneData.maxPitch !== undefined ? sceneData.maxPitch : this._maxPitch;
236
+ this._minDistance = sceneData.minDistance !== undefined ? sceneData.minDistance : this._minDistance;
237
+ this._maxDistance = sceneData.maxDistance !== undefined ? sceneData.maxDistance : this._maxDistance;
238
+ this._maxX = sceneData.maxX !== undefined ? sceneData.maxX : this._maxX;
239
+ this._minX = sceneData.minX !== undefined ? sceneData.minX : this._minX;
240
+ this._minY = sceneData.minY !== undefined ? sceneData.minY : this._minY;
241
+ this._maxY = sceneData.maxY !== undefined ? sceneData.maxY : this._maxY;
242
+ this._maxZ = sceneData.maxZ !== undefined ? sceneData.maxZ : this._maxZ;
243
+ this._minZ = sceneData.minZ !== undefined ? sceneData.minZ : this._minZ;
244
+ this._displacementSpeed = sceneData.displacementSpeed !== undefined ? sceneData.displacementSpeed : this._displacementSpeed;
245
+ this._enabled = sceneData.enabled !== undefined ? sceneData.enabled : this._enabled;
246
+ }
247
+
248
+ async serialize(sceneData: any, writer: any): Promise<void> {
249
+ super.serialize(sceneData, writer);
250
+ sceneData.rotateButtons = this._rotateButtons;
251
+ sceneData.panButtons = this._panButtons;
252
+ sceneData.zoomButtons = this._zoomButtons;
253
+ sceneData.rotation = this._rotation.toArray();
254
+ sceneData.distance = this._distance;
255
+ sceneData.center = this._center.toArray();
256
+ sceneData.rotationSpeed = this._rotationSpeed;
257
+ sceneData.forward = this._forward;
258
+ sceneData.left = this._left;
259
+ sceneData.wheelSpeed = this._wheelSpeed;
260
+ sceneData.minFocus = this._minFocus;
261
+ sceneData.minPitch = this._minPitch;
262
+ sceneData.maxPitch = this._maxPitch;
263
+ sceneData.minDistance = this._minDistance;
264
+ sceneData.maxDistance = this._maxDistance;
265
+ sceneData.maxX = this._maxX;
266
+ sceneData.minX = this._minX;
267
+ sceneData.minY = this._minY;
268
+ sceneData.maxY = this._maxY;
269
+ sceneData.maxZ = this._maxZ;
270
+ sceneData.minZ = this._minZ;
271
+ sceneData.displacementSpeed = this._displacementSpeed;
272
+ sceneData.enabled = this._enabled;
273
+ }
274
+
275
+ willUpdate(delta: number): void {
276
+ const orthoStrategy = this.camera && this.camera.projectionStrategy instanceof OrthographicProjectionStrategy ?
277
+ this.camera.projectionStrategy : null;
278
+
279
+ if (this.transform && this.enabled) {
280
+ const forward = this.transform.matrix.forwardVector;
281
+ const left = this.transform.matrix.leftVector;
282
+ forward.scale(this._forward);
283
+ left.scale(this._left);
284
+ this._center = Vec.Add(Vec.Add(this._center, forward), left);
285
+
286
+ let pitch = this._rotation.x > this._minPitch ? this._rotation.x : this._minPitch;
287
+ pitch = pitch < this._maxPitch ? pitch : this._maxPitch;
288
+ this._rotation.x = pitch;
289
+
290
+ this._distance = this._distance > this._minDistance ? this._distance : this._minDistance;
291
+ this._distance = this._distance < this._maxDistance ? this._distance : this._maxDistance;
292
+
293
+ if (this._mouseButtonPressed) {
294
+ let displacement = new Vec([0, 0, 0]);
295
+ if (this._keys[SpecialKey.UP_ARROW]) {
296
+ displacement = Vec.Add(displacement, this.transform.matrix.backwardVector);
297
+ }
298
+ if (this._keys[SpecialKey.DOWN_ARROW]) {
299
+ displacement = Vec.Add(displacement, this.transform.matrix.forwardVector);
300
+ }
301
+ if (this._keys[SpecialKey.LEFT_ARROW]) {
302
+ displacement = Vec.Add(displacement, this.transform.matrix.leftVector);
303
+ }
304
+ if (this._keys[SpecialKey.RIGHT_ARROW]) {
305
+ displacement = Vec.Add(displacement, this.transform.matrix.rightVector);
306
+ }
307
+ displacement.scale(this._displacementSpeed);
308
+ this._center = Vec.Add(this._center, displacement);
309
+ }
310
+
311
+ if (this._center.x < this._minX) this._center.x = this._minX;
312
+ else if (this._center.x > this._maxX) this._center.x = this._maxX;
313
+
314
+ if (this._center.y < this._minY) this._center.y = this._minY;
315
+ else if (this._center.y > this._maxY) this._center.y = this._maxY;
316
+
317
+ if (this._center.z < this._minZ) this._center.z = this._minZ;
318
+ else if (this._center.z > this._maxZ) this._center.z = this._maxZ;
319
+
320
+
321
+ this.transform.matrix.identity();
322
+
323
+ if (orthoStrategy) {
324
+ orthoStrategy.viewWidth = this._viewWidth!;
325
+ }
326
+ else {
327
+ this.transform.matrix.translate(0, 0, this._distance);
328
+ if (this.camera) {
329
+ // Update the camera focus distance to optimize the shadow map rendering
330
+ this.camera.focusDistance = this._distance;
331
+ }
332
+ }
333
+ this.transform.matrix.rotate(degreesToRadians(pitch), -1, 0, 0)
334
+ .rotate(degreesToRadians(this._rotation.y), 0, 1, 0)
335
+ .translate(this._center);
336
+ }
337
+
338
+ }
339
+
340
+ mouseDown(evt: MouseEvent): void {
341
+ if (!this.enabled) return;
342
+ this._mouseButtonPressed = true;
343
+ this._lastPos = new Vec(evt.x, evt.y);
344
+ }
345
+
346
+ mouseUp(evt: MouseEvent): void {
347
+ this._mouseButtonPressed = false;
348
+ }
349
+
350
+ mouseDrag(evt: MouseEvent): void {
351
+ if (this.transform && this._lastPos && this.enabled) {
352
+ const delta = new Vec(this._lastPos.y - evt.y,
353
+ this._lastPos.x - evt.x);
354
+ this._lastPos.setValue(evt.x, evt.y);
355
+ const orthoStrategy = this.camera && this.camera.projectionStrategy instanceof OrthographicProjectionStrategy || false;
356
+
357
+ switch (getOrbitAction(this)) {
358
+ case Action.ROTATE:
359
+ delta.x = delta.x * -1;
360
+ this._rotation = Vec.Add(this._rotation, delta.scale(0.5));
361
+ break;
362
+ case Action.PAN:
363
+ const up = this.transform.matrix.upVector;
364
+ const left = this.transform.matrix.leftVector;
365
+
366
+ if (orthoStrategy) {
367
+ up.scale(delta.x * -0.0005 * this._viewWidth!);
368
+ left.scale(delta.y * -0.0005 * this._viewWidth!);
369
+ }
370
+ else {
371
+ up.scale(delta.x * -0.001 * this._distance);
372
+ left.scale(delta.y * -0.001 * this._distance);
373
+ }
374
+ this._center = Vec.Add(Vec.Add(this._center, up), left);
375
+ break;
376
+ case Action.ZOOM:
377
+ this._distance += delta.x * 0.01 * this._distance;
378
+ this._viewWidth = (this._viewWidth || 0) + delta.x * 0.01 * (this._viewWidth || 0);
379
+ if (this._viewWidth < 0.5) this._viewWidth = 0.5;
380
+ break;
381
+ }
382
+ }
383
+ }
384
+
385
+ mouseWheel(evt: any): void {
386
+ if (!this.enabled) return;
387
+ const mult = this._distance > 0.01 ? this._distance : 0.01;
388
+ const wMult = (this._viewWidth || 0) > 1 ? (this._viewWidth || 0) : 1;
389
+ this._distance += evt.delta * 0.001 * mult * this._wheelSpeed;
390
+ this._viewWidth = (this._viewWidth || 0) + evt.delta * 0.0001 * wMult * this._wheelSpeed;
391
+ if (this._viewWidth < 0.5) this._viewWidth = 0.5;
392
+ }
393
+
394
+ touchStart(evt: any): void {
395
+ if (!this.enabled) return;
396
+ this._lastTouch = evt.touches;
397
+ evt.stopPropagation();
398
+ }
399
+
400
+ touchMove(evt: any): void {
401
+ if (this._lastTouch.length === evt.touches.length && this.transform && this.enabled) {
402
+ if (this._lastTouch.length === 1) {
403
+ // Rotate
404
+ const last = this._lastTouch[0];
405
+ const t = evt.touches[0];
406
+ const delta = new Vec((last.y - t.y) * -1.0, last.x - t.x);
407
+
408
+ this._rotation = Vec.Add(this._rotation, delta.scale(0.5));
409
+ }
410
+ else if (this._lastTouch.length === 2) {
411
+ // Pan/zoom
412
+ const l0 = this._lastTouch[0];
413
+ const l1 = this._lastTouch[1];
414
+ let t0: any = null;
415
+ let t1: any = null;
416
+ evt.touches.forEach((touch: any) => {
417
+ if (touch.identifier === l0.identifier) {
418
+ t0 = touch;
419
+ }
420
+ else if (touch.identifier === l1.identifier) {
421
+ t1 = touch;
422
+ }
423
+ });
424
+ const dist0 = Vec.Magnitude(Vec.Sub(new Vec(l0.x, l0.y), new Vec(l1.x, l1.y)));
425
+ const dist1 = Vec.Magnitude(Vec.Sub(new Vec(t0.x, t0.y), new Vec(t1.x, t1.y)));
426
+ const delta = new Vec(l0.y - t0.y, l1.x - t1.x);
427
+ const up = this.transform.matrix.upVector;
428
+ const left = this.transform.matrix.leftVector;
429
+
430
+ up.scale(delta.x * -0.001 * this._distance);
431
+ left.scale(delta.y * -0.001 * this._distance);
432
+ this._center = Vec.Add(this._center, Vec.Add(up, left));
433
+
434
+ this._distance += (dist0 - dist1) * 0.005 * this._distance;
435
+ }
436
+ evt.stopPropagation();
437
+ }
438
+ this._lastTouch = evt.touches;
439
+ }
440
+
441
+ keyDown(evt: any): void {
442
+ if (!this.enabled) return;
443
+ this._keys[evt.key] = true;
444
+ }
445
+
446
+ keyUp(evt: any): void {
447
+ if (!this.enabled) return;
448
+ this._keys[evt.key] = false;
449
+ }
450
+ }
@@ -0,0 +1,99 @@
1
+ import Component from './Component';
2
+ import OrbitCameraController, { Action, getOrbitAction } from './OrbitCameraController';
3
+ import MouseEvent, {
4
+ leftMouseButton,
5
+ middleMouseButton,
6
+ rightMouseButton
7
+ } from '../app/Bg2MouseEvent';
8
+ import { SpecialKey } from '../app/Bg2KeyboardEvent';
9
+ import { degreesToRadians, lerp, clamp } from '../math/functions';
10
+ import Vec from '../math/Vec';
11
+ import { OrthographicProjectionStrategy } from './Camera';
12
+ import Mat4 from '../math/Mat4';
13
+
14
+
15
+ export default class SmoothOrbitCameraController extends OrbitCameraController {
16
+ _smoothFactor: number;
17
+ _action: number;
18
+ _center0?: Vec;
19
+ _distance0?: number;
20
+ _pitch0?: number;
21
+ _yaw0?: number;
22
+
23
+ constructor() {
24
+ super("SmoothOrbitCameraController");
25
+ this._smoothFactor = 0.009;
26
+ this._action = Action.NONE;
27
+ }
28
+
29
+ clone(): SmoothOrbitCameraController {
30
+ const result = new SmoothOrbitCameraController();
31
+ result.assign(this);
32
+ return result;
33
+ }
34
+
35
+ assign(other: SmoothOrbitCameraController): void {
36
+ super.assign(other);
37
+ }
38
+
39
+ willUpdate(delta: number): void {
40
+ if (this.transform && this.enabled) {
41
+ const orthoStrategy = this.camera && this.camera.projectionStrategy instanceof OrthographicProjectionStrategy ?
42
+ this.camera.projectionStrategy : null;
43
+
44
+ if (this._mouseButtonPressed) {
45
+ let displacement = new Vec([0, 0, 0]);
46
+ if (this._keys[SpecialKey.UP_ARROW]) {
47
+ displacement = Vec.Add(displacement, this.transform.matrix.backwardVector);
48
+ }
49
+ if (this._keys[SpecialKey.DOWN_ARROW]) {
50
+ displacement = Vec.Add(displacement, this.transform.matrix.forwardVector);
51
+ }
52
+ if (this._keys[SpecialKey.LEFT_ARROW]) {
53
+ displacement = Vec.Add(displacement, this.transform.matrix.leftVector);
54
+ }
55
+ if (this._keys[SpecialKey.RIGHT_ARROW]) {
56
+ displacement = Vec.Add(displacement, this.transform.matrix.rightVector);
57
+ }
58
+ displacement.scale(this._displacementSpeed);
59
+ this._center = Vec.Add(this._center, displacement);
60
+ }
61
+
62
+ this._center0 = this._center0 ?? Mat4.GetPosition(this.transform.matrix);
63
+ this._distance0 = this._distance0 ?? Vec.Distance(this._center0, this._center);
64
+ this._center0 = Vec.Lerp(this._center0, this._center, delta * this._smoothFactor);
65
+ this._distance0 = lerp(this._distance0, this._distance, delta * this._smoothFactor * 2);
66
+ this._pitch0 = this._pitch0 ?? this._rotation.x;
67
+ this._yaw0 = this._yaw0 ?? this._rotation.y;
68
+
69
+ this._pitch0 = lerp(this._pitch0, this._rotation.x, delta * this._smoothFactor);
70
+ this._yaw0 = lerp(this._yaw0, this._rotation.y, delta * this._smoothFactor);
71
+
72
+ // Clamp values
73
+ this._distance = clamp(this._distance, this.minDistance, this.maxDistance);
74
+ this._distance0 = clamp(this._distance0, this.minDistance, this.maxDistance);
75
+ this._pitch0 = clamp(this._pitch0, this.minPitch, this.maxPitch);
76
+ this._rotation.x = clamp(this._rotation.x, this.minPitch, this.maxPitch);
77
+ const minDisp = new Vec(this.minX, this.minY, this.minZ);
78
+ const maxDisp = new Vec(this.maxX, this.maxY, this.maxZ);
79
+ this._center0 = Vec.Clamp(this._center0, minDisp, maxDisp);
80
+ this._center = Vec.Clamp(this._center, minDisp, maxDisp);
81
+
82
+ this.transform.matrix.identity();
83
+ if (orthoStrategy) {
84
+ orthoStrategy.viewWidth = this._viewWidth!;
85
+ }
86
+ else {
87
+ this.transform.matrix.translate(0, 0, this._distance0);
88
+ if (this.camera) {
89
+ // Update the camera focus distance to optimize the shadow map rendering
90
+ this.camera.focusDistance = this._distance0;
91
+ }
92
+ }
93
+ this.transform.matrix.rotate(degreesToRadians(-this._pitch0), 1, 0, 0)
94
+ .rotate(degreesToRadians(this._yaw0), 0, 1, 0)
95
+ .translate(this._center0);
96
+
97
+ }
98
+ }
99
+ }
@@ -0,0 +1,73 @@
1
+ import Component from './Component';
2
+ import Node from './Node';
3
+ import Mat4 from "../math/Mat4";
4
+ import NodeVisitor from './NodeVisitor';
5
+
6
+ export class TransformVisitor extends NodeVisitor {
7
+ _matrix: Mat4;
8
+
9
+ constructor() {
10
+ super();
11
+ this._matrix = Mat4.MakeIdentity();
12
+ }
13
+
14
+ get matrix(): Mat4 {
15
+ return this._matrix;
16
+ }
17
+
18
+ visit(node: any): void {
19
+ if (node.transform) {
20
+ this._matrix = Mat4.Mult(this._matrix, node.transform.matrix);
21
+ }
22
+ }
23
+ }
24
+
25
+ export default class Transform extends Component {
26
+ static GetWorldMatrix(node: Node | Component): Mat4 {
27
+ if (node instanceof Component) {
28
+ node = node.node;
29
+ }
30
+ const visitor = new TransformVisitor();
31
+ node.acceptReverse(visitor);
32
+ return visitor.matrix;
33
+ }
34
+
35
+ _matrix: Mat4;
36
+
37
+ constructor(mat: Mat4 = Mat4.MakeIdentity()) {
38
+ super("Transform");
39
+ this._matrix = mat;
40
+ }
41
+
42
+ get matrix(): Mat4 { return this._matrix; }
43
+ set matrix(m: Mat4) { this._matrix = m; }
44
+
45
+ clone(): Transform {
46
+ const result = new Transform();
47
+ result.assign(this);
48
+ return result;
49
+ }
50
+
51
+ assign(other: Transform): void {
52
+ this._matrix = new Mat4(other.matrix);
53
+ }
54
+
55
+ async deserialize(sceneData: any, loader: any): Promise<void> {
56
+ if (Array.isArray(sceneData.transformMatrix) && sceneData.transformMatrix.length === 16) {
57
+ this._matrix.assign(sceneData.transformMatrix);
58
+ }
59
+ else {
60
+ console.warn("Transform.deserialize(): invalid transformMatrix attribute found in scene data");
61
+ }
62
+ }
63
+
64
+ async serialize(sceneData: any, writer: any): Promise<void> {
65
+ await super.serialize(sceneData,writer);
66
+ throw new Error("Transform.serialice() not implemented");
67
+ }
68
+
69
+ update(delta: number, modelMatrix: Mat4): void {
70
+ //modelMatrix.mult(this._matrix);
71
+ modelMatrix.assign(Mat4.Mult(modelMatrix, this._matrix));
72
+ }
73
+ }
@@ -0,0 +1,57 @@
1
+
2
+
3
+ import DrawableComponent from "./Drawable";
4
+ import TransformComponent from "./Transform";
5
+ import ChainComponent from "./Chain";
6
+ import {
7
+ InputChainJoint as InputChainJointComponent,
8
+ OutputChainJoint as OutputChainJointComponent } from "./ChainJoint";
9
+ import LightComponent from "./LightComponent";
10
+ import CameraComponent, {
11
+ OpticalProjectionStrategy,
12
+ PerspectiveProjectionStrategy,
13
+ ProjectionStrategy
14
+ } from "./Camera";
15
+ import OrbitCameraControllerComponent from "./OrbitCameraController";
16
+ import SmoothOrbitCameraControllerComponent from "./SmoothOrbitCameraController";
17
+ import EnvironmentComponent from "./EnvironmentComponent";
18
+ import Component, { registerComponent } from "./Component";
19
+ import Node from "./Node";
20
+ import NodeVisitor from "./NodeVisitor";
21
+ import FindNodeVisitor from "./FindNodeVisitor";
22
+
23
+ export const registerComponents = () => {
24
+ registerComponent("Drawable", DrawableComponent);
25
+ registerComponent("Transform", TransformComponent);
26
+ registerComponent("Light", LightComponent);
27
+ registerComponent("Chain", ChainComponent);
28
+ registerComponent("InputChainJoint", InputChainJointComponent);
29
+ registerComponent("OutputChainJoint", OutputChainJointComponent);
30
+ registerComponent("Camera", CameraComponent);
31
+ registerComponent("OrbitCameraController", OrbitCameraControllerComponent);
32
+ registerComponent("SmoothOrbitCameraController", SmoothOrbitCameraControllerComponent);
33
+ registerComponent("Environment", EnvironmentComponent);
34
+ // TODO: Register more components
35
+ }
36
+
37
+ export default {
38
+ Component,
39
+ DrawableComponent,
40
+ TransformComponent,
41
+ ChainComponent,
42
+ InputChainJointComponent,
43
+ OutputChainJointComponent,
44
+ LightComponent,
45
+ CameraComponent,
46
+ OpticalProjectionStrategy,
47
+ PerspectiveProjectionStrategy,
48
+ ProjectionStrategy,
49
+ OrbitCameraControllerComponent,
50
+ SmoothOrbitCameraControllerComponent,
51
+ EnvironmentComponent,
52
+ registerComponents,
53
+ registerComponent,
54
+ Node,
55
+ NodeVisitor,
56
+ FindNodeVisitor
57
+ }