matrix-engine-wgpu 1.3.16 → 1.3.18
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/.codesandbox/tasks.json +46 -0
- package/.devcontainer/devcontainer.json +22 -0
- package/.github/dependabot.yml +12 -0
- package/REFERENCE.md +59 -0
- package/app-worker.js +45 -0
- package/dev.md +541 -0
- package/empty.js +17 -0
- package/examples/camera-texture.js +60 -0
- package/examples/games/jamb/html-content.js +128 -0
- package/examples/games/jamb/jamb.js +1341 -0
- package/examples/games/jamb/readme.md +3 -0
- package/examples/load-jamb.js +6 -0
- package/examples/load-obj-file.js +95 -0
- package/examples/load-objs-sequence.js +68 -0
- package/examples/unlit-textures.js +31 -0
- package/examples/video-texture.js +61 -0
- package/examples.js +73 -0
- package/main.js +635 -0
- package/non-project-files/cubebuffer-example.js +51 -0
- package/non-project-files/dev.txt +21 -0
- package/non-project-files/image1.png +0 -0
- package/non-project-files/image6.png +0 -0
- package/package.json +2 -5
- package/public/ammojs/ammo.js +957 -0
- package/public/ammojs/ammo.wasm.js +921 -0
- package/public/ammojs/ammo.wasm.wasm +0 -0
- package/public/app-worker.js +47 -0
- package/public/app.js +12744 -0
- package/public/css/style.css +711 -0
- package/public/empty.html +25 -0
- package/public/empty.js +10453 -0
- package/public/examples.html +30 -0
- package/public/examples.js +11217 -0
- package/public/index.html +20 -0
- package/public/manifest copy.web +35 -0
- package/public/manifest.web +25 -0
- package/public/res/audios/block.mp3 +0 -0
- package/public/res/audios/dice-roll.mp3 +0 -0
- package/public/res/audios/dice1.mp3 +0 -0
- package/public/res/audios/dice2.mp3 +0 -0
- package/public/res/audios/kenney/Kenney.url +2 -0
- package/public/res/audios/kenney/License.txt +22 -0
- package/public/res/audios/kenney/Patreon.url +2 -0
- package/public/res/audios/kenney/audios/back_001.ogg +0 -0
- package/public/res/audios/kenney/audios/back_002.ogg +0 -0
- package/public/res/audios/kenney/audios/back_003.ogg +0 -0
- package/public/res/audios/kenney/audios/back_004.ogg +0 -0
- package/public/res/audios/kenney/audios/bong_001.ogg +0 -0
- package/public/res/audios/kenney/audios/click_001.ogg +0 -0
- package/public/res/audios/kenney/audios/click_002.ogg +0 -0
- package/public/res/audios/kenney/audios/click_003.ogg +0 -0
- package/public/res/audios/kenney/audios/click_004.ogg +0 -0
- package/public/res/audios/kenney/audios/click_005.ogg +0 -0
- package/public/res/audios/kenney/audios/close_001.ogg +0 -0
- package/public/res/audios/kenney/audios/close_002.ogg +0 -0
- package/public/res/audios/kenney/audios/close_003.ogg +0 -0
- package/public/res/audios/kenney/audios/close_004.ogg +0 -0
- package/public/res/audios/kenney/audios/confirmation_001.ogg +0 -0
- package/public/res/audios/kenney/audios/confirmation_002.ogg +0 -0
- package/public/res/audios/kenney/audios/confirmation_003.ogg +0 -0
- package/public/res/audios/kenney/audios/confirmation_004.ogg +0 -0
- package/public/res/audios/kenney/audios/drop_001.ogg +0 -0
- package/public/res/audios/kenney/audios/drop_002.ogg +0 -0
- package/public/res/audios/kenney/audios/drop_003.ogg +0 -0
- package/public/res/audios/kenney/audios/drop_004.ogg +0 -0
- package/public/res/audios/kenney/audios/error_001.ogg +0 -0
- package/public/res/audios/kenney/audios/error_002.ogg +0 -0
- package/public/res/audios/kenney/audios/error_003.ogg +0 -0
- package/public/res/audios/kenney/audios/error_004.ogg +0 -0
- package/public/res/audios/kenney/audios/error_005.ogg +0 -0
- package/public/res/audios/kenney/audios/error_006.ogg +0 -0
- package/public/res/audios/kenney/audios/error_007.ogg +0 -0
- package/public/res/audios/kenney/audios/error_008.ogg +0 -0
- package/public/res/audios/kenney/audios/glass_001.ogg +0 -0
- package/public/res/audios/kenney/audios/glass_002.ogg +0 -0
- package/public/res/audios/kenney/audios/glass_003.ogg +0 -0
- package/public/res/audios/kenney/audios/glass_004.ogg +0 -0
- package/public/res/audios/kenney/audios/glass_005.ogg +0 -0
- package/public/res/audios/kenney/audios/glass_006.ogg +0 -0
- package/public/res/audios/kenney/audios/glitch_001.ogg +0 -0
- package/public/res/audios/kenney/audios/glitch_002.ogg +0 -0
- package/public/res/audios/kenney/audios/glitch_003.ogg +0 -0
- package/public/res/audios/kenney/audios/glitch_004.ogg +0 -0
- package/public/res/audios/kenney/audios/maximize_001.ogg +0 -0
- package/public/res/audios/kenney/audios/maximize_002.ogg +0 -0
- package/public/res/audios/kenney/audios/maximize_003.ogg +0 -0
- package/public/res/audios/kenney/audios/maximize_004.ogg +0 -0
- package/public/res/audios/kenney/audios/maximize_005.ogg +0 -0
- package/public/res/audios/kenney/audios/maximize_006.ogg +0 -0
- package/public/res/audios/kenney/audios/maximize_007.ogg +0 -0
- package/public/res/audios/kenney/audios/maximize_008.ogg +0 -0
- package/public/res/audios/kenney/audios/maximize_009.ogg +0 -0
- package/public/res/audios/kenney/audios/minimize_001.ogg +0 -0
- package/public/res/audios/kenney/audios/minimize_002.ogg +0 -0
- package/public/res/audios/kenney/audios/minimize_003.ogg +0 -0
- package/public/res/audios/kenney/audios/minimize_004.ogg +0 -0
- package/public/res/audios/kenney/audios/minimize_005.ogg +0 -0
- package/public/res/audios/kenney/audios/minimize_006.ogg +0 -0
- package/public/res/audios/kenney/audios/minimize_007.ogg +0 -0
- package/public/res/audios/kenney/audios/minimize_008.ogg +0 -0
- package/public/res/audios/kenney/audios/minimize_009.ogg +0 -0
- package/public/res/audios/kenney/audios/open_001.ogg +0 -0
- package/public/res/audios/kenney/audios/open_002.ogg +0 -0
- package/public/res/audios/kenney/audios/open_003.ogg +0 -0
- package/public/res/audios/kenney/audios/open_004.ogg +0 -0
- package/public/res/audios/kenney/audios/pluck_001.ogg +0 -0
- package/public/res/audios/kenney/audios/pluck_002.ogg +0 -0
- package/public/res/audios/kenney/audios/question_001.ogg +0 -0
- package/public/res/audios/kenney/audios/question_002.ogg +0 -0
- package/public/res/audios/kenney/audios/question_003.ogg +0 -0
- package/public/res/audios/kenney/audios/question_004.ogg +0 -0
- package/public/res/audios/kenney/audios/scratch_001.ogg +0 -0
- package/public/res/audios/kenney/audios/scratch_002.ogg +0 -0
- package/public/res/audios/kenney/audios/scratch_003.ogg +0 -0
- package/public/res/audios/kenney/audios/scratch_004.ogg +0 -0
- package/public/res/audios/kenney/audios/scratch_005.ogg +0 -0
- package/public/res/audios/kenney/audios/scroll_001.ogg +0 -0
- package/public/res/audios/kenney/audios/scroll_002.ogg +0 -0
- package/public/res/audios/kenney/audios/scroll_003.ogg +0 -0
- package/public/res/audios/kenney/audios/scroll_004.ogg +0 -0
- package/public/res/audios/kenney/audios/scroll_005.ogg +0 -0
- package/public/res/audios/kenney/audios/select_001.ogg +0 -0
- package/public/res/audios/kenney/audios/select_002.ogg +0 -0
- package/public/res/audios/kenney/audios/select_003.ogg +0 -0
- package/public/res/audios/kenney/audios/select_004.ogg +0 -0
- package/public/res/audios/kenney/audios/select_005.ogg +0 -0
- package/public/res/audios/kenney/audios/select_006.ogg +0 -0
- package/public/res/audios/kenney/audios/select_007.ogg +0 -0
- package/public/res/audios/kenney/audios/select_008.ogg +0 -0
- package/public/res/audios/kenney/audios/switch_001.ogg +0 -0
- package/public/res/audios/kenney/audios/switch_002.ogg +0 -0
- package/public/res/audios/kenney/audios/switch_003.ogg +0 -0
- package/public/res/audios/kenney/audios/switch_004.ogg +0 -0
- package/public/res/audios/kenney/audios/switch_005.ogg +0 -0
- package/public/res/audios/kenney/audios/switch_006.ogg +0 -0
- package/public/res/audios/kenney/audios/switch_007.ogg +0 -0
- package/public/res/audios/kenney/audios/tick_001.ogg +0 -0
- package/public/res/audios/kenney/audios/tick_002.ogg +0 -0
- package/public/res/audios/kenney/audios/tick_004.ogg +0 -0
- package/public/res/audios/kenney/audios/toggle_001.ogg +0 -0
- package/public/res/audios/kenney/audios/toggle_002.ogg +0 -0
- package/public/res/audios/kenney/audios/toggle_003.ogg +0 -0
- package/public/res/audios/kenney/audios/toggle_004.ogg +0 -0
- package/public/res/audios/start.mp3 +0 -0
- package/public/res/audios/toggle_002.mp3 +0 -0
- package/public/res/fonts/Accuratist.ttf +0 -0
- package/public/res/fonts/Closeness.ttf +0 -0
- package/public/res/fonts/WARGAMES.TTF +0 -0
- package/public/res/fonts/readme.txt +5 -0
- package/public/res/fonts/stormfaze.ttf +0 -0
- package/public/res/icons/512.png +0 -0
- package/public/res/icons/webgpu-horizontal.svg +45 -0
- package/public/res/meshes/blender/cube.blend +0 -0
- package/public/res/meshes/blender/cube.blend1 +0 -0
- package/public/res/meshes/blender/cube.mtl +12 -0
- package/public/res/meshes/blender/cube.obj +46 -0
- package/public/res/meshes/blender/cube.png +0 -0
- package/public/res/meshes/blender/cubeSmartUV.blend +0 -0
- package/public/res/meshes/blender/cubeSmartUV.mtl +12 -0
- package/public/res/meshes/blender/cubeSmartUV.obj +46 -0
- package/public/res/meshes/blender/lopta.mtl +10 -0
- package/public/res/meshes/blender/lopta.obj +3402 -0
- package/public/res/meshes/blender/piramyd.blend +0 -0
- package/public/res/meshes/blender/piramyd.blend1 +0 -0
- package/public/res/meshes/blender/piramyd.js +42 -0
- package/public/res/meshes/blender/piramyd.mtl +10 -0
- package/public/res/meshes/blender/piramyd.obj +18696 -0
- package/public/res/meshes/blender/piramyd1.js +42 -0
- package/public/res/meshes/blender/sphepe.blend +0 -0
- package/public/res/meshes/blender/sphepe.blend1 +0 -0
- package/public/res/meshes/blender/sphere.mtl +10 -0
- package/public/res/meshes/blender/sphere.obj +3402 -0
- package/public/res/meshes/blender/welcomeTextblend.blend +0 -0
- package/public/res/meshes/dragon/stanfordDragonData.js +5 -0
- package/public/res/meshes/jamb/bg.blend +0 -0
- package/public/res/meshes/jamb/bg.blend1 +0 -0
- package/public/res/meshes/jamb/bg.mtl +12 -0
- package/public/res/meshes/jamb/bg.obj +17 -0
- package/public/res/meshes/jamb/bg.png +0 -0
- package/public/res/meshes/jamb/dice-default.png +0 -0
- package/public/res/meshes/jamb/dice-mark.png +0 -0
- package/public/res/meshes/jamb/dice.mtl +12 -0
- package/public/res/meshes/jamb/dice.obj +40 -0
- package/public/res/meshes/jamb/dice.png +0 -0
- package/public/res/meshes/jamb/jamb-title.mtl +12 -0
- package/public/res/meshes/jamb/jamb-title.obj +26008 -0
- package/public/res/meshes/jamb/jamb.blend +0 -0
- package/public/res/meshes/jamb/jamb.blend1 +0 -0
- package/public/res/meshes/jamb/logo.png +0 -0
- package/public/res/meshes/jamb/nidzaDice.blend +0 -0
- package/public/res/meshes/jamb/nidzaDice.blend1 +0 -0
- package/public/res/meshes/jamb/pile.blend +0 -0
- package/public/res/meshes/jamb/simpleCube.blend +0 -0
- package/public/res/meshes/jamb/simpleCube.blend1 +0 -0
- package/public/res/meshes/jamb/sounds/roll1.wav +0 -0
- package/public/res/meshes/jamb/text.png +0 -0
- package/public/res/meshes/obj/armor.obj +319 -0
- package/public/res/meshes/obj/armor.png +0 -0
- package/public/res/meshes/objs-sequence/swat-walk-pistol_000001.mtl +22 -0
- package/public/res/meshes/objs-sequence/swat-walk-pistol_000001.obj +23264 -0
- package/public/res/meshes/objs-sequence/swat-walk-pistol_000002.mtl +22 -0
- package/public/res/meshes/objs-sequence/swat-walk-pistol_000002.obj +23261 -0
- package/public/res/meshes/objs-sequence/swat-walk-pistol_000003.mtl +22 -0
- package/public/res/meshes/objs-sequence/swat-walk-pistol_000003.obj +23264 -0
- package/public/res/meshes/objs-sequence/swat-walk-pistol_000004.mtl +22 -0
- package/public/res/meshes/objs-sequence/swat-walk-pistol_000004.obj +23261 -0
- package/public/res/meshes/objs-sequence/swat-walk-pistol_000005.mtl +22 -0
- package/public/res/meshes/objs-sequence/swat-walk-pistol_000005.obj +23261 -0
- package/public/res/meshes/objs-sequence/swat-walk-pistol_000006.mtl +22 -0
- package/public/res/meshes/objs-sequence/swat-walk-pistol_000006.obj +23261 -0
- package/public/res/meshes/objs-sequence/swat-walk-pistol_000007.mtl +22 -0
- package/public/res/meshes/objs-sequence/swat-walk-pistol_000007.obj +23264 -0
- package/public/res/meshes/objs-sequence/swat-walk-pistol_000008.mtl +22 -0
- package/public/res/meshes/objs-sequence/swat-walk-pistol_000008.obj +23263 -0
- package/public/res/meshes/objs-sequence/swat-walk-pistol_000009.mtl +22 -0
- package/public/res/meshes/objs-sequence/swat-walk-pistol_000009.obj +23264 -0
- package/public/res/meshes/objs-sequence/swat-walk-pistol_000010.mtl +22 -0
- package/public/res/meshes/objs-sequence/swat-walk-pistol_000010.obj +23260 -0
- package/public/res/meshes/objs-sequence/swat-walk-pistol_000011.mtl +22 -0
- package/public/res/meshes/objs-sequence/swat-walk-pistol_000011.obj +23262 -0
- package/public/res/meshes/objs-sequence/swat-walk-pistol_000012.mtl +22 -0
- package/public/res/meshes/objs-sequence/swat-walk-pistol_000012.obj +23262 -0
- package/public/res/meshes/objs-sequence/swat-walk-pistol_000013.mtl +22 -0
- package/public/res/meshes/objs-sequence/swat-walk-pistol_000013.obj +23263 -0
- package/public/res/meshes/objs-sequence/swat-walk-pistol_000014.mtl +22 -0
- package/public/res/meshes/objs-sequence/swat-walk-pistol_000014.obj +23262 -0
- package/public/res/meshes/objs-sequence/swat-walk-pistol_000015.mtl +22 -0
- package/public/res/meshes/objs-sequence/swat-walk-pistol_000015.obj +23263 -0
- package/public/res/meshes/objs-sequence/swat-walk-pistol_000016.mtl +22 -0
- package/public/res/meshes/objs-sequence/swat-walk-pistol_000016.obj +23264 -0
- package/public/res/meshes/objs-sequence/swat-walk-pistol_000017.mtl +22 -0
- package/public/res/meshes/objs-sequence/swat-walk-pistol_000017.obj +23263 -0
- package/public/res/meshes/objs-sequence/swat-walk-pistol_000018.mtl +22 -0
- package/public/res/meshes/objs-sequence/swat-walk-pistol_000018.obj +23261 -0
- package/public/res/meshes/objs-sequence/swat-walk-pistol_000019.mtl +22 -0
- package/public/res/meshes/objs-sequence/swat-walk-pistol_000019.obj +23263 -0
- package/public/res/meshes/objs-sequence/swat-walk-pistol_000020.mtl +22 -0
- package/public/res/meshes/objs-sequence/swat-walk-pistol_000020.obj +23261 -0
- package/public/res/meshes/shapes/star1.obj +60 -0
- package/public/res/multilang/en.json +39 -0
- package/public/res/multilang/sr.json +39 -0
- package/public/res/textures/default.png +0 -0
- package/public/res/textures/rust.jpg +0 -0
- package/public/res/textures/tex1.jpg +0 -0
- package/public/res/videos/readme.txt +2 -0
- package/public/res/videos/tunel.mp4 +0 -0
- package/public/test.html +636 -0
- package/public/three-test.js +165 -0
- package/public/worker.html +25 -0
- package/src/engine/ball.js +482 -0
- package/src/engine/cube.js +496 -0
- package/src/engine/engine.js +404 -0
- package/src/engine/final/adaptJSON1.js +53 -0
- package/src/engine/final/utils2.js +63 -0
- package/src/engine/lights.js +153 -0
- package/src/engine/loader-obj.js +473 -0
- package/src/engine/materials.js +295 -0
- package/src/engine/matrix-class.js +252 -0
- package/src/engine/mesh-obj.js +574 -0
- package/src/engine/raycast.js +218 -0
- package/src/engine/utils.js +881 -0
- package/src/libs/mat.js +0 -0
- package/src/multilang/lang.js +35 -0
- package/src/physics/matrix-ammo.js +363 -0
- package/src/shaders/fragment.video.wgsl.js +83 -0
- package/src/shaders/fragment.wgsl.js +75 -0
- package/src/shaders/shaders.js +51 -0
- package/src/shaders/standard-matrix-engine-shaders/standard-matrix-engine-fs.glsl +56 -0
- package/src/shaders/standard-matrix-engine-shaders/standard-matrix-engine-vs.glsl +75 -0
- package/src/shaders/vertex.wgsl.js +54 -0
- package/src/shaders/vertexShadow.wgsl.js +20 -0
- package/src/sounds/sounds.js +69 -0
- package/src/world.js +474 -0
|
@@ -0,0 +1,404 @@
|
|
|
1
|
+
// Note: The code in this file does not use the 'dst' output parameter of functions in the
|
|
2
|
+
// 'wgpu-matrix' library, so produces many temporary vectors and matrices.
|
|
3
|
+
// This is intentional, as this sample prefers readability over performance.
|
|
4
|
+
import { mat4, vec3 } from 'wgpu-matrix';
|
|
5
|
+
import {LOG_INFO} from './utils';
|
|
6
|
+
|
|
7
|
+
// The common functionality between camera implementations
|
|
8
|
+
class CameraBase {
|
|
9
|
+
// The camera matrix
|
|
10
|
+
matrix_ = new Float32Array([
|
|
11
|
+
1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1,
|
|
12
|
+
]);
|
|
13
|
+
|
|
14
|
+
// The calculated view matrix readonly
|
|
15
|
+
view_ = mat4.create();
|
|
16
|
+
|
|
17
|
+
// Aliases to column vectors of the matrix
|
|
18
|
+
right_ = new Float32Array(this.matrix_.buffer, 4 * 0, 4);
|
|
19
|
+
up_ = new Float32Array(this.matrix_.buffer, 4 * 4, 4);
|
|
20
|
+
back_ = new Float32Array(this.matrix_.buffer, 4 * 8, 4);
|
|
21
|
+
position_ = new Float32Array(this.matrix_.buffer, 4 * 12, 4);
|
|
22
|
+
|
|
23
|
+
// Returns the camera matrix
|
|
24
|
+
get matrix() {
|
|
25
|
+
return this.matrix_;
|
|
26
|
+
}
|
|
27
|
+
// Assigns `mat` to the camera matrix
|
|
28
|
+
set matrix(mat) {
|
|
29
|
+
mat4.copy(mat, this.matrix_);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
setProjection(fov = (2 * Math.PI) / 5, aspect = 1, near = 1, far = 1000) {
|
|
33
|
+
this.projectionMatrix = mat4.perspective(fov, aspect, near, far);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Returns the camera view matrix
|
|
37
|
+
get view() {
|
|
38
|
+
return this.view_;
|
|
39
|
+
}
|
|
40
|
+
// Assigns `mat` to the camera view
|
|
41
|
+
set view(mat) {
|
|
42
|
+
mat4.copy(mat, this.view_);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Returns column vector 0 of the camera matrix
|
|
46
|
+
get right() {
|
|
47
|
+
return this.right_;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Assigns `vec` to the first 3 elements of column vector 0 of the camera matrix
|
|
51
|
+
set right(vec) {
|
|
52
|
+
vec3.copy(vec, this.right_);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Returns column vector 1 of the camera matrix
|
|
56
|
+
get up() {
|
|
57
|
+
return this.up_;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Assigns `vec` to the first 3 elements of column vector 1 of the camera matrix \ Vec3
|
|
61
|
+
set up(vec) {
|
|
62
|
+
vec3.copy(vec, this.up_);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Returns column vector 2 of the camera matrix
|
|
66
|
+
get back() {
|
|
67
|
+
return this.back_;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Assigns `vec` to the first 3 elements of column vector 2 of the camera matrix
|
|
71
|
+
set back(vec) {
|
|
72
|
+
vec3.copy(vec, this.back_);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Returns column vector 3 of the camera matrix
|
|
76
|
+
get position() {
|
|
77
|
+
return this.position_;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Assigns `vec` to the first 3 elements of column vector 3 of the camera matrix
|
|
81
|
+
set position(vec) {
|
|
82
|
+
vec3.copy(vec, this.position_);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// WASDCamera is a camera implementation that behaves similar to first-person-shooter PC games.
|
|
87
|
+
export class WASDCamera extends CameraBase {
|
|
88
|
+
// The camera absolute pitch angle
|
|
89
|
+
pitch = 0;
|
|
90
|
+
// The camera absolute yaw angle
|
|
91
|
+
yaw = 0;
|
|
92
|
+
|
|
93
|
+
// The movement veloicty readonly
|
|
94
|
+
velocity_ = vec3.create();
|
|
95
|
+
|
|
96
|
+
// Speed multiplier for camera movement
|
|
97
|
+
movementSpeed = 10;
|
|
98
|
+
|
|
99
|
+
// Speed multiplier for camera rotation
|
|
100
|
+
rotationSpeed = 1;
|
|
101
|
+
|
|
102
|
+
// Movement velocity drag coeffient [0 .. 1]
|
|
103
|
+
// 0: Continues forever
|
|
104
|
+
// 1: Instantly stops moving
|
|
105
|
+
frictionCoefficient = 0.99;
|
|
106
|
+
|
|
107
|
+
// Returns velocity vector
|
|
108
|
+
get velocity() {
|
|
109
|
+
return this.velocity_;
|
|
110
|
+
}
|
|
111
|
+
// Assigns `vec` to the velocity vector
|
|
112
|
+
set velocity(vec) {
|
|
113
|
+
vec3.copy(vec, this.velocity_);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
constructor(options) {
|
|
117
|
+
super();
|
|
118
|
+
if (options && (options.position || options.target)) {
|
|
119
|
+
const position = options.position ?? vec3.create(0, 0, 0);
|
|
120
|
+
const target = options.target ?? vec3.create(0, 0, 0);
|
|
121
|
+
const forward = vec3.normalize(vec3.sub(target, position));
|
|
122
|
+
this.recalculateAngles(forward);
|
|
123
|
+
this.position = position;
|
|
124
|
+
this.setProjection()
|
|
125
|
+
// console.log(`%cCamera constructor : ${position}`, LOG_INFO);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Returns the camera matrix
|
|
130
|
+
get matrix() {
|
|
131
|
+
return super.matrix;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Assigns `mat` to the camera matrix, and recalcuates the camera angles
|
|
135
|
+
set matrix(mat) {
|
|
136
|
+
super.matrix = mat;
|
|
137
|
+
this.recalculateAngles(this.back);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
update(deltaTime, input) {
|
|
141
|
+
const sign = (positive, negative) =>
|
|
142
|
+
(positive ? 1 : 0) - (negative ? 1 : 0);
|
|
143
|
+
|
|
144
|
+
// Apply the delta rotation to the pitch and yaw angles
|
|
145
|
+
this.yaw -= input.analog.x * deltaTime * this.rotationSpeed;
|
|
146
|
+
this.pitch -= input.analog.y * deltaTime * this.rotationSpeed;
|
|
147
|
+
|
|
148
|
+
// Wrap yaw between [0° .. 360°], just to prevent large accumulation.
|
|
149
|
+
this.yaw = mod(this.yaw, Math.PI * 2);
|
|
150
|
+
// Clamp pitch between [-90° .. +90°] to prevent somersaults.
|
|
151
|
+
this.pitch = clamp(this.pitch, -Math.PI / 2, Math.PI / 2);
|
|
152
|
+
|
|
153
|
+
// Save the current position, as we're about to rebuild the camera matrix.
|
|
154
|
+
const position = vec3.copy(this.position);
|
|
155
|
+
|
|
156
|
+
// Reconstruct the camera's rotation, and store into the camera matrix.
|
|
157
|
+
super.matrix = mat4.rotateX(mat4.rotationY(this.yaw), this.pitch);
|
|
158
|
+
// super.matrix = mat4.rotateX(mat4.rotationY(this.yaw), -this.pitch);
|
|
159
|
+
// super.matrix = mat4.rotateY(mat4.rotateX(this.pitch), this.yaw);
|
|
160
|
+
|
|
161
|
+
// Calculate the new target velocity
|
|
162
|
+
const digital = input.digital;
|
|
163
|
+
const deltaRight = sign(digital.right, digital.left);
|
|
164
|
+
const deltaUp = sign(digital.up, digital.down);
|
|
165
|
+
const targetVelocity = vec3.create();
|
|
166
|
+
const deltaBack = sign(digital.backward, digital.forward);
|
|
167
|
+
vec3.addScaled(targetVelocity, this.right, deltaRight, targetVelocity);
|
|
168
|
+
vec3.addScaled(targetVelocity, this.up, deltaUp, targetVelocity);
|
|
169
|
+
vec3.addScaled(targetVelocity, this.back, deltaBack, targetVelocity);
|
|
170
|
+
vec3.normalize(targetVelocity, targetVelocity);
|
|
171
|
+
vec3.mulScalar(targetVelocity, this.movementSpeed, targetVelocity);
|
|
172
|
+
|
|
173
|
+
// Mix new target velocity
|
|
174
|
+
this.velocity = lerp(
|
|
175
|
+
targetVelocity,
|
|
176
|
+
this.velocity,
|
|
177
|
+
Math.pow(1 - this.frictionCoefficient, deltaTime)
|
|
178
|
+
);
|
|
179
|
+
|
|
180
|
+
// Integrate velocity to calculate new position
|
|
181
|
+
this.position = vec3.addScaled(position, this.velocity, deltaTime);
|
|
182
|
+
|
|
183
|
+
// Invert the camera matrix to build the view matrix
|
|
184
|
+
this.view = mat4.invert(this.matrix);
|
|
185
|
+
return this.view;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// Recalculates the yaw and pitch values from a directional vector
|
|
189
|
+
recalculateAngles(dir) {
|
|
190
|
+
this.yaw = Math.atan2(dir[0], dir[2]);
|
|
191
|
+
this.pitch = -Math.asin(dir[1]);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// ArcballCamera implements a basic orbiting camera around the world origin
|
|
196
|
+
export class ArcballCamera extends CameraBase {
|
|
197
|
+
// The camera distance from the target
|
|
198
|
+
distance = 0;
|
|
199
|
+
|
|
200
|
+
// The current angular velocity
|
|
201
|
+
angularVelocity = 0;
|
|
202
|
+
|
|
203
|
+
// The current rotation axis
|
|
204
|
+
axis_ = vec3.create();
|
|
205
|
+
|
|
206
|
+
// Returns the rotation axis
|
|
207
|
+
get axis() {
|
|
208
|
+
return this.axis_;
|
|
209
|
+
}
|
|
210
|
+
// Assigns `vec` to the rotation axis
|
|
211
|
+
set axis(vec) {
|
|
212
|
+
vec3.copy(vec, this.axis_);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// Speed multiplier for camera rotation
|
|
216
|
+
rotationSpeed = 1;
|
|
217
|
+
|
|
218
|
+
// Speed multiplier for camera zoom
|
|
219
|
+
zoomSpeed = 0.1;
|
|
220
|
+
|
|
221
|
+
// Rotation velocity drag coeffient [0 .. 1]
|
|
222
|
+
// 0: Spins forever
|
|
223
|
+
// 1: Instantly stops spinning
|
|
224
|
+
frictionCoefficient = 0.999;
|
|
225
|
+
|
|
226
|
+
// Construtor
|
|
227
|
+
constructor(options) {
|
|
228
|
+
super();
|
|
229
|
+
if (options && options.position) {
|
|
230
|
+
this.position = options.position;
|
|
231
|
+
this.distance = vec3.len(this.position);
|
|
232
|
+
this.back = vec3.normalize(this.position);
|
|
233
|
+
this.recalcuateRight();
|
|
234
|
+
this.recalcuateUp();
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// Returns the camera matrix
|
|
239
|
+
get matrix() {
|
|
240
|
+
return super.matrix;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// Assigns `mat` to the camera matrix, and recalcuates the distance
|
|
244
|
+
set matrix(mat) {
|
|
245
|
+
super.matrix = mat;
|
|
246
|
+
this.distance = vec3.len(this.position);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
update(deltaTime, input) {
|
|
250
|
+
const epsilon = 0.0000001;
|
|
251
|
+
|
|
252
|
+
if (input.analog.touching) {
|
|
253
|
+
// Currently being dragged.
|
|
254
|
+
this.angularVelocity = 0;
|
|
255
|
+
} else {
|
|
256
|
+
// Dampen any existing angular velocity
|
|
257
|
+
this.angularVelocity *= Math.pow(1 - this.frictionCoefficient, deltaTime);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// Calculate the movement vector
|
|
261
|
+
const movement = vec3.create();
|
|
262
|
+
vec3.addScaled(movement, this.right, input.analog.x, movement);
|
|
263
|
+
vec3.addScaled(movement, this.up, -input.analog.y, movement);
|
|
264
|
+
|
|
265
|
+
// Cross the movement vector with the view direction to calculate the rotation axis x magnitude
|
|
266
|
+
const crossProduct = vec3.cross(movement, this.back);
|
|
267
|
+
|
|
268
|
+
// Calculate the magnitude of the drag
|
|
269
|
+
const magnitude = vec3.len(crossProduct);
|
|
270
|
+
|
|
271
|
+
if (magnitude > epsilon) {
|
|
272
|
+
// Normalize the crossProduct to get the rotation axis
|
|
273
|
+
this.axis = vec3.scale(crossProduct, 1 / magnitude);
|
|
274
|
+
|
|
275
|
+
// Remember the current angular velocity. This is used when the touch is released for a fling.
|
|
276
|
+
this.angularVelocity = magnitude * this.rotationSpeed;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// The rotation around this.axis to apply to the camera matrix this update
|
|
280
|
+
const rotationAngle = this.angularVelocity * deltaTime;
|
|
281
|
+
if (rotationAngle > epsilon) {
|
|
282
|
+
// Rotate the matrix around axis
|
|
283
|
+
// Note: The rotation is not done as a matrix-matrix multiply as the repeated multiplications
|
|
284
|
+
// will quickly introduce substantial error into the matrix.
|
|
285
|
+
this.back = vec3.normalize(rotate(this.back, this.axis, rotationAngle));
|
|
286
|
+
this.recalcuateRight();
|
|
287
|
+
this.recalcuateUp();
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
// recalculate `this.position` from `this.back` considering zoom
|
|
291
|
+
if (input.analog.zoom !== 0) {
|
|
292
|
+
this.distance *= 1 + input.analog.zoom * this.zoomSpeed;
|
|
293
|
+
}
|
|
294
|
+
this.position = vec3.scale(this.back, this.distance);
|
|
295
|
+
|
|
296
|
+
// Invert the camera matrix to build the view matrix
|
|
297
|
+
this.view = mat4.invert(this.matrix);
|
|
298
|
+
return this.view;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// Assigns `this.right` with the cross product of `this.up` and `this.back`
|
|
302
|
+
recalcuateRight() {
|
|
303
|
+
this.right = vec3.normalize(vec3.cross(this.up, this.back));
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
// Assigns `this.up` with the cross product of `this.back` and `this.right`
|
|
307
|
+
recalcuateUp() {
|
|
308
|
+
this.up = vec3.normalize(vec3.cross(this.back, this.right));
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// Returns `x` clamped between [`min` .. `max`]
|
|
313
|
+
function clamp(x, min, max) {
|
|
314
|
+
return Math.min(Math.max(x, min), max);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
// Returns `x` float-modulo `div`
|
|
318
|
+
function mod(x, div) {
|
|
319
|
+
return x - Math.floor(Math.abs(x) / div) * div * Math.sign(x);
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
// Returns `vec` rotated `angle` radians around `axis`
|
|
323
|
+
function rotate(vec, axis, angle) {
|
|
324
|
+
return vec3.transformMat4Upper3x3(vec, mat4.rotation(axis, angle));
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// Returns the linear interpolation between 'a' and 'b' using 's'
|
|
328
|
+
function lerp(a, b, s) {
|
|
329
|
+
return vec3.addScaled(a, vec3.sub(b, a), s);
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
export function createInputHandler(window, canvas) {
|
|
333
|
+
let digital = {
|
|
334
|
+
forward: false,
|
|
335
|
+
backward: false,
|
|
336
|
+
left: false,
|
|
337
|
+
right: false,
|
|
338
|
+
up: false,
|
|
339
|
+
down: false,
|
|
340
|
+
};
|
|
341
|
+
let analog = {
|
|
342
|
+
x: 0,
|
|
343
|
+
y: 0,
|
|
344
|
+
zoom: 0,
|
|
345
|
+
};
|
|
346
|
+
let mouseDown = false;
|
|
347
|
+
|
|
348
|
+
const setDigital = (e, value) => {
|
|
349
|
+
switch (e.code) {
|
|
350
|
+
case 'KeyW': digital.forward = value; break;
|
|
351
|
+
case 'KeyS': digital.backward = value; break;
|
|
352
|
+
case 'KeyA': digital.left = value; break;
|
|
353
|
+
case 'KeyD': digital.right = value; break;
|
|
354
|
+
case 'Space': digital.up = value; break;
|
|
355
|
+
case 'ShiftLeft':
|
|
356
|
+
case 'ControlLeft':
|
|
357
|
+
case 'KeyC': digital.down = value; break;
|
|
358
|
+
}
|
|
359
|
+
e.preventDefault();
|
|
360
|
+
e.stopPropagation();
|
|
361
|
+
};
|
|
362
|
+
|
|
363
|
+
window.addEventListener('keydown', (e) => setDigital(e, true));
|
|
364
|
+
window.addEventListener('keyup', (e) => setDigital(e, false));
|
|
365
|
+
|
|
366
|
+
canvas.style.touchAction = 'pinch-zoom';
|
|
367
|
+
canvas.addEventListener('pointerdown', () => { mouseDown = true; });
|
|
368
|
+
canvas.addEventListener('pointerup', () => { mouseDown = false; });
|
|
369
|
+
canvas.addEventListener('pointermove', (e) => {
|
|
370
|
+
mouseDown = e.pointerType === 'mouse' ? (e.buttons & 1) !== 0 : true;
|
|
371
|
+
if (mouseDown) {
|
|
372
|
+
analog.x += e.movementX / 10;
|
|
373
|
+
analog.y += e.movementY / 10;
|
|
374
|
+
}
|
|
375
|
+
});
|
|
376
|
+
|
|
377
|
+
canvas.addEventListener('wheel', (e) => {
|
|
378
|
+
if ((e.buttons & 1) !== 0) {
|
|
379
|
+
analog.zoom += Math.sign(e.deltaY);
|
|
380
|
+
e.preventDefault();
|
|
381
|
+
e.stopPropagation();
|
|
382
|
+
}
|
|
383
|
+
}, { passive: false });
|
|
384
|
+
|
|
385
|
+
return () => {
|
|
386
|
+
// Guard: prevent zero deltas from breaking camera math
|
|
387
|
+
const safeX = analog.x || 0.0001;
|
|
388
|
+
const safeY = analog.y || 0.0001;
|
|
389
|
+
const out = {
|
|
390
|
+
digital,
|
|
391
|
+
analog: {
|
|
392
|
+
x: safeX,
|
|
393
|
+
y: safeY,
|
|
394
|
+
zoom: analog.zoom,
|
|
395
|
+
touching: mouseDown,
|
|
396
|
+
},
|
|
397
|
+
};
|
|
398
|
+
// Reset only the deltas for next frame
|
|
399
|
+
analog.x = 0;
|
|
400
|
+
analog.y = 0;
|
|
401
|
+
analog.zoom = 0;
|
|
402
|
+
return out;
|
|
403
|
+
};
|
|
404
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import {computeSurfaceNormals, computeProjectedPlaneUVs} from './utils2.js';
|
|
2
|
+
|
|
3
|
+
export function adaptJSON1(dragonRawData) {
|
|
4
|
+
|
|
5
|
+
let mesh = {
|
|
6
|
+
positions: dragonRawData.positions,
|
|
7
|
+
triangles: dragonRawData.cells,
|
|
8
|
+
normals: [],
|
|
9
|
+
uvs: []
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
// Compute surface normals
|
|
13
|
+
mesh.normals = computeSurfaceNormals(mesh.positions, mesh.triangles);
|
|
14
|
+
|
|
15
|
+
// Compute some easy uvs for testing
|
|
16
|
+
mesh.uvs = computeProjectedPlaneUVs(mesh.positions, 'xy');
|
|
17
|
+
|
|
18
|
+
return mesh;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function addVerticesNormalUvs(mesh) {
|
|
22
|
+
|
|
23
|
+
var meshAdapted = {
|
|
24
|
+
positions: [],
|
|
25
|
+
cells: [],
|
|
26
|
+
uvs: mesh.textures,
|
|
27
|
+
vertices: mesh.vertices
|
|
28
|
+
// normals: mesh.vertexNormals
|
|
29
|
+
};
|
|
30
|
+
// force syntese
|
|
31
|
+
for (var x = 0; x < mesh.vertices.length; x=x+3) {
|
|
32
|
+
var sub = [];
|
|
33
|
+
sub.push(mesh.vertices[x])
|
|
34
|
+
sub.push(mesh.vertices[x+1])
|
|
35
|
+
sub.push(mesh.vertices[x+2])
|
|
36
|
+
meshAdapted.positions.push(sub)
|
|
37
|
+
sub = [];
|
|
38
|
+
sub.push(mesh.indices[x])
|
|
39
|
+
sub.push(mesh.indices[x+1])
|
|
40
|
+
sub.push(mesh.indices[x+2])
|
|
41
|
+
meshAdapted.cells.push(sub)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Compute surface normals
|
|
45
|
+
meshAdapted.normals = computeSurfaceNormals(meshAdapted.positions, meshAdapted.cells);
|
|
46
|
+
// Compute some easy uvs for testing
|
|
47
|
+
meshAdapted.uvs = computeProjectedPlaneUVs(meshAdapted.positions, 'xy');
|
|
48
|
+
|
|
49
|
+
meshAdapted.triangles = meshAdapted.cells
|
|
50
|
+
return meshAdapted;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { vec3 } from 'wgpu-matrix';
|
|
2
|
+
|
|
3
|
+
export function computeSurfaceNormals(positions,triangles){
|
|
4
|
+
const normals = positions.map(() => {
|
|
5
|
+
// Initialize to zero.
|
|
6
|
+
return [0, 0, 0];
|
|
7
|
+
});
|
|
8
|
+
triangles.forEach(([i0, i1, i2]) => {
|
|
9
|
+
const p0 = positions[i0];
|
|
10
|
+
const p1 = positions[i1];
|
|
11
|
+
const p2 = positions[i2];
|
|
12
|
+
|
|
13
|
+
const v0 = vec3.subtract(p1, p0);
|
|
14
|
+
const v1 = vec3.subtract(p2, p0);
|
|
15
|
+
|
|
16
|
+
vec3.normalize(v0, v0);
|
|
17
|
+
vec3.normalize(v1, v1);
|
|
18
|
+
const norm = vec3.cross(v0, v1);
|
|
19
|
+
|
|
20
|
+
// Accumulate the normals.
|
|
21
|
+
vec3.add(normals[i0], norm, normals[i0]);
|
|
22
|
+
vec3.add(normals[i1], norm, normals[i1]);
|
|
23
|
+
vec3.add(normals[i2], norm, normals[i2]);
|
|
24
|
+
});
|
|
25
|
+
normals.forEach((n) => {
|
|
26
|
+
// Normalize accumulated normals.
|
|
27
|
+
vec3.normalize(n, n);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
return normals;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// type ProjectedPlane = 'xy' | 'xz' | 'yz';
|
|
34
|
+
const projectedPlane2Ids = {
|
|
35
|
+
xy: [0, 1],
|
|
36
|
+
xz: [0, 2],
|
|
37
|
+
yz: [1, 2],
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export function computeProjectedPlaneUVs(positions, projectedPlane) {
|
|
41
|
+
const idxs = projectedPlane2Ids[projectedPlane];
|
|
42
|
+
const uvs = positions.map(() => {
|
|
43
|
+
// Initialize to zero.
|
|
44
|
+
return [0, 0];
|
|
45
|
+
});
|
|
46
|
+
const extentMin = [Infinity, Infinity];
|
|
47
|
+
const extentMax = [-Infinity, -Infinity];
|
|
48
|
+
positions.forEach((pos, i) => {
|
|
49
|
+
// Simply project to the selected plane
|
|
50
|
+
uvs[i][0] = pos[idxs[0]];
|
|
51
|
+
uvs[i][1] = pos[idxs[1]];
|
|
52
|
+
|
|
53
|
+
extentMin[0] = Math.min(pos[idxs[0]], extentMin[0]);
|
|
54
|
+
extentMin[1] = Math.min(pos[idxs[1]], extentMin[1]);
|
|
55
|
+
extentMax[0] = Math.max(pos[idxs[0]], extentMax[0]);
|
|
56
|
+
extentMax[1] = Math.max(pos[idxs[1]], extentMax[1]);
|
|
57
|
+
});
|
|
58
|
+
uvs.forEach((uv) => {
|
|
59
|
+
uv[0] = (uv[0] - extentMin[0]) / (extentMax[0] - extentMin[0]);
|
|
60
|
+
uv[1] = (uv[1] - extentMin[1]) / (extentMax[1] - extentMin[1]);
|
|
61
|
+
});
|
|
62
|
+
return uvs;
|
|
63
|
+
}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import {mat4, vec3} from 'wgpu-matrix';
|
|
2
|
+
|
|
3
|
+
export class SpotLight {
|
|
4
|
+
// injected
|
|
5
|
+
camera;
|
|
6
|
+
inputHandler;
|
|
7
|
+
|
|
8
|
+
// Light
|
|
9
|
+
position;
|
|
10
|
+
target;
|
|
11
|
+
up;
|
|
12
|
+
direction;
|
|
13
|
+
|
|
14
|
+
viewMatrix;
|
|
15
|
+
projectionMatrix;
|
|
16
|
+
viewProjMatrix;
|
|
17
|
+
|
|
18
|
+
fov;
|
|
19
|
+
aspect;
|
|
20
|
+
near;
|
|
21
|
+
far;
|
|
22
|
+
|
|
23
|
+
innerCutoff;
|
|
24
|
+
outerCutoff;
|
|
25
|
+
|
|
26
|
+
spotlightUniformBuffer;
|
|
27
|
+
|
|
28
|
+
constructor(
|
|
29
|
+
camera,
|
|
30
|
+
inputHandler,
|
|
31
|
+
position = vec3.create(0, 5, -10),
|
|
32
|
+
target = vec3.create(0, 0, 0),
|
|
33
|
+
fov = 45,
|
|
34
|
+
aspect = 1.0,
|
|
35
|
+
near = 0.1,
|
|
36
|
+
far = 200
|
|
37
|
+
) {
|
|
38
|
+
this.camera = camera;
|
|
39
|
+
this.inputHandler = inputHandler;
|
|
40
|
+
|
|
41
|
+
this.position = position;
|
|
42
|
+
this.target = target;
|
|
43
|
+
this.up = vec3.create(0, 1, 0);
|
|
44
|
+
this.direction = vec3.normalize(vec3.subtract(target, position));
|
|
45
|
+
|
|
46
|
+
this.viewMatrix = mat4.lookAt(position, target, this.up);
|
|
47
|
+
this.projectionMatrix = mat4.perspective(
|
|
48
|
+
(fov * Math.PI) / 180,
|
|
49
|
+
aspect,
|
|
50
|
+
near,
|
|
51
|
+
far
|
|
52
|
+
);
|
|
53
|
+
this.viewProjMatrix = mat4.multiply(this.projectionMatrix, this.viewMatrix);
|
|
54
|
+
|
|
55
|
+
this.fov = fov;
|
|
56
|
+
this.aspect = aspect;
|
|
57
|
+
this.near = near;
|
|
58
|
+
this.far = far;
|
|
59
|
+
|
|
60
|
+
this.innerCutoff = Math.cos((Math.PI / 180) * 12.5);
|
|
61
|
+
this.outerCutoff = Math.cos((Math.PI / 180) * 17.5);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
update() {
|
|
65
|
+
// this.direction = vec3.normalize(vec3.subtract(this.target, this.position));
|
|
66
|
+
// this.viewMatrix = mat4.lookAt(this.position, this.target, this.up);
|
|
67
|
+
// this.viewProjMatrix = mat4.multiply(this.projectionMatrix, this.viewMatrix);
|
|
68
|
+
// console.log('test light update this.target : ', this.target)
|
|
69
|
+
// Use the existing direction
|
|
70
|
+
const target = vec3.add(this.position, this.direction);
|
|
71
|
+
this.viewMatrix = mat4.lookAt(this.position, target, this.up);
|
|
72
|
+
this.viewProjMatrix = mat4.multiply(this.projectionMatrix, this.viewMatrix);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
updateSceneUniforms(mainRenderBundle) {
|
|
76
|
+
const now = Date.now();
|
|
77
|
+
// First frame safety
|
|
78
|
+
let dt = (now - this.lastFrameMS) / 1000;
|
|
79
|
+
if(!this.lastFrameMS) {dt = 16;}
|
|
80
|
+
this.lastFrameMS = now;
|
|
81
|
+
// engine, once per frame
|
|
82
|
+
this.camera.update(dt, this.inputHandler());
|
|
83
|
+
const camVP = mat4.multiply(this.camera.projectionMatrix, this.camera.view); // P * V
|
|
84
|
+
|
|
85
|
+
for(const mesh of mainRenderBundle) {
|
|
86
|
+
// scene buffer layout = 0..63 lightVP, 64..127 camVP, 128..143 lightPos(+pad)
|
|
87
|
+
this.device.queue.writeBuffer(
|
|
88
|
+
mesh.sceneUniformBuffer,
|
|
89
|
+
64, // cameraViewProjMatrix offset
|
|
90
|
+
camVP.buffer,
|
|
91
|
+
camVP.byteOffset,
|
|
92
|
+
camVP.byteLength
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
// const camVP = mat4.multiply(camera.projectionMatrix, camera.view);
|
|
96
|
+
// const sceneData = new Float32Array(36); // 16 + 16 + 4
|
|
97
|
+
// sceneData.set(this.viewProjMatrix, 0);
|
|
98
|
+
// sceneData.set(camVP, 16);
|
|
99
|
+
// sceneData.set(this.position, 32);
|
|
100
|
+
// if(!this.device) {
|
|
101
|
+
// console.warn("Device not set for SpotLight");
|
|
102
|
+
// return;
|
|
103
|
+
// }
|
|
104
|
+
// this.device.queue.writeBuffer(
|
|
105
|
+
// sceneUniformBuffer,
|
|
106
|
+
// // this.spotlightUniformBuffer,
|
|
107
|
+
// 0,
|
|
108
|
+
// sceneData.buffer,
|
|
109
|
+
// sceneData.byteOffset,
|
|
110
|
+
// sceneData.byteLength
|
|
111
|
+
// );
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
prepareBuffer(device) {
|
|
115
|
+
if(!this.device) this.device = device;
|
|
116
|
+
this.spotlightUniformBuffer = this.device.createBuffer({
|
|
117
|
+
size: 16 * 4, // 64 bytes
|
|
118
|
+
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
const spotlightData = this.getLightDataBuffer();
|
|
122
|
+
this.device.queue.writeBuffer(
|
|
123
|
+
this.spotlightUniformBuffer,
|
|
124
|
+
0,
|
|
125
|
+
spotlightData.buffer,
|
|
126
|
+
spotlightData.byteOffset,
|
|
127
|
+
spotlightData.byteLength
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
updateLightBuffer() {
|
|
132
|
+
if(!this.device || !this.spotlightUniformBuffer) {return;}
|
|
133
|
+
const spotlightData = this.getLightDataBuffer();
|
|
134
|
+
this.device.queue.writeBuffer(
|
|
135
|
+
this.spotlightUniformBuffer,
|
|
136
|
+
0,
|
|
137
|
+
spotlightData.buffer,
|
|
138
|
+
spotlightData.byteOffset,
|
|
139
|
+
spotlightData.byteLength
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
getLightDataBuffer() {
|
|
144
|
+
return new Float32Array([
|
|
145
|
+
...this.position, 0.0,
|
|
146
|
+
...this.direction, 0.0,
|
|
147
|
+
this.innerCutoff,
|
|
148
|
+
this.outerCutoff,
|
|
149
|
+
0.0,
|
|
150
|
+
0.0,
|
|
151
|
+
]);
|
|
152
|
+
}
|
|
153
|
+
}
|