matrix-engine-wgpu 1.2.0 → 1.2.2
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/examples/games/jamb/html-content.js +25 -20
- package/examples/games/jamb/jamb.js +107 -53
- package/examples/games/jamb/readme.md +3 -0
- package/index.js +2 -2
- package/main.js +162 -40
- package/package.json +1 -1
- package/public/app.js +384 -120
- package/public/css/style.css +32 -13
- package/public/empty.js +10140 -9865
- package/public/examples.js +271 -97
- package/public/res/audios/dice-roll.mp3 +0 -0
- package/public/res/multilang/en.json +7 -2
- package/public/res/multilang/sr.json +7 -1
- package/readme.md +2 -0
- package/src/engine/utils.js +94 -7
package/main.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import MatrixEngineWGPU from "./src/world.js";
|
|
2
2
|
import {downloadMeshes} from './src/engine/loader-obj.js';
|
|
3
|
-
import {LOG_FUNNY, LOG_INFO, LOG_MATRIX, mb, randomFloatFromTo, randomIntFromTo} from "./src/engine/utils.js";
|
|
3
|
+
import {byId, LOG_FUNNY, LOG_INFO, LOG_MATRIX, mb, randomFloatFromTo, randomIntFromTo} from "./src/engine/utils.js";
|
|
4
4
|
import {dices, myDom} from "./examples/games/jamb/jamb.js";
|
|
5
5
|
import {addRaycastListener, touchCoordinate, rayIntersectsSphere, getRayFromMouse} from "./src/engine/raycast.js";
|
|
6
6
|
|
|
@@ -19,9 +19,58 @@ export let application = new MatrixEngineWGPU({
|
|
|
19
19
|
};
|
|
20
20
|
application.myDom = myDom;
|
|
21
21
|
myDom.createJamb();
|
|
22
|
+
myDom.addDraggerForTable();
|
|
22
23
|
myDom.createBlocker();
|
|
23
24
|
application.dices = dices;
|
|
24
25
|
|
|
26
|
+
|
|
27
|
+
application.activateDiceClickListener = null;
|
|
28
|
+
|
|
29
|
+
// -------------------------
|
|
30
|
+
// TEST
|
|
31
|
+
application.matrixAmmo.detectTopFaceFromQuat = (q) => {
|
|
32
|
+
// Define based on *visual face* → object-space normal mapping
|
|
33
|
+
const faces = [
|
|
34
|
+
{face: 1, vec: [0, 1, 0]}, // top
|
|
35
|
+
{face: 2, vec: [0, -1, 0]}, // bottom
|
|
36
|
+
{face: 3, vec: [0, 0, 1]}, // front
|
|
37
|
+
{face: 4, vec: [0, 0, -1]}, // back
|
|
38
|
+
{face: 5, vec: [1, 0, 0]}, // right
|
|
39
|
+
{face: 6, vec: [-1, 0, 0]} // left
|
|
40
|
+
];
|
|
41
|
+
|
|
42
|
+
let maxDot = -Infinity;
|
|
43
|
+
let topFace = null;
|
|
44
|
+
|
|
45
|
+
for(const f of faces) {
|
|
46
|
+
const v = application.matrixAmmo.applyQuatToVec(q, f.vec);
|
|
47
|
+
const dot = v.y; // Compare with world up (0, 1, 0)
|
|
48
|
+
if(dot > maxDot) {
|
|
49
|
+
maxDot = dot;
|
|
50
|
+
topFace = f.face;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return topFace;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
application.matrixAmmo.applyQuatToVec = (q, vec) => {
|
|
58
|
+
const [x, y, z] = vec;
|
|
59
|
+
const qx = q.x(), qy = q.y(), qz = q.z(), qw = q.w();
|
|
60
|
+
|
|
61
|
+
// Quaternion * vector * inverse(quaternion)
|
|
62
|
+
const ix = qw * x + qy * z - qz * y;
|
|
63
|
+
const iy = qw * y + qz * x - qx * z;
|
|
64
|
+
const iz = qw * z + qx * y - qy * x;
|
|
65
|
+
const iw = -qx * x - qy * y - qz * z;
|
|
66
|
+
|
|
67
|
+
return {
|
|
68
|
+
x: ix * qw + iw * -qx + iy * -qz - iz * -qy,
|
|
69
|
+
y: iy * qw + iw * -qy + iz * -qx - ix * -qz,
|
|
70
|
+
z: iz * qw + iw * -qz + ix * -qy - iy * -qx
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
// -------------------------
|
|
25
74
|
// This code must be on top (Physics)
|
|
26
75
|
application.matrixAmmo.detectCollision = function() {
|
|
27
76
|
this.lastRoll = '';
|
|
@@ -44,48 +93,60 @@ export let application = new MatrixEngineWGPU({
|
|
|
44
93
|
var testR = contactManifold.getBody0().getWorldTransform().getRotation();
|
|
45
94
|
}
|
|
46
95
|
var passed = false;
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
this.
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
if(Math.abs(testR.x()) < 0.00001) {
|
|
53
|
-
this.lastRoll = "5";
|
|
54
|
-
this.presentScore += 3;
|
|
55
|
-
passed = true;
|
|
56
|
-
}
|
|
57
|
-
if(testR.x().toString().substring(0, 5) == testR.y().toString().substring(1, 6)) {
|
|
58
|
-
this.lastRoll = "6";
|
|
59
|
-
this.presentScore += 2;
|
|
60
|
-
passed = true;
|
|
61
|
-
}
|
|
62
|
-
if(testR.x().toString().substring(0, 5) == testR.y().toString().substring(0, 5)) {
|
|
63
|
-
this.lastRoll = "2";
|
|
64
|
-
this.presentScore += 1;
|
|
65
|
-
passed = true;
|
|
66
|
-
}
|
|
67
|
-
if(testR.z().toString().substring(0, 5) == testR.y().toString().substring(1, 6)) {
|
|
68
|
-
this.lastRoll = "4";
|
|
69
|
-
this.presentScore += 6;
|
|
70
|
-
passed = true;
|
|
71
|
-
}
|
|
72
|
-
if(testR.z().toString().substring(0, 5) == testR.y().toString().substring(0, 5)) {
|
|
73
|
-
this.lastRoll = "1";
|
|
74
|
-
this.presentScore += 5;
|
|
75
|
-
passed = true;
|
|
96
|
+
const face = application.matrixAmmo.detectTopFaceFromQuat(testR);
|
|
97
|
+
if(face) {
|
|
98
|
+
this.lastRoll = face.toString();
|
|
99
|
+
// Update score logic
|
|
100
|
+
dispatchEvent(new CustomEvent(`dice-${face}`, {detail: {result: `dice-${face}`, cubeId: MY_DICE_NAME}}));
|
|
76
101
|
}
|
|
77
|
-
if(
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
102
|
+
// if(Math.abs(testR.y()) < 0.00001) {
|
|
103
|
+
// this.lastRoll = "3";
|
|
104
|
+
// this.presentScore += 4;
|
|
105
|
+
// passed = true;
|
|
106
|
+
// }
|
|
107
|
+
// if(Math.abs(testR.x()) < 0.00001) {
|
|
108
|
+
// this.lastRoll = "5";
|
|
109
|
+
// this.presentScore += 3;
|
|
110
|
+
// passed = true;
|
|
111
|
+
// }
|
|
112
|
+
// if(testR.x().toString().substring(0, 5) == testR.y().toString().substring(1, 6)) {
|
|
113
|
+
// this.lastRoll = "6";
|
|
114
|
+
// this.presentScore += 2;
|
|
115
|
+
// passed = true;
|
|
116
|
+
// }
|
|
117
|
+
// if(testR.x().toString().substring(0, 5) == testR.y().toString().substring(0, 5)) {
|
|
118
|
+
// this.lastRoll = "2";
|
|
119
|
+
// this.presentScore += 1;
|
|
120
|
+
// passed = true;
|
|
121
|
+
// }
|
|
122
|
+
// if(testR.z().toString().substring(0, 5) == testR.y().toString().substring(1, 6)) {
|
|
123
|
+
// this.lastRoll = "4";
|
|
124
|
+
// this.presentScore += 6;
|
|
125
|
+
// passed = true;
|
|
126
|
+
// }
|
|
127
|
+
// if(testR.z().toString().substring(0, 5) == testR.y().toString().substring(0, 5)) {
|
|
128
|
+
// this.lastRoll = "1";
|
|
129
|
+
// this.presentScore += 5;
|
|
130
|
+
// passed = true;
|
|
131
|
+
// }
|
|
132
|
+
// if(passed == true) dispatchEvent(new CustomEvent(`dice-${this.lastRoll}`, {
|
|
133
|
+
// detail: {
|
|
134
|
+
// result: `dice-${this.lastRoll}`,
|
|
135
|
+
// cubeId: MY_DICE_NAME
|
|
136
|
+
// }
|
|
137
|
+
// }))
|
|
83
138
|
}
|
|
84
139
|
}
|
|
85
140
|
}
|
|
86
141
|
|
|
87
142
|
addRaycastListener();
|
|
88
143
|
addEventListener("ray.hit.event", (e) => {
|
|
144
|
+
if(byId('topTitleDOM') && byId('topTitleDOM').getAttribute('data-gamestatus') != 'FREE' &&
|
|
145
|
+
byId('topTitleDOM').getAttribute('data-gamestatus') != 'status-select') {
|
|
146
|
+
console.log('no hit in middle of game ...');
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
|
|
89
150
|
if(application.dices.STATUS == "FREE_TO_PLAY") {
|
|
90
151
|
console.log("hit cube status free to play prevent pick. ", e.detail.hitObject.name)
|
|
91
152
|
} else if(application.dices.STATUS == "SELECT_DICES_1" ||
|
|
@@ -112,8 +173,12 @@ export let application = new MatrixEngineWGPU({
|
|
|
112
173
|
application.matrixSounds.createAudio('dice1', 'res/audios/dice1.mp3', 6)
|
|
113
174
|
application.matrixSounds.createAudio('dice2', 'res/audios/dice2.mp3', 6)
|
|
114
175
|
application.matrixSounds.createAudio('hover', 'res/audios/toggle_002.mp3', 3)
|
|
176
|
+
application.matrixSounds.createAudio('roll', 'res/audios/dice-roll.mp3', 2)
|
|
115
177
|
|
|
116
178
|
addEventListener('AmmoReady', () => {
|
|
179
|
+
|
|
180
|
+
app.matrixAmmo.speedUpSimulation = 2;
|
|
181
|
+
|
|
117
182
|
downloadMeshes({
|
|
118
183
|
cube: "./res/meshes/jamb/dice.obj",
|
|
119
184
|
}, onLoadObj, {scale: [1, 1, 1], swap: [null]})
|
|
@@ -379,12 +444,37 @@ export let application = new MatrixEngineWGPU({
|
|
|
379
444
|
if(dices.STATUS == "FREE_TO_PLAY" || dices.STATUS == "IN_PLAY") {
|
|
380
445
|
dices.STATUS = "SELECT_DICES_1";
|
|
381
446
|
console.log(`%cStatus<SELECT_DICES_1>`, LOG_FUNNY)
|
|
447
|
+
setTimeout(() => {
|
|
448
|
+
dispatchEvent(new CustomEvent('updateTitle',
|
|
449
|
+
{
|
|
450
|
+
detail: {
|
|
451
|
+
text: app.label.get.freetoroll,
|
|
452
|
+
status: 'FREE'
|
|
453
|
+
}
|
|
454
|
+
}));
|
|
455
|
+
}, 500);
|
|
382
456
|
} else if(dices.STATUS == "SELECT_DICES_1") {
|
|
383
457
|
dices.STATUS = "SELECT_DICES_2";
|
|
458
|
+
setTimeout(() => {
|
|
459
|
+
dispatchEvent(new CustomEvent('updateTitle',
|
|
460
|
+
{
|
|
461
|
+
detail: {
|
|
462
|
+
text: app.label.get.freetoroll,
|
|
463
|
+
status: 'FREE'
|
|
464
|
+
}
|
|
465
|
+
}));
|
|
466
|
+
}, 500);
|
|
384
467
|
console.log(`%cStatus<SELECT_DICES_2>`, LOG_FUNNY)
|
|
385
468
|
} else if(dices.STATUS == "SELECT_DICES_2") {
|
|
386
469
|
dices.STATUS = "FINISHED";
|
|
387
470
|
console.log(`%cStatus<FINISHED>`, LOG_FUNNY)
|
|
471
|
+
dispatchEvent(new CustomEvent('updateTitle',
|
|
472
|
+
{
|
|
473
|
+
detail: {
|
|
474
|
+
text: app.label.get.pick5,
|
|
475
|
+
status: 'status-select'
|
|
476
|
+
}
|
|
477
|
+
}));
|
|
388
478
|
}
|
|
389
479
|
}
|
|
390
480
|
};
|
|
@@ -403,6 +493,14 @@ export let application = new MatrixEngineWGPU({
|
|
|
403
493
|
app.cameras.WASD.pitch = 0;
|
|
404
494
|
app.cameras.WASD.position[2] = 0;
|
|
405
495
|
app.cameras.WASD.position[1] = 3.76;
|
|
496
|
+
|
|
497
|
+
dispatchEvent(new CustomEvent('updateTitle',
|
|
498
|
+
{
|
|
499
|
+
detail: {
|
|
500
|
+
text: app.label.get.hand1,
|
|
501
|
+
status: 'FREE'
|
|
502
|
+
}
|
|
503
|
+
}));
|
|
406
504
|
})
|
|
407
505
|
|
|
408
506
|
// ACTIONS
|
|
@@ -450,10 +548,11 @@ export let application = new MatrixEngineWGPU({
|
|
|
450
548
|
app.matrixAmmo.getBodyByName(`CubePhysics${x}`).setLinearVelocity(new Ammo.btVector3(
|
|
451
549
|
randomFloatFromTo(-5, 5), 15, -20
|
|
452
550
|
))
|
|
551
|
+
setTimeout(() => app.matrixSounds.play('roll'), 1500)
|
|
453
552
|
}, 200 * x)
|
|
454
553
|
}
|
|
455
554
|
|
|
456
|
-
|
|
555
|
+
application.activateDiceClickListener = (index) => {
|
|
457
556
|
index = parseInt(index);
|
|
458
557
|
switch(index) {
|
|
459
558
|
case 1:
|
|
@@ -472,11 +571,20 @@ export let application = new MatrixEngineWGPU({
|
|
|
472
571
|
};
|
|
473
572
|
|
|
474
573
|
let rollProcedure = () => {
|
|
574
|
+
if(topTitleDOM.getAttribute('data-gamestatus') != 'FREE') {
|
|
575
|
+
console.log('validation fails...');
|
|
576
|
+
return;
|
|
577
|
+
}
|
|
475
578
|
if(dices.STATUS == "FREE_TO_PLAY") {
|
|
476
579
|
app.matrixSounds.play('start')
|
|
477
580
|
dices.STATUS = "IN_PLAY";
|
|
478
|
-
|
|
479
|
-
|
|
581
|
+
dispatchEvent(new CustomEvent('updateTitle',
|
|
582
|
+
{
|
|
583
|
+
detail: {
|
|
584
|
+
text: app.label.get.hand1,
|
|
585
|
+
status: 'inplay'
|
|
586
|
+
}
|
|
587
|
+
}));
|
|
480
588
|
addEventListener('dice-1', dice1Click)
|
|
481
589
|
addEventListener('dice-2', dice2Click)
|
|
482
590
|
addEventListener('dice-3', dice3Click)
|
|
@@ -493,10 +601,24 @@ export let application = new MatrixEngineWGPU({
|
|
|
493
601
|
const key = "CubePhysics" + i;
|
|
494
602
|
if(!(key in app.dices.SAVED_DICES)) {
|
|
495
603
|
console.log("Still in game last char is id : ", key[key.length - 1]);
|
|
496
|
-
activateDiceClickListener(parseInt(key[key.length - 1]))
|
|
604
|
+
application.activateDiceClickListener(parseInt(key[key.length - 1]))
|
|
497
605
|
shootDice(key[key.length - 1])
|
|
606
|
+
} else {
|
|
607
|
+
console.log("??????????Still in game last char is id : ", key[key.length - 1]);
|
|
608
|
+
application.activateDiceClickListener(parseInt(key[key.length - 1]))
|
|
498
609
|
}
|
|
499
610
|
}
|
|
611
|
+
// ????
|
|
612
|
+
// application.activateDiceClickListener(1);
|
|
613
|
+
|
|
614
|
+
dispatchEvent(new CustomEvent('updateTitle',
|
|
615
|
+
{
|
|
616
|
+
detail: {
|
|
617
|
+
text: dices.STATUS == "SELECT_DICES_1" ? app.label.get.hand1 : app.label.get.hand2,
|
|
618
|
+
status: 'inplay'
|
|
619
|
+
}
|
|
620
|
+
}));
|
|
621
|
+
|
|
500
622
|
} else if(dices.STATUS == "FINISHED") {
|
|
501
623
|
mb.error('No more roll...');
|
|
502
624
|
mb.show('Pick up 5 dices');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "matrix-engine-wgpu",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.2",
|
|
4
4
|
"description": "+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
|
"scripts": {
|