matrix-engine-wgpu 1.3.13 → 1.3.17

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.
@@ -1,307 +0,0 @@
1
- /**
2
- * @description
3
- * Created for matrix-engine-wgpu project.
4
- * MeshObj class estends Materials.
5
- * @author Nikola Lukic
6
- * @email zlatnaspirala@gmail.com
7
- */
8
-
9
- export default class Materials {
10
- constructor(device) {
11
- this.device = device;
12
- this.isVideo = false;
13
- // For shadow comparison
14
- this.compareSampler = this.device.createSampler({compare: 'less'});
15
- // For image textures (standard sampler)
16
- this.imageSampler = this.device.createSampler({
17
- magFilter: 'linear',
18
- minFilter: 'linear',
19
- });
20
- // For external video textures (needs to be filtering sampler too!)
21
- this.videoSampler = this.device.createSampler({
22
- magFilter: 'linear',
23
- minFilter: 'linear',
24
- });
25
-
26
- // FX effect
27
- this.postFXModeBuffer = this.device.createBuffer({
28
- size: 4, // u32 = 4 bytes
29
- usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
30
- });
31
-
32
- // Dymmy buffer
33
- this.dummySpotlightUniformBuffer = this.device.createBuffer({
34
- size: 64, // Must match size in shader
35
- usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
36
- });
37
- this.device.queue.writeBuffer(this.dummySpotlightUniformBuffer, 0, new Float32Array(16));
38
-
39
- }
40
-
41
- updatePostFXMode(mode) {
42
- const arrayBuffer = new Uint32Array([mode]);
43
- this.device.queue.writeBuffer(this.postFXModeBuffer, 0, arrayBuffer);
44
- }
45
-
46
- async loadTex0(texturesPaths) {
47
- this.sampler = this.device.createSampler({
48
- magFilter: 'linear',
49
- minFilter: 'linear',
50
- });
51
- return new Promise(async (resolve) => {
52
- const response = await fetch(texturesPaths[0]);
53
- const imageBitmap = await createImageBitmap(await response.blob());
54
- this.texture0 = this.device.createTexture({
55
- size: [imageBitmap.width, imageBitmap.height, 1], // REMOVED 1
56
- format: 'rgba8unorm',
57
- usage:
58
- GPUTextureUsage.TEXTURE_BINDING |
59
- GPUTextureUsage.COPY_DST |
60
- GPUTextureUsage.RENDER_ATTACHMENT,
61
- });
62
- this.device.queue.copyExternalImageToTexture(
63
- {source: imageBitmap},
64
- {texture: this.texture0},
65
- [imageBitmap.width, imageBitmap.height]
66
- );
67
- resolve()
68
- })
69
- }
70
-
71
- async loadVideoTexture(arg) {
72
- this.isVideo = true;
73
- if(arg.type === 'video') {
74
- this.video = document.createElement('video');
75
- this.video.src = arg.src || 'res/videos/tunel.mp4';
76
- this.video.crossOrigin = 'anonymous';
77
- this.video.autoplay = true;
78
- this.video.loop = true;
79
- document.body.append(this.video);
80
- this.video.style.display = 'none';
81
- await this.video.play();
82
- } else if(arg.type === 'videoElement') {
83
- this.video = arg.el;
84
- await this.video.play();
85
- } else if(arg.type === 'camera') {
86
- this.video = document.createElement('video');
87
- this.video.autoplay = true;
88
- this.video.muted = true;
89
- this.video.playsInline = true;
90
- this.video.style.display = 'none';
91
- document.body.append(this.video);
92
-
93
- try {
94
- const stream = await (navigator.mediaDevices?.getUserMedia?.({
95
- video: {
96
- width: {ideal: 1280},
97
- height: {ideal: 720},
98
- },
99
- audio: false
100
- }));
101
-
102
- this.video.srcObject = stream;
103
- await this.video.play();
104
- } catch(err) {
105
- console.error("❌ Failed to access camera:", err);
106
- return;
107
- }
108
- } else if(arg.type === 'canvas2d') {
109
- // Existing canvas (arg.el) — assume it's actively drawing
110
- this.video = document.createElement('video');
111
- this.video.autoplay = true;
112
- this.video.muted = true;
113
- this.video.playsInline = true;
114
- this.video.style.display = 'none';
115
- document.body.append(this.video);
116
-
117
- // Create stream from existing canvas
118
- const stream = arg.el.captureStream?.() || arg.el.mozCaptureStream?.();
119
- if(!stream) {
120
- console.error('❌ Cannot capture stream from canvas2d');
121
- return;
122
- }
123
-
124
- this.video.srcObject = stream;
125
- await this.video.play();
126
-
127
- } else if(arg.type === 'canvas2d-inline') {
128
- // Miniature inline-drawn canvas created dynamically
129
- const canvas = document.createElement('canvas');
130
- canvas.width = arg.width || 256;
131
- canvas.height = arg.height || 256;
132
- const ctx = canvas.getContext('2d');
133
-
134
- if(typeof arg.canvaInlineProgram === 'function') {
135
- // Start drawing loop
136
- const drawLoop = () => {
137
- arg.canvaInlineProgram(ctx, canvas);
138
- requestAnimationFrame(drawLoop);
139
- };
140
- drawLoop();
141
- }
142
-
143
- this.video = document.createElement('video');
144
- this.video.autoplay = true;
145
- this.video.muted = true;
146
- this.video.playsInline = true;
147
- this.video.style.display = 'none';
148
- document.body.append(this.video);
149
-
150
- const stream = canvas.captureStream?.() || canvas.mozCaptureStream?.();
151
- if(!stream) {
152
- console.error('❌ Cannot capture stream from inline canvas');
153
- return;
154
- }
155
-
156
- this.video.srcObject = stream;
157
- await this.video.play();
158
- }
159
-
160
- this.sampler = this.device.createSampler({
161
- magFilter: 'linear',
162
- minFilter: 'linear',
163
- });
164
-
165
- // ✅ Now
166
- // includes externalTexture type
167
- this.createLayoutForRender();
168
- this.setupPipeline();
169
- setTimeout(() => this.createBindGroupForRender(), 1500);
170
- }
171
-
172
- updateVideoTexture() {
173
- if(!this.video || this.video.readyState < 2) return;
174
- this.externalTexture = this.device.importExternalTexture({source: this.video});
175
- this.createBindGroupForRender();
176
- }
177
-
178
- createBindGroupForRender() {
179
- const textureResource = this.isVideo
180
- ? this.externalTexture // must be set via updateVideoTexture
181
- : this.texture0.createView();
182
- // Log all bindings to debug
183
- if(!textureResource || !this.sceneUniformBuffer || !this.shadowDepthTextureView || !this.sampler) {
184
- console.warn("❗Missing res skipping...");
185
- return;
186
- }
187
-
188
- if(this.isVideo == true) {
189
- this.sceneBindGroupForRender = this.device.createBindGroup({
190
- layout: this.bglForRender,
191
- entries: [
192
- {
193
- binding: 0,
194
- resource: {buffer: this.sceneUniformBuffer},
195
- },
196
- {
197
- binding: 1,
198
- resource: this.shadowDepthTextureView,
199
- },
200
- {
201
- binding: 2,
202
- resource: this.compareSampler,
203
- },
204
- {
205
- binding: 3,
206
- resource: textureResource,
207
- },
208
- {
209
- binding: 4,
210
- resource: this.videoSampler,
211
- },
212
- {binding: 5, resource: {buffer: this.postFXModeBuffer}}
213
- ],
214
- });
215
- } else {
216
- this.sceneBindGroupForRender = this.device.createBindGroup({
217
- layout: this.bglForRender,
218
- entries: [
219
- {
220
- binding: 0,
221
- resource: {buffer: this.sceneUniformBuffer},
222
- },
223
- {
224
- binding: 1,
225
- resource: this.shadowDepthTextureView,
226
- },
227
- {
228
- binding: 2,
229
- resource: this.compareSampler,
230
- },
231
- {
232
- binding: 3,
233
- resource: textureResource,
234
- },
235
- {
236
- binding: 4,
237
- resource: this.imageSampler,
238
- },
239
- {
240
- binding: 5,
241
- resource: {buffer: this.lightContainer.length == 0 ? this.dummySpotlightUniformBuffer : this.lightContainer[0].spotlightUniformBuffer},
242
- },
243
- ],
244
- });
245
- }
246
- }
247
-
248
- createLayoutForRender() {
249
- this.bglForRender = this.device.createBindGroupLayout({
250
- entries: [
251
- {
252
- binding: 0,
253
- visibility: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT,
254
- buffer: {type: 'uniform'},
255
- },
256
- {
257
- binding: 1,
258
- visibility: GPUShaderStage.FRAGMENT,
259
- texture: {sampleType: 'depth'},
260
- },
261
- {
262
- binding: 2,
263
- visibility: GPUShaderStage.FRAGMENT,
264
- sampler: {type: 'comparison'},
265
- },
266
- ...(this.isVideo
267
- ? [ // VIDEO
268
- {
269
- binding: 3,
270
- visibility: GPUShaderStage.FRAGMENT,
271
- externalTexture: {},
272
- },
273
- {
274
- binding: 4,
275
- visibility: GPUShaderStage.FRAGMENT,
276
- sampler: {type: 'filtering'}, // for video sampling
277
- },
278
- {
279
- binding: 5,
280
- visibility: GPUShaderStage.FRAGMENT,
281
- buffer: {type: 'uniform'},
282
- }
283
- ]
284
- : [ // IMAGE
285
- {
286
- binding: 3,
287
- visibility: GPUShaderStage.FRAGMENT,
288
- texture: {
289
- sampleType: 'float',
290
- viewDimension: '2d',
291
- },
292
- },
293
- {
294
- binding: 4,
295
- visibility: GPUShaderStage.FRAGMENT,
296
- sampler: {type: 'filtering'},
297
- },
298
- {
299
- binding: 5,
300
- visibility: GPUShaderStage.FRAGMENT,
301
- buffer: {type: 'uniform'},
302
- }
303
- ])
304
- ],
305
- });
306
- }
307
- }
@@ -1,252 +0,0 @@
1
- import {degToRad, radToDeg} from "./utils";
2
-
3
- /**
4
- * @description
5
- * Sub classes for matrix-wgpu
6
- * Base class
7
- * Position { x, y, z }
8
- */
9
-
10
- export class Position {
11
- constructor(x, y, z) {
12
- // console.log('TEST TYTPOF ', x)
13
- // Not in use for nwo this is from matrix-engine project [nameUniq]
14
- this.nameUniq = null;
15
-
16
- if(typeof x == 'undefined') x = 0;
17
- if(typeof y == 'undefined') y = 0;
18
- if(typeof z == 'undefined') z = 0;
19
-
20
- this.x = parseFloat(x);
21
- this.y = parseFloat(y);
22
- this.z = parseFloat(z);
23
-
24
- this.velY = 0;
25
- this.velX = 0;
26
- this.velZ = 0;
27
- this.inMove = false;
28
- this.targetX = parseFloat(x);
29
- this.targetY = parseFloat(y);
30
- this.targetZ = parseFloat(z);
31
- this.thrust = 0.01;
32
-
33
- return this;
34
- }
35
-
36
- setSpeed(n) {
37
- if(typeof n === 'number') {
38
- this.thrust = n;
39
- } else {
40
- console.log('Description: arguments (w, h) must be type of number.');
41
- }
42
- }
43
-
44
- translateByX(x) {
45
- this.inMove = true;
46
- this.targetX = parseFloat(x);
47
- };
48
-
49
- translateByY(y) {
50
- this.inMove = true;
51
- this.targetY = parseFloat(y);
52
- }
53
-
54
- translateByZ(z) {
55
- this.inMove = true;
56
- this.targetZ = parseFloat(z);
57
- }
58
-
59
- translateByXY(x, y) {
60
- this.inMove = true;
61
- this.targetX = parseFloat(x);
62
- this.targetY = parseFloat(y);
63
- }
64
-
65
- translateByXZ(x, z) {
66
- this.inMove = true;
67
- this.targetX = parseFloat(x);
68
- this.targetZ = parseFloat(z);
69
- }
70
-
71
- translateByYZ(y, z) {
72
- this.inMove = true;
73
- this.targetY = parseFloat(y);
74
- this.targetZ = parseFloat(z);
75
- }
76
-
77
- onTargetPositionReach() {}
78
-
79
- update() {
80
- var tx = parseFloat(this.targetX) - parseFloat(this.x),
81
- ty = parseFloat(this.targetY) - parseFloat(this.y),
82
- tz = parseFloat(this.targetZ) - parseFloat(this.z),
83
- dist = Math.sqrt(tx * tx + ty * ty + tz * tz);
84
- this.velX = (tx / dist) * this.thrust;
85
- this.velY = (ty / dist) * this.thrust;
86
- this.velZ = (tz / dist) * this.thrust;
87
- if(this.inMove == true) {
88
- if(dist > this.thrust) {
89
- this.x += this.velX;
90
- this.y += this.velY;
91
- this.z += this.velZ;
92
-
93
- // // from me
94
- // if(net && net.connection && typeof em === 'undefined' && App.scene[this.nameUniq].net.enable == true) net.connection.send({
95
- // netPos: {x: this.x, y: this.y, z: this.z},
96
- // netObjId: this.nameUniq,
97
- // });
98
-
99
- } else {
100
- this.x = this.targetX;
101
- this.y = this.targetY;
102
- this.z = this.targetZ;
103
- this.inMove = false;
104
- this.onTargetPositionReach();
105
-
106
- // // from me
107
- // if(net && net.connection && typeof em === 'undefined' && App.scene[this.nameUniq].net.enable == true) net.connection.send({
108
- // netPos: {x: this.x, y: this.y, z: this.z},
109
- // netObjId: this.nameUniq,
110
- // });
111
- }
112
- }
113
- }
114
-
115
- get worldLocation() {
116
- return [parseFloat(this.x), parseFloat(this.y), parseFloat(this.z)];
117
- }
118
-
119
- SetX(newx, em) {
120
- this.x = newx;
121
- this.targetX = newx;
122
- this.inMove = false;
123
-
124
- // if(net && net.connection && typeof em === 'undefined' &&
125
- // App.scene[this.nameUniq].net && App.scene[this.nameUniq].net.enable == true) {
126
- // net.connection.send({
127
- // netPos: {x: this.x, y: this.y, z: this.z},
128
- // netObjId: this.nameUniq,
129
- // });
130
- // }
131
- }
132
-
133
- SetY(newy, em) {
134
- this.y = newy;
135
- this.targetY = newy;
136
- this.inMove = false;
137
- // if(net && net.connection && typeof em === 'undefined' &&
138
- // App.scene[this.nameUniq].net && App.scene[this.nameUniq].net.enable == true) net.connection.send({
139
- // netPos: {x: this.x, y: this.y, z: this.z},
140
- // netObjId: this.nameUniq,
141
- // });
142
- }
143
-
144
- SetZ(newz, em) {
145
- this.z = newz;
146
- this.targetZ = newz;
147
- this.inMove = false;
148
- // if(net && net.connection && typeof em === 'undefined' &&
149
- // App.scene[this.nameUniq].net && App.scene[this.nameUniq].net.enable == true) net.connection.send({
150
- // netPos: {x: this.x, y: this.y, z: this.z},
151
- // netObjId: this.nameUniq,
152
- // });
153
- }
154
-
155
- get X() {
156
- return parseFloat(this.x)
157
- }
158
-
159
- get Y() {
160
- return parseFloat(this.y)
161
- }
162
-
163
- get Z() {
164
- return parseFloat(this.z)
165
- }
166
-
167
- setPosition(newx, newy, newz) {
168
- this.x = newx;
169
- this.y = newy;
170
- this.z = newz;
171
- this.targetX = newx;
172
- this.targetY = newy;
173
- this.targetZ = newz;
174
- this.inMove = false;
175
-
176
- // from me
177
- // if(App.scene[this.nameUniq] && net && net.connection && typeof em === 'undefined' &&
178
- // App.scene[this.nameUniq].net && App.scene[this.nameUniq].net.enable == true) net.connection.send({
179
- // netPos: {x: this.x, y: this.y, z: this.z},
180
- // netObjId: this.nameUniq,
181
- // });
182
- }
183
- }
184
-
185
- export class Rotation {
186
-
187
- constructor(x, y, z) {
188
- // Not in use for nwo this is from matrix-engine project [nameUniq]
189
- this.nameUniq = null;
190
- if(typeof x == 'undefined') x = 0;
191
- if(typeof y == 'undefined') y = 0;
192
- if(typeof z == 'undefined') z = 0;
193
- this.x = x;
194
- this.y = y;
195
- this.z = z;
196
- this.rotationSpeed = {x: 0, y: 0, z: 0};
197
- this.angle = 0;
198
- this.axis = {x: 0, y: 0, z: 0};
199
- // not in use good for exstend logic
200
- this.matrixRotation = null;
201
- }
202
-
203
- toDegree() {
204
-
205
- /*
206
- heading = atan2(y * sin(angle)- x * z * (1 - cos(angle)) , 1 - (y2 + z2 ) * (1 - cos(angle)))
207
- attitude = asin(x * y * (1 - cos(angle)) + z * sin(angle))
208
- bank = atan2(x * sin(angle)-y * z * (1 - cos(angle)) , 1 - (x2 + z2) * (1 - cos(angle)))
209
- */
210
- return [radToDeg(this.axis.x), radToDeg(this.axis.y), radToDeg(this.axis.z)];
211
- }
212
-
213
- toDegreeX() {
214
- return Math.cos(radToDeg(this.axis.x) / 2)
215
- }
216
-
217
- toDegreeY() {
218
- return Math.cos(radToDeg(this.axis.z) / 2)
219
- }
220
-
221
- toDegreeZ() {
222
- return Math.cos(radToDeg(this.axis.y) / 2)
223
- }
224
-
225
- getRotX() {
226
- if(this.rotationSpeed.x == 0) {
227
- return degToRad(this.x);
228
- } else {
229
- this.x = this.x + this.rotationSpeed.x * 0.001;
230
- return degToRad(this.x);
231
- }
232
- }
233
-
234
- getRotY() {
235
- if(this.rotationSpeed.y == 0) {
236
- return degToRad(this.y);
237
- } else {
238
- this.y = this.y + this.rotationSpeed.y * 0.001;
239
- return degToRad(this.y);
240
- }
241
- }
242
-
243
- getRotZ() {
244
- if(this.rotationSpeed.z == 0) {
245
- return degToRad(this.z);
246
- } else {
247
- this.z = this.z + this.rotationSpeed.z * 0.001;
248
- return degToRad(this.z);
249
- }
250
- }
251
-
252
- }