matrix-engine-wgpu 1.3.11 → 1.3.12
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/readme.md +23 -10
- package/src/engine/materials.js +73 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "matrix-engine-wgpu",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.12",
|
|
4
4
|
"description": "obj sequence anim +HOTFIX raycast, webGPU powered pwa application. Crazy fast rendering with AmmoJS physics support. Simple raycaster hit object added.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"files": [
|
package/readme.md
CHANGED
|
@@ -132,7 +132,7 @@ app.mainRenderBundle[0].rotation.rotationSpeed.y = 0;
|
|
|
132
132
|
|
|
133
133
|
---
|
|
134
134
|
|
|
135
|
-
### Camera Example
|
|
135
|
+
### 3D Camera Example
|
|
136
136
|
|
|
137
137
|
Manipulate WASD camera:
|
|
138
138
|
|
|
@@ -265,7 +265,7 @@ window.app = application;
|
|
|
265
265
|
|
|
266
266
|
This example shows how to load and animate a sequence of .obj files to simulate mesh-based animation (e.g. walking character).
|
|
267
267
|
|
|
268
|
-
|
|
268
|
+
```js
|
|
269
269
|
import MatrixEngineWGPU from "../src/world.js";
|
|
270
270
|
import { downloadMeshes, makeObjSeqArg } from "../src/engine/loader-obj.js";
|
|
271
271
|
import { LOG_MATRIX } from "../src/engine/utils.js";
|
|
@@ -327,18 +327,31 @@ export var loadObjsSequence = function () {
|
|
|
327
327
|
|
|
328
328
|
window.app = loadObjFile;
|
|
329
329
|
};
|
|
330
|
+
```
|
|
330
331
|
|
|
331
|
-
### 📽️
|
|
332
|
+
### 📽️ Video textures
|
|
332
333
|
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
334
|
+
```js
|
|
335
|
+
TEST.loadVideoTexture({
|
|
336
|
+
type: 'video', // video , camera //not tested yet canvas2d , canvas2dinline
|
|
337
|
+
src: 'res/videos/tunel.mp4'
|
|
338
|
+
});
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
<pre>
|
|
342
|
+
| Scenario | Best Approach |
|
|
343
|
+
| ------------------------------ | ---------------------------------- |
|
|
344
|
+
| Dynamic 2D canvas animation | `canvas.captureStream()` → `video` |
|
|
345
|
+
| Static canvas snapshot | `createImageBitmap(canvas)` |
|
|
346
|
+
| Replaying real video or webcam | Direct `video` element |
|
|
347
|
+
</pre>
|
|
338
348
|
|
|
339
|
-
|
|
349
|
+
### Note
|
|
350
|
+
If this happen less then 15 times (Loading procces) then it is ok probably...
|
|
340
351
|
|
|
341
|
-
|
|
352
|
+
```json
|
|
353
|
+
Draw func (err):TypeError: Failed to execute 'beginRenderPass' on 'GPUCommandEncoder': The provided value is not of type 'GPURenderPassDescriptor'.
|
|
354
|
+
```
|
|
342
355
|
|
|
343
356
|
## About URLParams
|
|
344
357
|
|
package/src/engine/materials.js
CHANGED
|
@@ -63,6 +63,79 @@ export default class Materials {
|
|
|
63
63
|
} else if(arg.type === 'videoElement') {
|
|
64
64
|
this.video = arg.el;
|
|
65
65
|
await this.video.play();
|
|
66
|
+
} else if(arg.type === 'camera') {
|
|
67
|
+
this.video = document.createElement('video');
|
|
68
|
+
this.video.autoplay = true;
|
|
69
|
+
this.video.muted = true;
|
|
70
|
+
this.video.playsInline = true;
|
|
71
|
+
this.video.style.display = 'none';
|
|
72
|
+
document.body.append(this.video);
|
|
73
|
+
|
|
74
|
+
try {
|
|
75
|
+
const stream = await (navigator.mediaDevices?.getUserMedia?.({
|
|
76
|
+
video: {
|
|
77
|
+
width: {ideal: 1280},
|
|
78
|
+
height: {ideal: 720},
|
|
79
|
+
},
|
|
80
|
+
audio: false
|
|
81
|
+
}));
|
|
82
|
+
|
|
83
|
+
this.video.srcObject = stream;
|
|
84
|
+
await this.video.play();
|
|
85
|
+
} catch(err) {
|
|
86
|
+
console.error("❌ Failed to access camera:", err);
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
} else if(arg.type === 'canvas2d') {
|
|
90
|
+
// Existing canvas (arg.el) — assume it's actively drawing
|
|
91
|
+
this.video = document.createElement('video');
|
|
92
|
+
this.video.autoplay = true;
|
|
93
|
+
this.video.muted = true;
|
|
94
|
+
this.video.playsInline = true;
|
|
95
|
+
this.video.style.display = 'none';
|
|
96
|
+
document.body.append(this.video);
|
|
97
|
+
|
|
98
|
+
// Create stream from existing canvas
|
|
99
|
+
const stream = arg.el.captureStream?.() || arg.el.mozCaptureStream?.();
|
|
100
|
+
if(!stream) {
|
|
101
|
+
console.error('❌ Cannot capture stream from canvas2d');
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
this.video.srcObject = stream;
|
|
106
|
+
await this.video.play();
|
|
107
|
+
|
|
108
|
+
} else if(arg.type === 'canvas2d-inline') {
|
|
109
|
+
// Miniature inline-drawn canvas created dynamically
|
|
110
|
+
const canvas = document.createElement('canvas');
|
|
111
|
+
canvas.width = arg.width || 256;
|
|
112
|
+
canvas.height = arg.height || 256;
|
|
113
|
+
const ctx = canvas.getContext('2d');
|
|
114
|
+
|
|
115
|
+
if(typeof arg.canvaInlineProgram === 'function') {
|
|
116
|
+
// Start drawing loop
|
|
117
|
+
const drawLoop = () => {
|
|
118
|
+
arg.canvaInlineProgram(ctx, canvas);
|
|
119
|
+
requestAnimationFrame(drawLoop);
|
|
120
|
+
};
|
|
121
|
+
drawLoop();
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
this.video = document.createElement('video');
|
|
125
|
+
this.video.autoplay = true;
|
|
126
|
+
this.video.muted = true;
|
|
127
|
+
this.video.playsInline = true;
|
|
128
|
+
this.video.style.display = 'none';
|
|
129
|
+
document.body.append(this.video);
|
|
130
|
+
|
|
131
|
+
const stream = canvas.captureStream?.() || canvas.mozCaptureStream?.();
|
|
132
|
+
if(!stream) {
|
|
133
|
+
console.error('❌ Cannot capture stream from inline canvas');
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
this.video.srcObject = stream;
|
|
138
|
+
await this.video.play();
|
|
66
139
|
}
|
|
67
140
|
|
|
68
141
|
this.sampler = this.device.createSampler({
|