matrix-engine-wgpu 1.1.0 → 1.2.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.
Files changed (127) hide show
  1. package/examples/games/jamb/html-content.js +123 -0
  2. package/examples/games/jamb/jamb.js +242 -83
  3. package/examples/unlit-textures.js +18 -17
  4. package/index.js +8 -2
  5. package/main.js +504 -442
  6. package/package.json +5 -2
  7. package/public/app.js +11991 -11387
  8. package/public/css/style.css +229 -80
  9. package/public/examples.js +2091 -241
  10. package/public/index.html +0 -3
  11. package/public/res/audios/kenney/Kenney.url +2 -0
  12. package/public/res/audios/kenney/License.txt +22 -0
  13. package/public/res/audios/kenney/Patreon.url +2 -0
  14. package/public/res/audios/kenney/audios/back_001.ogg +0 -0
  15. package/public/res/audios/kenney/audios/back_002.ogg +0 -0
  16. package/public/res/audios/kenney/audios/back_003.ogg +0 -0
  17. package/public/res/audios/kenney/audios/back_004.ogg +0 -0
  18. package/public/res/audios/kenney/audios/bong_001.ogg +0 -0
  19. package/public/res/audios/kenney/audios/click_001.ogg +0 -0
  20. package/public/res/audios/kenney/audios/click_002.ogg +0 -0
  21. package/public/res/audios/kenney/audios/click_003.ogg +0 -0
  22. package/public/res/audios/kenney/audios/click_004.ogg +0 -0
  23. package/public/res/audios/kenney/audios/click_005.ogg +0 -0
  24. package/public/res/audios/kenney/audios/close_001.ogg +0 -0
  25. package/public/res/audios/kenney/audios/close_002.ogg +0 -0
  26. package/public/res/audios/kenney/audios/close_003.ogg +0 -0
  27. package/public/res/audios/kenney/audios/close_004.ogg +0 -0
  28. package/public/res/audios/kenney/audios/confirmation_001.ogg +0 -0
  29. package/public/res/audios/kenney/audios/confirmation_002.ogg +0 -0
  30. package/public/res/audios/kenney/audios/confirmation_003.ogg +0 -0
  31. package/public/res/audios/kenney/audios/confirmation_004.ogg +0 -0
  32. package/public/res/audios/kenney/audios/drop_001.ogg +0 -0
  33. package/public/res/audios/kenney/audios/drop_002.ogg +0 -0
  34. package/public/res/audios/kenney/audios/drop_003.ogg +0 -0
  35. package/public/res/audios/kenney/audios/drop_004.ogg +0 -0
  36. package/public/res/audios/kenney/audios/error_001.ogg +0 -0
  37. package/public/res/audios/kenney/audios/error_002.ogg +0 -0
  38. package/public/res/audios/kenney/audios/error_003.ogg +0 -0
  39. package/public/res/audios/kenney/audios/error_004.ogg +0 -0
  40. package/public/res/audios/kenney/audios/error_005.ogg +0 -0
  41. package/public/res/audios/kenney/audios/error_006.ogg +0 -0
  42. package/public/res/audios/kenney/audios/error_007.ogg +0 -0
  43. package/public/res/audios/kenney/audios/error_008.ogg +0 -0
  44. package/public/res/audios/kenney/audios/glass_001.ogg +0 -0
  45. package/public/res/audios/kenney/audios/glass_002.ogg +0 -0
  46. package/public/res/audios/kenney/audios/glass_003.ogg +0 -0
  47. package/public/res/audios/kenney/audios/glass_004.ogg +0 -0
  48. package/public/res/audios/kenney/audios/glass_005.ogg +0 -0
  49. package/public/res/audios/kenney/audios/glass_006.ogg +0 -0
  50. package/public/res/audios/kenney/audios/glitch_001.ogg +0 -0
  51. package/public/res/audios/kenney/audios/glitch_002.ogg +0 -0
  52. package/public/res/audios/kenney/audios/glitch_003.ogg +0 -0
  53. package/public/res/audios/kenney/audios/glitch_004.ogg +0 -0
  54. package/public/res/audios/kenney/audios/maximize_001.ogg +0 -0
  55. package/public/res/audios/kenney/audios/maximize_002.ogg +0 -0
  56. package/public/res/audios/kenney/audios/maximize_003.ogg +0 -0
  57. package/public/res/audios/kenney/audios/maximize_004.ogg +0 -0
  58. package/public/res/audios/kenney/audios/maximize_005.ogg +0 -0
  59. package/public/res/audios/kenney/audios/maximize_006.ogg +0 -0
  60. package/public/res/audios/kenney/audios/maximize_007.ogg +0 -0
  61. package/public/res/audios/kenney/audios/maximize_008.ogg +0 -0
  62. package/public/res/audios/kenney/audios/maximize_009.ogg +0 -0
  63. package/public/res/audios/kenney/audios/minimize_001.ogg +0 -0
  64. package/public/res/audios/kenney/audios/minimize_002.ogg +0 -0
  65. package/public/res/audios/kenney/audios/minimize_003.ogg +0 -0
  66. package/public/res/audios/kenney/audios/minimize_004.ogg +0 -0
  67. package/public/res/audios/kenney/audios/minimize_005.ogg +0 -0
  68. package/public/res/audios/kenney/audios/minimize_006.ogg +0 -0
  69. package/public/res/audios/kenney/audios/minimize_007.ogg +0 -0
  70. package/public/res/audios/kenney/audios/minimize_008.ogg +0 -0
  71. package/public/res/audios/kenney/audios/minimize_009.ogg +0 -0
  72. package/public/res/audios/kenney/audios/open_001.ogg +0 -0
  73. package/public/res/audios/kenney/audios/open_002.ogg +0 -0
  74. package/public/res/audios/kenney/audios/open_003.ogg +0 -0
  75. package/public/res/audios/kenney/audios/open_004.ogg +0 -0
  76. package/public/res/audios/kenney/audios/pluck_001.ogg +0 -0
  77. package/public/res/audios/kenney/audios/pluck_002.ogg +0 -0
  78. package/public/res/audios/kenney/audios/question_001.ogg +0 -0
  79. package/public/res/audios/kenney/audios/question_002.ogg +0 -0
  80. package/public/res/audios/kenney/audios/question_003.ogg +0 -0
  81. package/public/res/audios/kenney/audios/question_004.ogg +0 -0
  82. package/public/res/audios/kenney/audios/scratch_001.ogg +0 -0
  83. package/public/res/audios/kenney/audios/scratch_002.ogg +0 -0
  84. package/public/res/audios/kenney/audios/scratch_003.ogg +0 -0
  85. package/public/res/audios/kenney/audios/scratch_004.ogg +0 -0
  86. package/public/res/audios/kenney/audios/scratch_005.ogg +0 -0
  87. package/public/res/audios/kenney/audios/scroll_001.ogg +0 -0
  88. package/public/res/audios/kenney/audios/scroll_002.ogg +0 -0
  89. package/public/res/audios/kenney/audios/scroll_003.ogg +0 -0
  90. package/public/res/audios/kenney/audios/scroll_004.ogg +0 -0
  91. package/public/res/audios/kenney/audios/scroll_005.ogg +0 -0
  92. package/public/res/audios/kenney/audios/select_001.ogg +0 -0
  93. package/public/res/audios/kenney/audios/select_002.ogg +0 -0
  94. package/public/res/audios/kenney/audios/select_003.ogg +0 -0
  95. package/public/res/audios/kenney/audios/select_004.ogg +0 -0
  96. package/public/res/audios/kenney/audios/select_005.ogg +0 -0
  97. package/public/res/audios/kenney/audios/select_006.ogg +0 -0
  98. package/public/res/audios/kenney/audios/select_007.ogg +0 -0
  99. package/public/res/audios/kenney/audios/select_008.ogg +0 -0
  100. package/public/res/audios/kenney/audios/switch_001.ogg +0 -0
  101. package/public/res/audios/kenney/audios/switch_002.ogg +0 -0
  102. package/public/res/audios/kenney/audios/switch_003.ogg +0 -0
  103. package/public/res/audios/kenney/audios/switch_004.ogg +0 -0
  104. package/public/res/audios/kenney/audios/switch_005.ogg +0 -0
  105. package/public/res/audios/kenney/audios/switch_006.ogg +0 -0
  106. package/public/res/audios/kenney/audios/switch_007.ogg +0 -0
  107. package/public/res/audios/kenney/audios/tick_001.ogg +0 -0
  108. package/public/res/audios/kenney/audios/tick_002.ogg +0 -0
  109. package/public/res/audios/kenney/audios/tick_004.ogg +0 -0
  110. package/public/res/audios/kenney/audios/toggle_001.ogg +0 -0
  111. package/public/res/audios/kenney/audios/toggle_002.ogg +0 -0
  112. package/public/res/audios/kenney/audios/toggle_003.ogg +0 -0
  113. package/public/res/audios/kenney/audios/toggle_004.ogg +0 -0
  114. package/public/res/audios/toggle_002.mp3 +0 -0
  115. package/public/res/meshes/shapes/star1.obj +60 -0
  116. package/public/res/multilang/en.json +8 -1
  117. package/public/res/multilang/sr.json +7 -1
  118. package/readme.md +56 -36
  119. package/src/engine/ball.js +474 -468
  120. package/src/engine/cube.js +478 -470
  121. package/src/engine/engine.js +3 -1
  122. package/src/engine/mesh-obj.js +6 -15
  123. package/src/engine/{raycast-test.js → raycast.js} +17 -9
  124. package/src/engine/utils.js +71 -1
  125. package/src/physics/matrix-ammo.js +64 -26
  126. package/src/sounds/sounds.js +32 -10
  127. package/src/world.js +361 -307
@@ -0,0 +1,123 @@
1
+
2
+ export let settingsBox = `
3
+ <div>
4
+ <span style="font-size:170%" data-label="settings"></span>
5
+ <div style="margin:20px;" >
6
+ <div>
7
+ <span data-label="sounds"></span>
8
+ <label class="switch">
9
+ <input id="settingsAudios" type="checkbox">
10
+ <span class="sliderSwitch round"></span>
11
+ </label>
12
+ </div>
13
+ <div>
14
+ <div>
15
+ <span data-label="graphics"></span>
16
+
17
+ <select id="physicsSpeed" class="setting-select">
18
+ <option value="1">Slow</option>
19
+ <option value="2">Normal</option>
20
+ <option value="3">Fast</option>
21
+ </select>
22
+
23
+ <select id="blurControl">
24
+ <option value="0px">Blur: 0</option>
25
+ <option value="1px">Blur: 1</option>
26
+ <option value="2px">Blur: 2</option>
27
+ <option value="3px">Blur: 3</option>
28
+ </select>
29
+ </div>
30
+
31
+ <div>
32
+ <select id="grayscaleControl">
33
+ <option value="0%">Grayscale: 0%</option>
34
+ <option value="25%">Grayscale: 25%</option>
35
+ <option value="50%">Grayscale: 50%</option>
36
+ <option value="75%">Grayscale: 75%</option>
37
+ <option value="100%">Grayscale: 100%</option>
38
+ </select>
39
+ </div>
40
+
41
+ <div>
42
+ <label>Brightness:</label>
43
+ <select id="brightnessControl">
44
+ <option value="100%">100%</option>
45
+ <option value="150%">150%</option>
46
+ <option value="200%">200%</option>
47
+ </select>
48
+ </div>
49
+
50
+ <div>
51
+ <label>Contrast:</label>
52
+ <select id="contrastControl">
53
+ <option value="100%">100%</option>
54
+ <option value="150%">150%</option>
55
+ <option value="200%">200%</option>
56
+ </select>
57
+ </div>
58
+
59
+ <div>
60
+ <label>Saturate:</label>
61
+ <select id="saturateControl">
62
+ <option value="100%">100%</option>
63
+ <option value="150%">150%</option>
64
+ <option value="200%">200%</option>
65
+ </select>
66
+ </div>
67
+
68
+ <div>
69
+ <label>Sepia:</label>
70
+ <select id="sepiaControl">
71
+ <option value="0%">0%</option>
72
+ <option value="50%">50%</option>
73
+ <option value="100%">100%</option>
74
+ </select>
75
+ </div>
76
+
77
+ <div>
78
+ <label>Invert:</label>
79
+ <select id="invertControl">
80
+ <option value="0%">0%</option>
81
+ <option value="50%">50%</option>
82
+ <option value="100%">100%</option>
83
+ </select>
84
+ </div>
85
+
86
+ <div>
87
+ <label>Hue Rotate:</label>
88
+ <select id="hueControl">
89
+ <option value="0deg">0°</option>
90
+ <option value="90deg">90°</option>
91
+ <option value="180deg">180°</option>
92
+ <option value="270deg">270°</option>
93
+ </select>
94
+ </div>
95
+
96
+ </div>
97
+ <div>
98
+ <button class="btn" onclick="app.myDom.hideSettings()">
99
+ <span data-label="hide"></span>
100
+ </button>
101
+ </div>
102
+ </div>
103
+ </div>`;
104
+
105
+ export let welcomeBoxHTML =
106
+ `<span class="fancy-title" data-label="welcomeMsg"></span>
107
+ <a href="https://github.com/zlatnaspirala/matrix-engine-wgpu">zlatnaspirala/matrix-engine-wgpu</a><br><br>
108
+ <div style="display:flex;flex-direction:column;align-items: center;margin:20px;padding: 10px;">
109
+ <span style="width:100%" data-label="choosename"></span>
110
+ <input style="text-align: center;height:50px;font-size:100%;width:250px" class="fancy-label" type="text" value="Guest" />
111
+ </div>
112
+ <button id="startFromWelcome" class="btn" ><span style="font-size:30px;margin:15px;padding:10px" data-label="startGame"></span></button> <br>
113
+ <div><span class="fancy-label" data-label="changeLang"></span></div>
114
+ <button class="btn" onclick="
115
+ app.label.loadMultilang('en').then(r => {
116
+ app.label.get = r;
117
+ app.label.update()
118
+ });
119
+ " ><span data-label="english"></span></button>
120
+ <button class="btn" onclick="app.label.loadMultilang('sr').then(r => {
121
+ app.label.get = r
122
+ app.label.update() })" ><span data-label="serbian"></span></button>
123
+ `;
@@ -1,30 +1,165 @@
1
- import MatrixEngineWGPU from "../../../src/world.js";
2
- import {downloadMeshes} from '../../../src/engine/loader-obj.js';
3
- import {LOG_FUNNY, LOG_INFO, LOG_MATRIX, byId, mb} from "../../../src/engine/utils.js";
1
+ import {LOG_FUNNY, LOG_INFO, LOG_MATRIX, byId, mb, setupCanvasFilters, typeText} from "../../../src/engine/utils.js";
2
+ import {settingsBox, welcomeBoxHTML} from "./html-content.js";
4
3
 
5
4
  export let dices = {
6
5
  C: 0,
7
6
  STATUS: 'FREE_TO_PLAY',
8
- STATUS_H2: 'WAIT',
9
- STATUS_H3: 'WAIT',
10
7
  R: {},
8
+ SAVED_DICES: {},
9
+ pickDice: function(dice) {
10
+ if(Object.keys(this.SAVED_DICES).length >= 5) {
11
+ console.log("⚠️ You can only select up to 5 dice!");
12
+ return; // prevent adding more
13
+ }
14
+ this.SAVED_DICES[dice] = this.R[dice]
15
+ this.refreshSelectedBox()
16
+ },
17
+
18
+ setStartUpPosition: () => {
19
+ //
20
+ let currentIndex = 0;
21
+ for(var x = 1;x < 7;x++) {
22
+ app.matrixAmmo.getBodyByName(('CubePhysics' + x)).MEObject.position.setPosition(-5 + currentIndex * 5, 2, -15);
23
+ }
24
+ },
25
+
26
+ refreshSelectedBox: function(arg) {
27
+ let currentIndex = 0;
28
+ for(var key in this.SAVED_DICES) {
29
+ let B = app.matrixAmmo.getBodyByName(key);
30
+ this.deactivatePhysics(B);
31
+ const transform = new Ammo.btTransform();
32
+ transform.setIdentity();
33
+ transform.setOrigin(new Ammo.btVector3(0, 0, 0));
34
+ B.setWorldTransform(transform);
35
+ B.MEObject.position.setPosition(-5 + currentIndex, 5, -16);
36
+ currentIndex += 3;
37
+ }
38
+ },
39
+
40
+ deactivatePhysics: function(body) {
41
+ const CF_KINEMATIC_OBJECT = 2;
42
+ const DISABLE_DEACTIVATION = 4;
43
+ // 1. Remove from world
44
+ app.matrixAmmo.dynamicsWorld.removeRigidBody(body);
45
+ // 2. Set body to kinematic
46
+ const flags = body.getCollisionFlags();
47
+ body.setCollisionFlags(flags | CF_KINEMATIC_OBJECT);
48
+ body.setActivationState(DISABLE_DEACTIVATION); // no auto-wakeup
49
+ // 3. Clear motion
50
+ const zero = new Ammo.btVector3(0, 0, 0);
51
+ body.setLinearVelocity(zero);
52
+ body.setAngularVelocity(zero);
53
+ // 4. Reset transform to current position (optional — preserves pose)
54
+ const currentTransform = body.getWorldTransform();
55
+ body.setWorldTransform(currentTransform);
56
+ body.getMotionState().setWorldTransform(currentTransform);
57
+ // 5. Add back to physics world
58
+ app.matrixAmmo.dynamicsWorld.addRigidBody(body);
59
+ // 6. Mark it manually (logic flag)
60
+ body.isKinematic = true;
61
+ },
62
+
63
+ resetBodyAboveFloor: function(body, z = -14) {
64
+ const transform = new Ammo.btTransform();
65
+ transform.setIdentity();
66
+ transform.setOrigin(new Ammo.btVector3(-1 + Math.random(), 3, z));
67
+ body.setWorldTransform(transform);
68
+ body.getMotionState().setWorldTransform(transform);
69
+ },
70
+
71
+ activatePhysics: function(body) {
72
+ // 1. Make it dynamic again
73
+ body.setCollisionFlags(body.getCollisionFlags() & ~2); // remove kinematic
74
+ body.setActivationState(1); // ACTIVE_TAG
75
+ body.isKinematic = false;
76
+
77
+ // 2. Reset position ABOVE the floor — force it out of collision
78
+ // const newY = 3 + Math.random(); // ensure it’s above the floor
79
+ const transform = new Ammo.btTransform();
80
+ transform.setIdentity();
81
+ const newX = (Math.random() - 0.5) * 4; // spread from -2 to +2 on X
82
+ const newY = 3; // fixed height above floor
83
+ transform.setOrigin(new Ammo.btVector3(newX, newY, 0));
84
+ body.setWorldTransform(transform);
85
+
86
+ // 3. Clear velocities
87
+ body.setLinearVelocity(new Ammo.btVector3(0, 0, 0));
88
+ body.setAngularVelocity(new Ammo.btVector3(0, 0, 0));
89
+
90
+ // 4. Enable CCD (to prevent tunneling)
91
+ const size = 1; // cube side length
92
+ body.setCcdMotionThreshold(1e-7);
93
+ body.setCcdSweptSphereRadius(size * 0.5);
94
+
95
+ // Re-add to world if needed
96
+ // Optionally: remove and re-add if not responding
97
+ app.matrixAmmo.dynamicsWorld.removeRigidBody(body);
98
+ app.matrixAmmo.dynamicsWorld.addRigidBody(body);
99
+
100
+ // 5. Reactivate it
101
+ body.activate(true);
102
+
103
+ this.resetBodyAboveFloor(body);
104
+ },
105
+
106
+ activateAllDicesPhysics: function() {
107
+ this.getAllDices()
108
+ // .filter((item) => {
109
+ // let test = app.matrixAmmo.getBodyByName(item.name)?.isKinematicObject();
110
+ // if(test === true) {
111
+ // return true;
112
+ // } else {
113
+ // return false;
114
+ // }
115
+ // })
116
+ .forEach((dice) => {
117
+ const body = app.matrixAmmo.getBodyByName(dice.name);
118
+ if(body) {
119
+ this.activatePhysics(body); // <--- FIX: pass the physics body, not the dice object
120
+ }
121
+ });
122
+ },
123
+
124
+ getAllDices: function() {
125
+ return app.mainRenderBundle.filter(item => item.name.indexOf("CubePhysics") !== -1);
126
+ },
127
+
128
+ getDiceByName: function(name) {
129
+ return app.mainRenderBundle.find(item => item.name === name);
130
+ },
131
+
11
132
  checkAll: function() {
12
133
  this.C++;
13
- if(typeof this.R.CubePhysics1 != 'undefined' &&
14
- typeof this.R.CubePhysics2 != 'undefined' &&
15
- typeof this.R.CubePhysics3 != 'undefined' &&
16
- typeof this.R.CubePhysics4 != 'undefined' &&
17
- typeof this.R.CubePhysics5 != 'undefined' &&
18
- typeof this.R.CubePhysics6 != 'undefined' && this.C > 1200) {
19
- dispatchEvent(new CustomEvent('all-done', {detail: {}}))
134
+
135
+ let activeRollingCount = 0;
136
+ let allReady = true;
137
+
138
+ for(let i = 1;i <= 6;i++) {
139
+ const key = "CubePhysics" + i;
140
+ if(key in this.SAVED_DICES) continue; // skip saved ones
141
+ activeRollingCount++; // count how many are still active
142
+ if(typeof this.R[key] === 'undefined') {
143
+ allReady = false;
144
+ break;
145
+ }
146
+ }
147
+ // Dynamic threshold: min wait time based on rolling dice
148
+ const minWait = Math.max(200, activeRollingCount * 200); // e.g. 1 die => 200, 5 dice => 1000, 6 dice => 1200
149
+ if(allReady && this.C > minWait) {
150
+ dispatchEvent(new CustomEvent('all-done', {detail: {}}));
20
151
  this.C = 0;
21
152
  }
22
153
  },
23
154
  validatePass: function() {
24
- if(dices.STATUS == "IN_PLAY" || dices.STATUS == "FREE_TO_PLAY") {
25
- // console.log('%cBLOCK', LOG_FUNNY)
26
- if(dices.STATUS == "IN_PLAY") mb.error(`STATUS IS ${dices.STATUS}, please wait for results...`);
27
- if(dices.STATUS == "FREE_TO_PLAY") mb.error(`STATUS IS ${dices.STATUS}, you need to roll dice first.`);
155
+ if(Object.keys(this.SAVED_DICES).length !== 5) {
156
+ console.log('%cBLOCK', LOG_FUNNY)
157
+ mb.error(`Must select (minimum) 5 dices before add results...`);
158
+ return false;
159
+ }
160
+ if(dices.STATUS != "FINISHED") {
161
+ console.log('%cBLOCK', LOG_FUNNY)
162
+ mb.error(`STATUS IS ${dices.STATUS}, please wait for results...`);
28
163
  app.matrixSounds.play('block')
29
164
  return false;
30
165
  } else {
@@ -56,44 +191,38 @@ export let myDom = {
56
191
 
57
192
  var help = document.createElement('div')
58
193
  help.id = 'HELP';
59
- help.classList.add('btn2')
194
+ help.classList.add('btn')
60
195
  help.innerHTML = `<span data-label="help"></span>`;
61
196
 
62
197
  var settings = document.createElement('div')
63
198
  settings.id = 'settings';
64
- settings.classList.add('btn2')
199
+ settings.classList.add('btn')
65
200
  settings.innerHTML = `<span data-label="settings"></span>`;
66
201
  settings.addEventListener('click', () => {
67
-
68
- byId('messageBox').innerHTML = `
69
- <div>
70
- <span data-label="settings"></span>
71
- <div>
72
-
73
- <div>
74
- <span data-label="sounds"></span>
75
-
76
- <label class="switch">
77
- <input type="checkbox">
78
- <span class="sliderSwitch round"></span>
79
- </label>
80
-
81
- </div>
82
-
83
- <div>
84
- <button class="btn2" onclick="app.myDom.hideSettings()">
85
- <span data-label="hide"></span>
86
- </button>
87
- </div>
88
-
89
- </div>
90
- </div>
91
- `;
92
-
202
+ if(document.getElementById('messageBox').getAttribute('data-loaded') != null) {
203
+ byId('blocker').style.display = 'flex';
204
+ byId('messageBox').style.display = 'unset';
205
+ return;
206
+ }
207
+ byId('messageBox').innerHTML = settingsBox;
93
208
  byId('blocker').style.display = 'flex';
94
- byId('messageBox').style.display = 'flex';
95
-
209
+ byId('messageBox').style.display = 'unset';
96
210
  dispatchEvent(new CustomEvent('updateLang', {}))
211
+
212
+ byId('settingsAudios').click()
213
+ byId('settingsAudios').addEventListener('change', (e) => {
214
+ if(e.target.checked == true) {
215
+ app.matrixSounds.unmuteAll();
216
+ } else {
217
+ app.matrixSounds.muteAll();
218
+ }
219
+ });
220
+ setupCanvasFilters();
221
+ byId('messageBox').setAttribute('data-loaded', 'loaded')
222
+ byId("physicsSpeed").addEventListener("change", (e) => {
223
+ app.matrixAmmo.speedUpSimulation = parseInt(e.target.value);
224
+ });
225
+
97
226
  })
98
227
 
99
228
  var roll = document.createElement('div')
@@ -105,7 +234,7 @@ export let myDom = {
105
234
  })
106
235
 
107
236
  var separator = document.createElement('div')
108
- separator.innerHTML = `=======`;
237
+ separator.innerHTML = `✨maximumroulette.com✨`;
109
238
 
110
239
  root.append(settings)
111
240
  root.append(help)
@@ -127,21 +256,7 @@ export let myDom = {
127
256
  messageBox.id = 'messageBox';
128
257
 
129
258
  // console.log('TEST', app.label.get)
130
- messageBox.innerHTML = `
131
- <span data-label="welcomeMsg"></span>
132
- <a href="https://github.com/zlatnaspirala/matrix-engine-wgpu">zlatnaspirala/matrix-engine-wgpu</a><br><br>
133
- <button class="btn" ><span style="font-size:30px;margin:15px;padding:10px" data-label="startGame"></span></button> <br>
134
- <div><span data-label="changeLang"></span></div>
135
- <button class="btn" onclick="
136
- app.label.loadMultilang('en').then(r => {
137
- app.label.get = r;
138
- app.label.update()
139
- });
140
- " ><span data-label="english"></span></button>
141
- <button class="btn" onclick="app.label.loadMultilang('sr').then(r => {
142
- app.label.get = r
143
- app.label.update() })" ><span data-label="serbian"></span></button>
144
- `;
259
+ messageBox.innerHTML = welcomeBoxHTML;
145
260
 
146
261
 
147
262
  let initialMsgBoxEvent = function() {
@@ -150,25 +265,31 @@ export let myDom = {
150
265
  byId('blocker').style.display = 'none';
151
266
  myDom.createMenu();
152
267
  messageBox.removeEventListener('click', initialMsgBoxEvent)
153
- };
154
268
 
155
- messageBox.addEventListener('click', initialMsgBoxEvent)
269
+ document.querySelectorAll('.btn, .fancy-label, .fancy-title').forEach(el => {
270
+ el.addEventListener('mouseenter', () => {
271
+ app.matrixSounds.play('hover');
272
+ });
273
+ });
274
+ };
156
275
  root.append(messageBox)
157
-
158
276
  document.body.appendChild(root);
159
-
160
277
  app.label.update();
278
+ document.querySelectorAll('.btn, .fancy-label, .fancy-title').forEach(el => {
279
+ el.addEventListener('mouseenter', () => {
280
+ app.matrixSounds.play('hover');
281
+ });
282
+ });
283
+
284
+ setTimeout(() => {
285
+ byId('startFromWelcome').addEventListener('click', initialMsgBoxEvent)
286
+ }, 200);
161
287
  },
162
288
 
163
289
  createJamb: function() {
164
290
  var root = document.createElement('div')
165
291
  root.id = 'jambTable';
166
292
  root.style.position = 'absolute';
167
- root.style.display = 'flex';
168
- root.style.top = '10px';
169
- root.style.left = '10px';
170
- root.style.width = '200px';
171
- root.style.background = '#7d7d7d8c';
172
293
 
173
294
  var rowHeader = document.createElement('div')
174
295
  rowHeader.id = 'rowHeader';
@@ -177,15 +298,16 @@ export let myDom = {
177
298
  rowHeader.style.width = '200px';
178
299
  rowHeader.innerHTML = '<span data-label="cornerText"></span><span id="user-points">0</span>';
179
300
  root.appendChild(rowHeader);
180
- rowHeader.classList.add('myTheme1')
301
+ rowHeader.classList.add('fancy-label')
181
302
 
182
303
  var rowDown = document.createElement('div')
183
304
  rowDown.id = 'rowDown';
184
305
  rowDown.style.top = '10px';
185
306
  rowDown.style.left = '10px';
186
307
  rowDown.style.width = '200px';
187
- rowDown.innerHTML = '';
188
- rowDown.classList.add('myTheme1')
308
+ rowDown.innerHTML = '↓<span data-label="down"></span>';
309
+ rowDown.classList.add('fancy-label')
310
+ rowDown.classList.add('btn')
189
311
  root.appendChild(rowDown);
190
312
 
191
313
  var rowFree = document.createElement('div')
@@ -193,8 +315,9 @@ export let myDom = {
193
315
  rowFree.style.top = '10px';
194
316
  rowFree.style.left = '10px';
195
317
  rowFree.style.width = '200px';
196
- rowFree.innerHTML = '';
197
- rowFree.classList.add('myTheme1')
318
+ rowFree.innerHTML = '↕<span data-label="free"></span>';
319
+ rowFree.classList.add('fancy-label')
320
+ rowFree.classList.add('btn')
198
321
  root.appendChild(rowFree);
199
322
 
200
323
  var rowUp = document.createElement('div')
@@ -202,8 +325,9 @@ export let myDom = {
202
325
  rowUp.style.top = '10px';
203
326
  rowUp.style.left = '10px';
204
327
  rowUp.style.width = '200px';
205
- rowUp.innerHTML = '';
206
- rowUp.classList.add('myTheme1')
328
+ rowUp.innerHTML = '↑<span data-label="up"></span>';
329
+ rowUp.classList.add('fancy-label')
330
+ rowUp.classList.add('btn')
207
331
  root.appendChild(rowUp);
208
332
 
209
333
  var rowHand = document.createElement('div')
@@ -212,7 +336,8 @@ export let myDom = {
212
336
  rowHand.style.left = '10px';
213
337
  rowHand.style.width = '200px';
214
338
  rowHand.innerHTML = '<span data-label="hand"></span>';
215
- rowHand.classList.add('myTheme1')
339
+ rowHand.classList.add('fancy-label')
340
+ rowHand.classList.add('btn')
216
341
  root.appendChild(rowHand);
217
342
 
218
343
  // INJECT TABLE HEADER ROW
@@ -222,12 +347,45 @@ export let myDom = {
222
347
  this.createRow(rowUp);
223
348
  this.createRow(rowHand);
224
349
 
350
+ this.createSelectedBox();
351
+
225
352
  document.body.appendChild(root);
226
353
  // console.log('JambTable added.')
227
354
  },
228
355
 
229
- createLeftHeaderRow: function(myRoot) {
356
+ showHideJambTable: () => {
357
+ const panel = document.getElementById('jambTable');
358
+ if(panel.classList.contains('show')) {
359
+ panel.classList.remove('show');
360
+ panel.classList.add('hide');
361
+ // Delay actual hiding from layout to finish animation
362
+ setTimeout(() => {
363
+ panel.style.display = 'none';
364
+ }, 300);
365
+ } else {
366
+ panel.style.display = 'flex';
367
+ setTimeout(() => {
368
+ panel.classList.remove('hide');
369
+ panel.classList.add('show');
370
+ }, 10); // allow repaint
371
+ }
372
+ },
373
+ createSelectedBox: function() {
374
+ var topTitleDOM = document.createElement('div')
375
+ topTitleDOM.id = 'topTitleDOM';
376
+ topTitleDOM.style.width = 'auto';
377
+ topTitleDOM.style.position = 'absolute';
378
+ topTitleDOM.style.left = '35%';
379
+ topTitleDOM.style.top = '5%';
380
+ topTitleDOM.style.background = '#7d7d7d8c';
381
+ topTitleDOM.innerHTML = app.label.get.ready + ", " + app.userState.name + '.';
382
+ document.body.appendChild(topTitleDOM);
383
+ addEventListener('updateTitle', (e) => {
384
+ typeText('topTitleDOM', e.detail);
385
+ })
386
+ },
230
387
 
388
+ createLeftHeaderRow: function(myRoot) {
231
389
  for(var x = 1;x < 7;x++) {
232
390
  var rowNumber = document.createElement('div')
233
391
  rowNumber.id = 'rowNumber' + x;
@@ -427,7 +585,7 @@ export let myDom = {
427
585
  var getName = e.target.id;
428
586
  getName = getName.replace('free-rowNumber', '')
429
587
  var count23456 = 0;
430
- for(let key in dices.R) {
588
+ for(let key in dices.SAVED_DICES) {
431
589
  if(parseInt(dices.R[key]) == parseInt(getName)) {
432
590
  count23456++;
433
591
  }
@@ -529,6 +687,7 @@ export let myDom = {
529
687
  rowNumber.style.left = '10px';
530
688
  rowNumber.style.width = 'auto';
531
689
  rowNumber.style.background = '#7d7d7d8c';
690
+ rowNumber.style.cursor = 'pointer';
532
691
  rowNumber.innerHTML = `-`;
533
692
 
534
693
  this.memoNumberRow.push(rowNumber)
@@ -547,7 +706,7 @@ export let myDom = {
547
706
  console.log('LOG ', getName)
548
707
  if(parseInt(getName) == 1) {
549
708
  var count1 = 0;
550
- for(let key in dices.R) {
709
+ for(let key in dices.SAVED_DICES) {
551
710
  if(parseInt(dices.R[key]) == 1) {
552
711
  console.log('yeap', dices.R)
553
712
  count1++;
@@ -568,7 +727,7 @@ export let myDom = {
568
727
  if(parseInt(getName) == this.state.rowDown.length + 1) {
569
728
  console.log('moze za ', parseInt(getName))
570
729
  var count23456 = 0;
571
- for(let key in dices.R) {
730
+ for(let key in dices.SAVED_DICES) {
572
731
  if(parseInt(dices.R[key]) == parseInt(getName)) {
573
732
  console.log('yeap', dices.R)
574
733
  count23456++;
@@ -5,24 +5,25 @@ export var unlitTextures = function() {
5
5
  useSingleRenderPass: false,
6
6
  canvasSize: 'fullscreen'
7
7
  }, () => {
8
+ addEventListener('AmmoReady', () => {
9
+ let c = {
10
+ scale: 2,
11
+ position: {x: -3, y: 0, z: -10},
12
+ rotation: {x: 0, y: 0, z: 0},
13
+ rotationSpeed: {x: 10, y: 0, z: 0},
14
+ texturesPaths: ['./res/textures/rust.jpg']
15
+ };
8
16
 
9
- let c = {
10
- scale: 2,
11
- position: {x: -3, y: 0, z: -10},
12
- rotation: {x: 0, y: 0, z: 0},
13
- rotationSpeed: {x: 10, y: 0, z: 0},
14
- texturesPaths: ['./res/textures/rust.jpg']
15
- };
16
-
17
- let o = {
18
- scale: 2,
19
- position: {x: 3, y: 0, z: -10},
20
- rotation: {x: 0, y: 45, z: 0},
21
- rotationSpeed: {x: 0, y: 10, z: 0},
22
- texturesPaths: ['./res/textures/rust.jpg']
23
- };
24
- unlitTextures.addBall(c)
25
- unlitTextures.addCube(o)
17
+ let o = {
18
+ scale: 2,
19
+ position: {x: 3, y: 0, z: -10},
20
+ rotation: {x: 0, y: 0, z: 0},
21
+ rotationSpeed: {x: 10, y: 0, z: 0},
22
+ texturesPaths: ['./res/textures/default.png']
23
+ };
24
+ unlitTextures.addCube(o)
25
+ unlitTextures.addBall(c)
26
+ });
26
27
  })
27
28
 
28
29
  window.app = unlitTextures;
package/index.js CHANGED
@@ -6,19 +6,25 @@
6
6
  import {degToRad} from "wgpu-matrix/dist/2.x/utils.js";
7
7
  import {downloadMeshes} from "./src/engine/loader-obj.js";
8
8
  import MatrixEngineWGPU from "./src/meWGPU.js";
9
+ import {getRayFromMouse, rayIntersectsSphere} from "./src/engine/raycast.js";
9
10
 
10
11
  var about = () => {
11
12
  console.log("Hi npm. matrix-engine for webgpu is ready...")
12
13
  console.log("--------------------------------------------")
13
- console.log("List of features : ")
14
+ console.log("List of features: ")
14
15
  console.log(" - Loading obj files with uvs")
15
- console.log(" - Scene oriented draws")
16
+ console.log(" - Scene camera use -z front")
16
17
  console.log(" - position, rotation - same like matrix-engine")
18
+ console.log(" - Physics used Ammo.js build")
19
+ console.log(" - Raycaster HIT/CLICK on object scene")
17
20
  }
18
21
 
19
22
  export {
20
23
  MatrixEngineWGPU,
21
24
  downloadMeshes,
25
+ rayIntersectsSphere,
26
+ getRayFromMouse,
27
+ addRaycastListener,
22
28
  degToRad,
23
29
  about
24
30
  }