kireji 0.17.0 → 0.18.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.
- package/package.json +1 -1
- package/src/app/kireji/issue-tracker/active-overlay/issue-modal/1776207331/priority +1 -0
- package/src/app/kireji/issue-tracker/active-overlay/issue-modal/1776212585/status +1 -0
- package/src/app/kireji/issue-tracker/active-overlay/issue-modal/1776307785/status +1 -1
- package/src/app/kireji/issue-tracker/active-overlay/issue-modal/1780696449/status +1 -1
- package/src/app/kireji/issue-tracker/active-overlay/issue-modal/1781522546/affects_.js +3 -0
- package/src/app/kireji/issue-tracker/active-overlay/issue-modal/1781522546/description +1 -0
- package/src/app/kireji/issue-tracker/active-overlay/issue-modal/1781522546/part.json +3 -0
- package/src/app/kireji/issue-tracker/active-overlay/issue-modal/1781522546/priority +1 -0
- package/src/app/kireji/issue-tracker/active-overlay/issue-modal/1781522546/status +1 -0
- package/src/app/kireji/issue-tracker/active-overlay/issue-modal/1781522546/title +1 -0
- package/src/app/kireji/issue-tracker/active-overlay/issue-modal/1782803713/affects_.js +3 -0
- package/src/app/kireji/issue-tracker/active-overlay/issue-modal/1782803713/description +1 -0
- package/src/app/kireji/issue-tracker/active-overlay/issue-modal/1782803713/part.json +3 -0
- package/src/app/kireji/issue-tracker/active-overlay/issue-modal/1782803713/priority +1 -0
- package/src/app/kireji/issue-tracker/active-overlay/issue-modal/1782803713/status +1 -0
- package/src/app/kireji/issue-tracker/active-overlay/issue-modal/1782803713/title +1 -0
- package/src/app/kireji/issue-tracker/active-overlay/issue-modal/1782803799/affects_.js +3 -0
- package/src/app/kireji/issue-tracker/active-overlay/issue-modal/1782803799/description +1 -0
- package/src/app/kireji/issue-tracker/active-overlay/issue-modal/1782803799/part.json +3 -0
- package/src/app/kireji/issue-tracker/active-overlay/issue-modal/1782803799/priority +1 -0
- package/src/app/kireji/issue-tracker/active-overlay/issue-modal/1782803799/status +1 -0
- package/src/app/kireji/issue-tracker/active-overlay/issue-modal/1782803799/title +1 -0
- package/src/app/kireji/issue-tracker/active-overlay/issue-modal/1782804028/affects_.js +3 -0
- package/src/app/kireji/issue-tracker/active-overlay/issue-modal/1782804028/description +7 -0
- package/src/app/kireji/issue-tracker/active-overlay/issue-modal/1782804028/part.json +3 -0
- package/src/app/kireji/issue-tracker/active-overlay/issue-modal/1782804028/priority +1 -0
- package/src/app/kireji/issue-tracker/active-overlay/issue-modal/1782804028/status +1 -0
- package/src/app/kireji/issue-tracker/active-overlay/issue-modal/1782804028/title +1 -0
- package/src/build.js +1 -1
- package/src/part.css_.js +4 -0
- package/src/part.html_.js +2 -0
- package/src/parts/abstract/gltf-game/async-load-level.js +10 -2
- package/src/parts/abstract/gltf-game/build.js +1 -0
- package/src/parts/abstract/gltf-game/camera/buffer_.js +34 -95
- package/src/parts/abstract/gltf-game/debug-toggle.js +8 -0
- package/src/parts/abstract/gltf-game/levels/level/data-get.js +22 -0
- package/src/parts/abstract/gltf-game/levels/level/type.d.ts +2 -0
- package/src/parts/abstract/gltf-game/loop.js +1 -1
- package/src/parts/abstract/gltf-game/part.html_.js +1 -1
- package/src/parts/abstract/gltf-game/part.json +0 -1
- package/src/parts/abstract/gltf-game/point-action.js +1 -0
- package/src/parts/abstract/gltf-game/render.js +1 -1
- package/src/parts/abstract/gltf-game/type.d.ts +3 -0
- package/src/parts/abstract/gltf-game/unlit.wgsl +3 -2
- package/src/parts/abstract/gltf-game/view-hydrate.js +8 -1
- package/src/parts/abstract/type.d.ts +1 -0
- package/src/parts/abstract/walkable/part.json +3 -1
- package/src/parts/abstract/walkable/point-tri-that-contains.js +2 -0
- package/src/parts/abstract/walkable/type.d.ts +7 -2
- package/src/parts/core/debug/hide-debug/data-state +1 -0
- package/src/parts/core/debug/hide-debug/id +1 -0
- package/src/parts/core/debug/hide-debug/part.json +3 -0
- package/src/parts/core/debug/hide-debug/title +1 -0
- package/src/parts/core/debug/open-is_.js +1 -0
- package/src/parts/core/debug/part.html_.js +4 -0
- package/src/parts/core/debug/part.json +10 -0
- package/src/parts/core/debug/point.js +8 -0
- package/src/parts/core/debug/show-debug/data-state +1 -0
- package/src/parts/core/debug/show-debug/id +1 -0
- package/src/parts/core/debug/show-debug/part.json +3 -0
- package/src/parts/core/debug/show-debug/title +1 -0
- package/src/parts/core/debug/title +1 -0
- package/src/parts/core/debug/type.d.ts +12 -0
- package/src/parts/core/era/modern/part.css +3 -2
- package/src/parts/core/era/vintage/part.css_.js +2 -0
- package/src/parts/core/math/matrix/build.js +49 -0
- package/src/parts/core/math/matrix/chain.js +1 -0
- package/src/parts/core/math/matrix/columnMajor-from.js +15 -0
- package/src/parts/core/math/matrix/compose.js +3 -0
- package/src/parts/core/math/matrix/identity.js +6 -0
- package/src/parts/core/math/matrix/part.json +48 -0
- package/src/parts/core/math/matrix/perspective.js +8 -0
- package/src/parts/core/math/matrix/rotationQuaternion.js +11 -0
- package/src/parts/core/math/matrix/rotationX.js +8 -0
- package/src/parts/core/math/matrix/rotationY.js +8 -0
- package/src/parts/core/math/matrix/rotationZ.js +8 -0
- package/src/parts/core/math/matrix/scaling.js +6 -0
- package/src/parts/core/math/matrix/translation.js +6 -0
- package/src/parts/core/math/matrix/type.d.ts +45 -0
- package/src/parts/core/math/vector/type.d.ts +27 -26
- package/src/parts/core/sound/build.js +104 -0
- package/src/parts/core/sound/description +1 -0
- package/src/parts/core/sound/frequency-tone-to.js +1 -0
- package/src/parts/core/sound/now_.js +1 -0
- package/src/parts/core/sound/output_.js +1 -0
- package/src/parts/core/sound/part.json +14 -0
- package/src/parts/core/sound/reverb.js +15 -0
- package/src/parts/core/sound/sync-install.js +5 -0
- package/src/parts/core/sound/title +1 -0
- package/src/parts/core/sound/type.d.ts +56 -0
- package/src/parts/core/task-bar/tray/item/tray.html_.js +1 -1
- package/src/parts/core/task-bar/tray/stats/part.json +2 -1
- package/src/parts/core/windows/HTML-render-task.js +1 -1
- package/src/parts/desktop/about/part.css +159 -149
- package/src/parts/desktop/about/part.html_.js +6 -1
- package/src/parts/desktop/about/scroller/part.json +3 -0
- package/src/parts/desktop/about/scroller/precision_.js +1 -0
- package/src/parts/desktop/about/scroller/query +1 -0
- package/src/parts/desktop/about/type.d.ts +3 -0
- package/src/parts/desktop/about/update-color.js +10 -6
- package/src/parts/desktop/about/update-era.js +3 -1
package/package.json
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
C
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
doing
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
done
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
done
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Add a global debug part. Control it via a toggle in the About app. It should enable things like the debug map overlay for Orbital and position overlays for both walkable games. It should also toggle the FPS meter in the task bar tray.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
B
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
done
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Add Debug Boolean Part
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Add a sound manager which can be used to hold sound utilities and a global audio context.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
B
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
done
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Add Sound Manager
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Right now, mesh instances aren't rendered and all meshes in a GLTF file have to have their transforms applied so that they will render in the correct location in the game. This needs to be updated to fully leverage the GLTF format's potential: geometry instancing will save file space and use less memory on the GPU than having duplicate copies of the same data. This will make adding reusable props and archetecture easy and performant and will make editing the game levels in Blender easier too.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
A
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
done
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Support Instancing and Node Transforms in GLTF Game
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
Right now, only one scene (scene 0) is usable for each GLTF. This wastes the potential of having the scenes represent different levels so that a single GLTF can represent an entire game and geometry instances can be rightly shared between levels.
|
|
2
|
+
|
|
3
|
+
Also, right now, the very first walkable mesh in the mesh list is used as the sole walkable collision surface for a GLTF game. Instead, scene transitions should be used to switch between multiple walkable meshes.
|
|
4
|
+
|
|
5
|
+
Further, walkable meshes must currently have all of their transforms applied in order for collision to be in the correct position in the game. This should be changed to support transforms on collision nodes.
|
|
6
|
+
|
|
7
|
+
Also, multiple collision meshes in a single scene should be aggregated into a single collision mesh space. Take note that multiple instances of the same collision mesh might be used across multiple scenes and it might make sense and save space to incorperate the scene and transform into the game state so that there is only one runtime copy of each triangle collision mesh while at the same time there is a walkable mesh transform matrix which can be multiplied by the geometry along with the camera matrix.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
A
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
to-do
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Support Multiple Scenes and Walkable Mesh Nodes in GLTF Game
|
package/src/build.js
CHANGED
|
@@ -142,7 +142,7 @@ function ƒ(_) {
|
|
|
142
142
|
logAny(0, data, "debug")
|
|
143
143
|
}
|
|
144
144
|
function logAny(verbosity, data, method) {
|
|
145
|
-
(["error", "warn"].includes(method) || _.command !== "build") && verbosity <= _.verbosity && console[method](...(environment === "offline-server" ? ["offline-server:", ...data] : data))
|
|
145
|
+
(["error", "warn"].includes(method) || (_.command !== "build" || environment.startsWith("node-"))) && verbosity <= _.verbosity && console[method](...(environment === "offline-server" ? ["offline-server:", ...data] : data))
|
|
146
146
|
}
|
|
147
147
|
function logError(...data) {
|
|
148
148
|
logAny(0, data, "error")
|
package/src/part.css_.js
CHANGED
package/src/part.html_.js
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
thisGLTFGame.loading = true
|
|
2
2
|
|
|
3
3
|
// Create new level buffers, pipeline, bind group and render pass definitions.
|
|
4
|
-
const
|
|
4
|
+
const gltf = thisGLTFGame.levels.arm.gltf
|
|
5
5
|
|
|
6
6
|
thisGLTFGame.renderPassDefinitions.length = 0
|
|
7
7
|
|
|
8
|
-
for (const
|
|
8
|
+
for (const [meshIndex, instanceMatrices] of gltf.scenes[gltf.scene ?? 0].transformsMap) {
|
|
9
|
+
|
|
10
|
+
const mesh = gltf.meshes[meshIndex]
|
|
9
11
|
|
|
10
12
|
if (mesh.name.startsWith("walkable_"))
|
|
11
13
|
continue
|
|
@@ -161,11 +163,16 @@ for (const mesh of gltf.meshes) {
|
|
|
161
163
|
},
|
|
162
164
|
})
|
|
163
165
|
|
|
166
|
+
// ------
|
|
164
167
|
|
|
168
|
+
const instanceData = new Float32Array(instanceMatrices.length * 16)
|
|
169
|
+
instanceMatrices.forEach((m, i) => instanceData.set(m.data, i * 16))
|
|
170
|
+
const instanceBuffer = Graphics.createBuffer(instanceData, GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST)
|
|
165
171
|
thisGLTFGame.renderPassDefinitions.push({
|
|
166
172
|
vertexBuffers,
|
|
167
173
|
pipeline,
|
|
168
174
|
indexCount: indexArray.length,
|
|
175
|
+
instanceCount: instanceMatrices.length,
|
|
169
176
|
indexBuffer: Graphics.createBuffer(indexArray, GPUBufferUsage.INDEX | GPUBufferUsage.COPY_DST),
|
|
170
177
|
bindGroup: Graphics.device.createBindGroup({
|
|
171
178
|
layout: pipeline.getBindGroupLayout(0),
|
|
@@ -173,6 +180,7 @@ for (const mesh of gltf.meshes) {
|
|
|
173
180
|
{ binding: 0, resource: { buffer: thisGLTFGame.uniformBuffer } },
|
|
174
181
|
{ binding: 1, resource: gpuTexture.createView() },
|
|
175
182
|
{ binding: 2, resource: gpuSampler },
|
|
183
|
+
{ binding: 3, resource: { buffer: instanceBuffer } },
|
|
176
184
|
]
|
|
177
185
|
}),
|
|
178
186
|
indexArray
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
define(thisGLTFGame, {
|
|
2
2
|
loading: { value: false, writable: true },
|
|
3
3
|
loadedLevel: { value: null, writable: true },
|
|
4
|
+
disabledSound: { value: null, writable: true },
|
|
4
5
|
uniformBuffer: { value: null, writable: true },
|
|
5
6
|
onscreenContext: { value: null, writable: true },
|
|
6
7
|
offscreenContext: { value: null, writable: true },
|
|
@@ -1,98 +1,37 @@
|
|
|
1
|
-
const {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
a[4] * b[2] + a[5] * b[6] + a[6] * b[10] + a[7] * b[14],
|
|
24
|
-
a[4] * b[3] + a[5] * b[7] + a[6] * b[11] + a[7] * b[15],
|
|
25
|
-
|
|
26
|
-
a[8] * b[0] + a[9] * b[4] + a[10] * b[8] + a[11] * b[12],
|
|
27
|
-
a[8] * b[1] + a[9] * b[5] + a[10] * b[9] + a[11] * b[13],
|
|
28
|
-
a[8] * b[2] + a[9] * b[6] + a[10] * b[10] + a[11] * b[14],
|
|
29
|
-
a[8] * b[3] + a[9] * b[7] + a[10] * b[11] + a[11] * b[15],
|
|
30
|
-
|
|
31
|
-
a[12] * b[0] + a[13] * b[4] + a[14] * b[8] + a[15] * b[12],
|
|
32
|
-
a[12] * b[1] + a[13] * b[5] + a[14] * b[9] + a[15] * b[13],
|
|
33
|
-
a[12] * b[2] + a[13] * b[6] + a[14] * b[10] + a[15] * b[14],
|
|
34
|
-
a[12] * b[3] + a[13] * b[7] + a[14] * b[11] + a[15] * b[15],
|
|
35
|
-
]),
|
|
36
|
-
|
|
37
|
-
rx: a => [
|
|
38
|
-
1, 0, 0, 0,
|
|
39
|
-
0, cos(a), sin(a), 0,
|
|
40
|
-
0, -sin(a), cos(a), 0,
|
|
41
|
-
0, 0, 0, 1
|
|
42
|
-
],
|
|
43
|
-
|
|
44
|
-
ry: a => [
|
|
45
|
-
cos(a), 0, -sin(a), 0,
|
|
46
|
-
0, 1, 0, 0,
|
|
47
|
-
sin(a), 0, cos(a), 0,
|
|
48
|
-
0, 0, 0, 1
|
|
49
|
-
],
|
|
50
|
-
|
|
51
|
-
rz: a => [
|
|
52
|
-
cos(a), sin(a), 0, 0,
|
|
53
|
-
-sin(a), cos(a), 0, 0,
|
|
54
|
-
0, 0, 1, 0,
|
|
55
|
-
0, 0, 0, 1
|
|
56
|
-
],
|
|
57
|
-
|
|
58
|
-
t: (x, y, z) => [
|
|
59
|
-
1, 0, 0, 0,
|
|
60
|
-
0, 1, 0, 0,
|
|
61
|
-
0, 0, 1, 0,
|
|
62
|
-
x, y, z, 1
|
|
63
|
-
]
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// ── Perspective projection (WebGPU NDC depth range: 0 to 1) ───────────────────
|
|
67
|
-
const f = 1.0 / Math.tan((thisGLTFGameCamera.manifest.fov * Math.PI / 180) / 2)
|
|
68
|
-
const aspect = myGLTFGame.onscreenContext.canvas.width /
|
|
69
|
-
myGLTFGame.onscreenContext.canvas.height
|
|
70
|
-
const nf = 1 / (near - far)
|
|
71
|
-
|
|
72
|
-
const perspective = [
|
|
73
|
-
f / aspect, 0, 0, 0,
|
|
74
|
-
0, f, 0, 0,
|
|
75
|
-
0, 0, far * nf, -1,
|
|
76
|
-
0, 0, far * near * nf, 0
|
|
77
|
-
]
|
|
78
|
-
|
|
79
|
-
// ── View transform chain ──────────────────────────────────────────────────────
|
|
80
|
-
// Reading right to left: translate to player, rotate, pull back by scope.
|
|
81
|
-
// In row-vector convention the rightmost matrix is applied last (closest to P).
|
|
82
|
-
const rotation = thisGLTFGameCamera.model
|
|
83
|
-
const position = myGLTFGame.levels.arm.model
|
|
84
|
-
|
|
85
|
-
const t = matrix.t(-position.x, -thisGLTFGameCamera.manifest.height - position.y, -position.z)
|
|
86
|
-
const ry = matrix.ry(rotation.y * Math.PI / 180)
|
|
87
|
-
const rx = matrix.rx(rotation.x * Math.PI / 180)
|
|
88
|
-
const rz = matrix.rz(rotation.z * Math.PI / 180)
|
|
89
|
-
|
|
90
|
-
// Chain: t → ry → rx → rz → perspective
|
|
91
|
-
// reduceRight so leftmost matrix is outermost (applied last)
|
|
92
|
-
const viewProj = [perspective, rz, rx, ry, t]
|
|
93
|
-
.reduceRight(matrix.multiply)
|
|
1
|
+
const {
|
|
2
|
+
manifest: {
|
|
3
|
+
near,
|
|
4
|
+
far,
|
|
5
|
+
fov,
|
|
6
|
+
height
|
|
7
|
+
},
|
|
8
|
+
model: rotation,
|
|
9
|
+
[".."]: {
|
|
10
|
+
levels: {
|
|
11
|
+
arm: {
|
|
12
|
+
model: position
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
onscreenContext: {
|
|
16
|
+
canvas: {
|
|
17
|
+
width: canvasWidth,
|
|
18
|
+
height: canvasHeight
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
} = thisGLTFGameCamera
|
|
94
23
|
|
|
95
24
|
return new Float32Array([
|
|
96
|
-
|
|
97
|
-
|
|
25
|
+
|
|
26
|
+
// Perspective matrix.
|
|
27
|
+
...Matrix.chain(
|
|
28
|
+
Matrix.translation(-position.x, -height - position.y, -position.z),
|
|
29
|
+
Matrix.rotationY(rotation.y * Math.PI / 180),
|
|
30
|
+
Matrix.rotationX(rotation.x * Math.PI / 180),
|
|
31
|
+
Matrix.rotationZ(rotation.z * Math.PI / 180),
|
|
32
|
+
Matrix.perspective(fov, canvasWidth / canvasHeight, near, far)
|
|
33
|
+
).data,
|
|
34
|
+
|
|
35
|
+
// Time.
|
|
36
|
+
_.now / 1000
|
|
98
37
|
])
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
if (Debug.arm === Debug.showDebug)
|
|
2
|
+
Q(`#${thisGLTFGame.domains.join("_")}>canvas`).after((() => {
|
|
3
|
+
const offscreen = document.createElement("div")
|
|
4
|
+
offscreen.innerHTML = thisGLTFGame.levels.arm["part.html"]
|
|
5
|
+
return offscreen.querySelector("world-")
|
|
6
|
+
})())
|
|
7
|
+
|
|
8
|
+
else Q(`#${thisGLTFGame.domains.join("_")} world-`).remove()
|
|
@@ -66,6 +66,28 @@ const data = {
|
|
|
66
66
|
gltf: json
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
+
for (const scene of json.scenes) {
|
|
70
|
+
scene.transformsMap = new Map()
|
|
71
|
+
|
|
72
|
+
const gatherNodeTransforms = (nodeIndex, parentWorld) => {
|
|
73
|
+
const node = json.nodes[nodeIndex]
|
|
74
|
+
const local = node.matrix ? Matrix.fromColumnMajor(node.matrix) : Matrix.compose(node.translation, node.rotation, node.scale)
|
|
75
|
+
const world = parentWorld ? Matrix.chain(local, parentWorld) : local
|
|
76
|
+
|
|
77
|
+
if (node.mesh !== undefined) {
|
|
78
|
+
if (!scene.transformsMap.has(node.mesh))
|
|
79
|
+
scene.transformsMap.set(node.mesh, [])
|
|
80
|
+
scene.transformsMap.get(node.mesh).push(world)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
for (const child of node.children ?? [])
|
|
84
|
+
gatherNodeTransforms(child, world)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
for (const rootIndex of scene.nodes)
|
|
88
|
+
gatherNodeTransforms(rootIndex, null)
|
|
89
|
+
}
|
|
90
|
+
|
|
69
91
|
const walkableIndices = json.meshes.reduce((indices, mesh, index) => {
|
|
70
92
|
if (mesh.name.startsWith('walkable_'))
|
|
71
93
|
indices.push(index)
|
|
@@ -175,6 +175,8 @@ interface GLTFNode {
|
|
|
175
175
|
interface GLTFScene {
|
|
176
176
|
nodes: number[]
|
|
177
177
|
name?: string
|
|
178
|
+
/** A runtime property that stores the array of node transforms around each mesh in the scene. */
|
|
179
|
+
transformsMap: Map<number, IMatrix4[]>
|
|
178
180
|
}
|
|
179
181
|
|
|
180
182
|
// ── Root glTF document ────────────────────────────────────────────────────────
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
return /* html */`<canvas id="onscreen-canvas">
|
|
2
2
|
Your browser does not support the HTML canvas tag.
|
|
3
3
|
</canvas>
|
|
4
|
-
${
|
|
4
|
+
${Debug.arm === Debug.showDebug ? thisGLTFGame.levels.arm["part.html"] : ""}
|
|
5
5
|
<section id=hud>${thisGLTFGame["hud.html"]}</section>
|
|
6
6
|
<section id=pause-menu>${thisGLTFGame["pause-menu.html"]}</section>`
|
|
@@ -30,7 +30,7 @@ for (const renderPassDefinition of thisGLTFGame.renderPassDefinitions) {
|
|
|
30
30
|
pass.setBindGroup(0, renderPassDefinition.bindGroup)
|
|
31
31
|
pass.setIndexBuffer(renderPassDefinition.indexBuffer, renderPassDefinition.indexArray instanceof Uint32Array ? 'uint32' : 'uint16')
|
|
32
32
|
renderPassDefinition.vertexBuffers.forEach((buffer, index) => pass.setVertexBuffer(index, buffer))
|
|
33
|
-
pass.drawIndexed(renderPassDefinition.indexCount)
|
|
33
|
+
pass.drawIndexed(renderPassDefinition.indexCount, renderPassDefinition.instanceCount)
|
|
34
34
|
}
|
|
35
35
|
pass.end()
|
|
36
36
|
Graphics.device.queue.submit([encoder.finish()])
|
|
@@ -50,6 +50,8 @@ declare interface IGLTFGame<TOwner>
|
|
|
50
50
|
readonly currentTurnSpeed: number
|
|
51
51
|
readonly canvasSizeChanged: boolean
|
|
52
52
|
readonly renderPassDefinitions: GPURenderPassDefinition[]
|
|
53
|
+
/** The sound that plays when the player uses the action button with no interactive object in focus. */
|
|
54
|
+
readonly disabledSound?: SoundWave
|
|
53
55
|
}
|
|
54
56
|
|
|
55
57
|
declare interface IGLTFGameManifest
|
|
@@ -67,6 +69,7 @@ declare interface IGLTFGameManifest
|
|
|
67
69
|
|
|
68
70
|
declare interface GPURenderPassDefinition {
|
|
69
71
|
readonly indexCount: number
|
|
72
|
+
readonly instanceCount: number
|
|
70
73
|
readonly vertexBuffers: [
|
|
71
74
|
slot: GPUIndex32,
|
|
72
75
|
buffer:
|
|
@@ -6,15 +6,16 @@ struct Camera {
|
|
|
6
6
|
@group(0) @binding(0) var<uniform> camera : Camera;
|
|
7
7
|
@group(0) @binding(1) var t_diffuse: texture_2d<f32>;
|
|
8
8
|
@group(0) @binding(2) var s_diffuse: sampler;
|
|
9
|
+
@group(0) @binding(3) var<storage, read> instances: array<mat4x4<f32>>;
|
|
9
10
|
|
|
10
11
|
struct VertexOutput {
|
|
11
12
|
@builtin(position) position: vec4<f32>,
|
|
12
13
|
@location(0) uv: vec2<f32>,
|
|
13
14
|
};
|
|
14
15
|
|
|
15
|
-
@vertex fn v({$0}) -> VertexOutput {
|
|
16
|
+
@vertex fn v({$0}, @builtin(instance_index) instanceIndex: u32) -> VertexOutput {
|
|
16
17
|
var out: VertexOutput;
|
|
17
|
-
out.position = camera.projection * vec4<f32>(POSITION, 1.0);
|
|
18
|
+
out.position = camera.projection * (instances[instanceIndex] * vec4<f32>(POSITION, 1.0));
|
|
18
19
|
out.uv = TEXCOORD_0;
|
|
19
20
|
return out;
|
|
20
21
|
}
|
|
@@ -39,4 +39,11 @@ document.addEventListener('pointerlockchange', reactivePause)
|
|
|
39
39
|
document.addEventListener('pointerlockerror', reactivePause)
|
|
40
40
|
document.addEventListener('visibilitychange', reactivePause)
|
|
41
41
|
window.addEventListener('blur', reactivePause)
|
|
42
|
-
window.addEventListener('focus', reactivePause)
|
|
42
|
+
window.addEventListener('focus', reactivePause)
|
|
43
|
+
|
|
44
|
+
Debug.attach("update", thisGLTFGame, "toggleDebug")
|
|
45
|
+
|
|
46
|
+
thisGLTFGame.disabledSound = new Sound.Wave()
|
|
47
|
+
thisGLTFGame.disabledSound.duration = 0.125
|
|
48
|
+
thisGLTFGame.disabledSound.tone = 40
|
|
49
|
+
thisGLTFGame.disabledSound.type = "sawtooth"
|
|
@@ -9,6 +9,7 @@ declare interface IAbstract
|
|
|
9
9
|
readonly comingSoon: IComingSoonApp<IAbstract>
|
|
10
10
|
readonly error: IErrorApp<IAbstract>
|
|
11
11
|
readonly facet: IFacet<IAbstract, null>
|
|
12
|
+
readonly gltfGame: IGLTFGame<IAbstract>
|
|
12
13
|
readonly issue: ITrackedIssue<IAbstract>
|
|
13
14
|
readonly match: IMatch<IAbstract, null>
|
|
14
15
|
readonly walkable: IWalkable<IAbstract>
|
|
@@ -7,4 +7,6 @@ for (let triIndex = 0; triIndex < thisWalkable.triTable.length; triIndex++)
|
|
|
7
7
|
if (triIndex !== thisWalkable.triIndex && thisWalkable.triContainsPoint(triIndex, POINT))
|
|
8
8
|
return triIndex
|
|
9
9
|
|
|
10
|
+
// Among all triangles at the candidate XZ point, sorted by ascending surfaceY, select the one with the highest surfaceY that satisfies surfaceY ≤ PLAYER_REFERENCE_Y + climbThreshold.
|
|
11
|
+
|
|
10
12
|
return -1
|
|
@@ -3,8 +3,13 @@ declare interface IWalkable<TOwner>
|
|
|
3
3
|
|
|
4
4
|
// Components.
|
|
5
5
|
readonly getData(): IWalkableData
|
|
6
|
-
/** Casts a ray from the current walkable position along the force vector direction for the given delta time and returns a summary of the results.
|
|
7
|
-
|
|
6
|
+
/** Casts a ray from the current walkable position along the force vector direction for the given delta time and returns a summary of the results.
|
|
7
|
+
* @param FORCE_VECTOR the force vector represent the position the uninterrupted ray will arrive at in one second.
|
|
8
|
+
* @param DELTA_TIME the duration of the time cast in seconds.
|
|
9
|
+
* @param ENABLE_SLIDING if true, the ray will "wrap" along a boundary instead of stopping cold.
|
|
10
|
+
* @param GRAVITY if defined, the ray will not be snapped to the Y-position of the walkable surface but will accelerate downward toward it at the given rate (in Y units per second).
|
|
11
|
+
* @param MAX_CLIMB if defined, ray casts which land on a triangle whose Y-position is higher than the start position will be considered boundary walls unless they are less than this number. */
|
|
12
|
+
readonly castRay(FORCE_VECTOR: Vector3, DELTA_TIME: number, ENABLE_SLIDING: boolean, GRAVITY: number, MAX_CLIMB: number): IWalkableRayCastResult
|
|
8
13
|
/** Checks if a point (x, y, z) rounds to a valid pixel within the specified tri's memoized row data. */
|
|
9
14
|
readonly triContainsPoint(TRI_INDEX: IWalkableTriIndex, POINT: Vector3): boolean
|
|
10
15
|
/** Returns whether or not the given point is in a tri. @returns the index of the tri that contains the point. -1 otherwise. */
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
disabled
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
debug-control
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Hide
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
return true
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
enabled
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
debug-control
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Show
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Debug Views
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
declare interface IDebug
|
|
2
|
+
extends IMatch<IDesktop, IBodyMode<IEra>>,
|
|
3
|
+
IWebView {
|
|
4
|
+
|
|
5
|
+
// Subparts.
|
|
6
|
+
readonly hideDebug: IBodyMode<IDebug>
|
|
7
|
+
readonly showDebug: IBodyMode<IDebug>
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/** Toggles helper views for developers. */
|
|
11
|
+
declare const Debug: IDebug
|
|
12
|
+
type Debug = T
|