@woosh/meep-engine 2.40.0 → 2.40.1

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.
@@ -959,14 +959,19 @@ export class BinaryBuffer {
959
959
  /**
960
960
  *
961
961
  * @param {number} length
962
+ * @param {boolean} [null_terminated]
962
963
  * @returns {string}
963
964
  */
964
- readASCIICharacters(length) {
965
+ readASCIICharacters(length, null_terminated = false) {
965
966
  let result = "";
966
967
 
967
968
  for (let i = 0; i < length; i++) {
968
969
  const code = this.readUint8();
969
970
 
971
+ if (null_terminated && code === 0) {
972
+ break;
973
+ }
974
+
970
975
  result += String.fromCharCode(code);
971
976
  }
972
977
 
@@ -1470,7 +1470,7 @@ class Quaternion {
1470
1470
 
1471
1471
  /**
1472
1472
  * Based on GDC talk from Bungie on destiny, compressing quaternions for animation
1473
- * @param value
1473
+ * @param {number} value
1474
1474
  */
1475
1475
  decodeFromUint32(value) {
1476
1476
  //read components
@@ -1481,9 +1481,9 @@ class Quaternion {
1481
1481
  const iv2 = (value >> 22) & 0x3FF;
1482
1482
 
1483
1483
  //scale components back to quaternion range
1484
- const v0 = (iv0 / 511.5 - 1) * K_CONST;
1485
- const v1 = (iv1 / 511.5 - 1) * K_CONST;
1486
- const v2 = (iv2 / 511.5 - 1) * K_CONST;
1484
+ const v0 = (iv0 / 511 - 1) * K_CONST;
1485
+ const v1 = (iv1 / 511 - 1) * K_CONST;
1486
+ const v2 = (iv2 / 511 - 1) * K_CONST;
1487
1487
 
1488
1488
  //restore dropped component using quaternion identity: x^2 + y^2 + z^2 + w^2 = 1
1489
1489
  const dropped_2 = 1 - v0 * v0 - v1 * v1 - v2 * v2;
@@ -1501,7 +1501,7 @@ class Quaternion {
1501
1501
  }
1502
1502
 
1503
1503
  /**
1504
- *
1504
+ * Based on GDC talk from Bungie on destiny, compressing quaternions for animation
1505
1505
  * @returns {number}
1506
1506
  */
1507
1507
  encodeToUint32() {
@@ -1590,9 +1590,9 @@ class Quaternion {
1590
1590
  const m = 1 / (l * K_CONST);
1591
1591
 
1592
1592
  //re-normalize the remaining components to 10 bit UINT value
1593
- const oV0 = ((v0 * m + 1) * 511.5) | 0;
1594
- const oV1 = ((v1 * m + 1) * 511.5) | 0;
1595
- const oV2 = ((v2 * m + 1) * 511.5) | 0;
1593
+ const oV0 = Math.round((v0 * m + 1) * 511);
1594
+ const oV1 = Math.round((v1 * m + 1) * 511);
1595
+ const oV2 = Math.round((v2 * m + 1) * 511);
1596
1596
 
1597
1597
  assert.ok(oV0 <= 1023 && oV0 >= 0, `expected 0 <= ov0 <= 1023, instead was '${oV0}'`);
1598
1598
  assert.ok(oV1 <= 1023 && oV1 >= 0, `expected 0 <= ov1 <= 1023, instead was '${oV1}'`);
@@ -154,6 +154,19 @@ test('encoding to Uint32 consistency', () => {
154
154
  check(1, 0, 0, 0);
155
155
  });
156
156
 
157
+ test('encoding to Uint32 and decoding identity correctly', () => {
158
+ const a = new Quaternion();
159
+ a.copy(Quaternion.identity);
160
+
161
+ const b = new Quaternion();
162
+
163
+ const encoded = a.encodeToUint32();
164
+
165
+ b.decodeFromUint32(encoded);
166
+
167
+ expect(b.toJSON()).toEqual(a.toJSON());
168
+ });
169
+
157
170
 
158
171
  test('to/from euler YXZ consistency', () => {
159
172
  function check(x, y, z) {
@@ -10,4 +10,6 @@ export default class Vector1 {
10
10
  _sub(v: number): void
11
11
 
12
12
  isZero(): boolean
13
+
14
+ process(callback: (x) => any): void
13
15
  }
@@ -24,7 +24,7 @@ export class NumberController extends View {
24
24
  const el = document.createElement('input');
25
25
  this.el = el;
26
26
 
27
- classList.forEach(c => this.addClass(c));
27
+ this.addClasses(classList);
28
28
 
29
29
  el.setAttribute('type', 'text');
30
30
  el.setAttribute('spellcheck', false);
@@ -34,6 +34,7 @@ export class NumberController extends View {
34
34
 
35
35
  let lockForward = false;
36
36
 
37
+
37
38
  /**
38
39
  *
39
40
  * @param {number} num_value
@@ -44,7 +45,26 @@ export class NumberController extends View {
44
45
  let str = String(num_value);
45
46
 
46
47
  if (Math.abs(num_value) > 0 && Math.abs(num_value % 1).toString().length > (figures + 2)) {
47
- str = num_value.toFixed(figures);
48
+ const long_form = num_value.toFixed(figures);
49
+
50
+ const separator_index = long_form.indexOf('.');
51
+
52
+ if (separator_index !== -1) {
53
+ // has a decimal fraction, remove trailing zeroes
54
+ let i = long_form.length - 1;
55
+
56
+ while (i > 0 && long_form.charAt(i) === "0") {
57
+ i--;
58
+ }
59
+
60
+ if (long_form.charAt(i) === '.') {
61
+ i--;
62
+ }
63
+
64
+ str = long_form.slice(0, i + 1);
65
+ } else {
66
+ str = long_form;
67
+ }
48
68
  }
49
69
 
50
70
  return str;
@@ -80,10 +100,8 @@ export class NumberController extends View {
80
100
  * Input field stops being edited
81
101
  */
82
102
  function handle_blur() {
83
- if (Number.isNaN(parseFloat(el.value))) {
84
- // input in the field is invalid, replace with the value held in the data container
85
- el.value = format_value_string(_value.getValue());
86
- }
103
+ // reformat contents of the input field
104
+ el.value = format_value_string(_value.getValue());
87
105
  }
88
106
 
89
107
  _value.process(data2view);
@@ -81,7 +81,7 @@ export class EngineHarness {
81
81
 
82
82
  window.engine = this.engine;
83
83
 
84
- logger.addBackend(new ConsoleLoggerBackend());
84
+ logger.addBackend(ConsoleLoggerBackend.INSTANCE);
85
85
 
86
86
  this.p = null;
87
87
  }
@@ -437,6 +437,7 @@ export class EngineHarness {
437
437
 
438
438
  const eb = new EntityBuilder();
439
439
 
440
+ eb.add(new Transform())
440
441
  eb.add(terrain);
441
442
 
442
443
  if (enableWater) {
@@ -40,6 +40,12 @@ export function PNG() {
40
40
  */
41
41
  this.trns = null;
42
42
 
43
+
44
+ /**
45
+ * Text metadata coming from tEXt chunks
46
+ * @type {Object<string>}
47
+ */
48
+ this.text = {};
43
49
  }
44
50
 
45
51
  PNG.prototype.getWidth = function () {
@@ -157,12 +157,53 @@ PNGReader.prototype.decodeChunk = function () {
157
157
  case 'IEND':
158
158
  this.decodeIEND(chunk);
159
159
  break;
160
+ default:
161
+ //console.log(`Unsupported block ${type}`);
162
+ break;
160
163
  }
161
164
 
162
165
  return type;
163
166
 
164
167
  };
165
168
 
169
+ /**
170
+ * https://www.w3.org/TR/PNG/#11tEXt
171
+ * @param {Uint8Array} chunk
172
+ */
173
+ PNGReader.prototype.decodetEXt = function (chunk) {
174
+ const buff = BinaryBuffer.fromArrayBuffer(chunk.buffer);
175
+ const keyword = buff.readASCIICharacters(Number.POSITIVE_INFINITY, true);
176
+
177
+ const value = buff.readASCIICharacters(keyword.length - 1, false);
178
+
179
+ this.png.text[keyword] = value;
180
+ }
181
+ /**
182
+ * NOTE: untested
183
+ * https://www.w3.org/TR/PNG/#11iEXt
184
+ * @param {Uint8Array} chunk
185
+ */
186
+ PNGReader.prototype.decodeiEXt = function (chunk) {
187
+ const buff = BinaryBuffer.fromArrayBuffer(chunk.buffer);
188
+
189
+ const keyword = buff.readASCIICharacters(Number.POSITIVE_INFINITY, true);
190
+
191
+ const compression_flag = buff.readUint8();
192
+ const compression_method = buff.readUint8();
193
+ const language_tag = buff.readASCIICharacters(Number.POSITIVE_INFINITY, true);
194
+ const translated_keyword = buff.readUTF8String();
195
+
196
+ const separator = buff.readUint8();
197
+
198
+ if (separator !== 0) {
199
+ throw new Error('Expected Null Separator after Translated keyword');
200
+ }
201
+
202
+ const text = buff.readUTF8String();
203
+
204
+ this.png.text[keyword] = text;
205
+ }
206
+
166
207
  /**
167
208
  * http://www.w3.org/TR/2003/REC-PNG-20031110/#11IHDR
168
209
  * http://www.libpng.org/pub/png/spec/1.2/png-1.2-pdg.html#C.IHDR
@@ -496,6 +496,8 @@ class TerrainTile {
496
496
  geometry_bb.x0, geometry_bb.y0, geometry_bb.z0,
497
497
  geometry_bb.x1, geometry_bb.y1, geometry_bb.z1
498
498
  );
499
+ // update changes up the tree
500
+ this.boundingBox.bubbleRefit();
499
501
  }
500
502
 
501
503
  /**
@@ -303,6 +303,31 @@ export class LightManager {
303
303
  this.__visible_bvh_needs_update = true;
304
304
  }
305
305
 
306
+ /**
307
+ * Please set this to false if you have a lot of overlapping decals in the scene
308
+ * Overlapping decals can provide filtering artifacts due to incorrect mipmap level detection by WebGL
309
+ * see article: https://0fps.net/2013/07/09/texture-atlases-wrapping-and-mip-mapping/
310
+ * NOTE: the technique mentioned in the article above is not implemented, as it would require significant increase in number of texture fetches
311
+ * @param {boolean} v
312
+ */
313
+ set decal_filtering_enabled(v) {
314
+ const t = this.__decal_atlas_texture;
315
+
316
+ if (t.generateMipmaps === v) {
317
+ return;
318
+ }
319
+
320
+ t.generateMipmaps = v;
321
+ }
322
+
323
+ /**
324
+ *
325
+ * @return {boolean}
326
+ */
327
+ get decal_filtering_enabled() {
328
+ return this.__decal_atlas_texture.generateMipmaps;
329
+ }
330
+
306
331
  __update_decal_atlas_texture() {
307
332
  const sampler = this.__decal_atlas.sampler;
308
333
 
@@ -1,7 +1,9 @@
1
- import { DataTexture, NearestFilter, RedFormat, UnsignedByteType } from "three";
1
+ import { ClampToEdgeWrapping, DataTexture, NearestFilter, RedFormat, UnsignedByteType } from "three";
2
2
  import { DataType } from "../../../../../core/collection/table/DataType.js";
3
3
  import { assert } from "../../../../../core/assert.js";
4
- import { DataType2TypedArrayConstructorMapping } from "../../../../../core/collection/table/DataType2TypedArrayConstructorMapping.js";
4
+ import {
5
+ DataType2TypedArrayConstructorMapping
6
+ } from "../../../../../core/collection/table/DataType2TypedArrayConstructorMapping.js";
5
7
  import { max2 } from "../../../../../core/math/max2.js";
6
8
  import { NumericType } from "./NumericType.js";
7
9
  import { computeDataType } from "./computeDataType.js";
@@ -63,6 +65,8 @@ export class TextureBackedMemoryRegion {
63
65
  this.__texture.format = RedFormat;
64
66
  this.__texture.magFilter = NearestFilter;
65
67
  this.__texture.minFilter = NearestFilter;
68
+ this.__texture.wrapS = ClampToEdgeWrapping;
69
+ this.__texture.wrapT = ClampToEdgeWrapping;
66
70
  this.__texture.generateMipmaps = false;
67
71
 
68
72
  /**
@@ -53,30 +53,25 @@ export const FP_SHADER_CHUNK_ACCUMULATION = `
53
53
  vec4 local_position = decal_transform_matrix*vec4(v_world_position, 1.0);
54
54
 
55
55
  if(max3(abs(local_position.xyz)) < 0.5){
56
- // material.diffuseColor = material.diffuseColor*(0.8) + (local_position.xyz + 0.5)*0.2; // display UV
57
-
56
+
58
57
  // we're inside decal volume
59
58
  vec4 light_data_4 = texelFetch(fp_t_light_data, address_to_data_texture_coordinates(light_address+4u), 0);
60
-
59
+
61
60
  // compute normal of the decal
62
61
  vec4 decal_normal = normalize( viewMatrix*decal_transform_matrix*vec4(0.0, 0.0, 1.0, 0.0) );
63
62
  float decal_surface_dot = dot(decal_normal.xyz, geometry.normal);
64
-
63
+
65
64
  // we fade out decals when the projection angle to the surface gets too steep
66
65
  // 0.7 is cos(45deg) and 0.5 is cos(60deg), dot returns cos of angle between two normals
67
66
  float decal_surface_angle_fade = smoothstep(-0.5,-0.7,decal_surface_dot);
68
- // float decal_surface_angle_fade = decal_surface_dot;
69
-
70
-
67
+
71
68
  vec2 decal_uv = (local_position.xy + 0.5)*light_data_4.zw + light_data_4.xy;
72
69
 
73
- //material.diffuseColor = material.diffuseColor*(0.8) + vec3(decal_uv + 0.5, 0.0)*0.2; // display UV
74
70
 
75
-
76
71
  vec4 decal_color = texture(fp_t_decal_atlas, decal_uv);
72
+
77
73
  float decal_alpha = decal_color.a * decal_surface_angle_fade;
78
- // float decal_alpha = decal_color.a;
79
-
74
+
80
75
  material.diffuseColor = material.diffuseColor*(1.0-decal_alpha) + decal_color.xyz*decal_alpha;
81
76
 
82
77
  }
@@ -65,6 +65,7 @@ import { StaticKnowledgeDatabase } from "../../../../knowledge/database/StaticKn
65
65
  import { Localization } from "../../../../../core/Localization.js";
66
66
  import '../../../../../../../../css/game.scss'
67
67
  import { randomFromArray } from "../../../../../core/math/random/randomFromArray.js";
68
+ import { debugAtlas } from "../../../particles/particular/engine/shader/debugAtlas.js";
68
69
 
69
70
  document.body.style.margin = 0;
70
71
 
@@ -871,6 +872,270 @@ data/textures/icons/sci-fi-nathan/v6/Proc normal_2.png`
871
872
  camera.position.set(0, 0, 10);
872
873
  }
873
874
 
875
+ async function prepare_scene_decal_2() {
876
+
877
+ const am = new AssetManager(null);
878
+
879
+ await am.registerLoader("image", new ImageRGBADataLoader());
880
+
881
+
882
+ const decal_urls = `data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/staff_13_t.png
883
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/artifact_01_t.png
884
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/artifact_02_t.png
885
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/artifact_03_t.png
886
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/artifact_04_t.png
887
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/artifact_05_t.png
888
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/artifact_06_t.png
889
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/artifact_07_t.png
890
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/artifact_08_t.png
891
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/artifact_09_t.png
892
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/artifact_10_t.png
893
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/artifact_11_t.png
894
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/artifact_12_t.png
895
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/artifact_13_t.png
896
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/artifact_14_t.png
897
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/bag_01_t.png
898
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/bag_02_t.png
899
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/bag_03_t.png
900
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/bag_04_t.png
901
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/bag_05_t.png
902
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/bag_06_t.png
903
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/bag_07_t.png
904
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/bag_08_t.png
905
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/bag_09_t.png
906
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/bag_10_b.png
907
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/bag_11_t.png
908
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/bag_12_t.png
909
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/book_01_t.png
910
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/book_02_t.png
911
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/book_03_t.png
912
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/book_04_t.png
913
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/book_05_t.png
914
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/book_06_t.png
915
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/book_07_t.png
916
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/book_08_t.png
917
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/book_09_t.png
918
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/book_10_t.png
919
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/book_11_t.png
920
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/book_12_t.png
921
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/book_13_t.png
922
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/book_14_t.png
923
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/book_15_t.png
924
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/book_16_t.png
925
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/book_17_t.png
926
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/orb_01_t.png
927
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/orb_02_t.png
928
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/orb_03_t.png
929
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/orb_04_t.png
930
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/orb_05_t.png
931
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/orb_06_t.png
932
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/orb_07_t.png
933
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/orb_08_t.png
934
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/orb_09_t.png
935
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/orb_10_t.png
936
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/orb_11_t.png
937
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/orb_12_t.png
938
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/potion_01_t.png
939
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/potion_02_t.png
940
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/potion_03_t.png
941
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/potion_04_t.png
942
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/potion_05_t.png
943
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/potion_06_t.png
944
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/potion_07_t.png
945
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/potion_08_t.png
946
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/potion_09_t.png
947
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/potion_10_t.png
948
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/potion_11_t.png
949
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/potion_12_t.png
950
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/rune_01_t.png
951
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/rune_02_t.png
952
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/rune_03_t.png
953
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/rune_04_t.png
954
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/rune_05_t.png
955
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/rune_06_t.png
956
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/rune_07_t.png
957
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/rune_08_t.png
958
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/rune_09_t.png
959
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/rune_10_t.png
960
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/rune_11_t.png
961
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/rune_12_t.png
962
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/scroll_01_t.png
963
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/scroll_02_t.png
964
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/scroll_03_t.png
965
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/scroll_04_t.png
966
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/scroll_05_t.png
967
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/scroll_06_t.png
968
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/scroll_07_t.png
969
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/scroll_08_t.png
970
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/scroll_09_t.png
971
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/scroll_10_t.png
972
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/scroll_11_t.png
973
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/scroll_12_t.png
974
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/scroll_13_t.png
975
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/staff_01_t.png
976
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/staff_02_t.png
977
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/staff_03_t.png
978
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/staff_04_t.png
979
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/staff_05_t.png
980
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/staff_06_t.png
981
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/staff_07_t.png
982
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/staff_08_t.png
983
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/staff_09_t.png
984
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/staff_10_t.png
985
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/staff_11_t.png
986
+ data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/staff_12_t.png
987
+ data/textures/icons/sci-fi-nathan/v6/Proc normal_3.png
988
+ data/textures/icons/sci-fi-nathan/v6/Proc strong_1.png
989
+ data/textures/icons/sci-fi-nathan/v6/Proc strong_2.png
990
+ data/textures/icons/sci-fi-nathan/v6/Proc strong_3.png
991
+ data/textures/icons/sci-fi-nathan/v6/Proc very strong_1.png
992
+ data/textures/icons/sci-fi-nathan/v6/Proc very strong_2.png
993
+ data/textures/icons/sci-fi-nathan/v6/Proc very strong_3.png
994
+ data/textures/icons/sci-fi-nathan/v6/Proc very weak_1.png
995
+ data/textures/icons/sci-fi-nathan/v6/Proc very weak_2.png
996
+ data/textures/icons/sci-fi-nathan/v6/Proc very weak_3.png
997
+ data/textures/icons/sci-fi-nathan/v6/Proc weak_1.png
998
+ data/textures/icons/sci-fi-nathan/v6/Proc weak_2.png
999
+ data/textures/icons/sci-fi-nathan/v6/Proc weak_3.png
1000
+ data/textures/icons/sci-fi-nathan/v6/Core normal_1.png
1001
+ data/textures/icons/sci-fi-nathan/v6/Core normal_2.png
1002
+ data/textures/icons/sci-fi-nathan/v6/Core normal_3.png
1003
+ data/textures/icons/sci-fi-nathan/v6/Core strong_1.png
1004
+ data/textures/icons/sci-fi-nathan/v6/Core strong_2.png
1005
+ data/textures/icons/sci-fi-nathan/v6/Core strong_3.png
1006
+ data/textures/icons/sci-fi-nathan/v6/Core very strong_1.png
1007
+ data/textures/icons/sci-fi-nathan/v6/Core very strong_2.png
1008
+ data/textures/icons/sci-fi-nathan/v6/Core very strong_3.png
1009
+ data/textures/icons/sci-fi-nathan/v6/Core very weak_1.png
1010
+ data/textures/icons/sci-fi-nathan/v6/Core very weak_2.png
1011
+ data/textures/icons/sci-fi-nathan/v6/Core very weak_3.png
1012
+ data/textures/icons/sci-fi-nathan/v6/Core weak_1.png
1013
+ data/textures/icons/sci-fi-nathan/v6/Core weak_2.png
1014
+ data/textures/icons/sci-fi-nathan/v6/Core weak_3.png
1015
+ data/textures/icons/sci-fi-nathan/v6/Memory normal_1.png
1016
+ data/textures/icons/sci-fi-nathan/v6/Memory normal_2.png
1017
+ data/textures/icons/sci-fi-nathan/v6/Memory normal_3.png
1018
+ data/textures/icons/sci-fi-nathan/v6/Memory strong_1.png
1019
+ data/textures/icons/sci-fi-nathan/v6/Memory strong_2.png
1020
+ data/textures/icons/sci-fi-nathan/v6/Memory strong_3.png
1021
+ data/textures/icons/sci-fi-nathan/v6/Memory very strong_1.png
1022
+ data/textures/icons/sci-fi-nathan/v6/Memory very strong_2.png
1023
+ data/textures/icons/sci-fi-nathan/v6/Memory very strong_3.png
1024
+ data/textures/icons/sci-fi-nathan/v6/Memory very weak_1.png
1025
+ data/textures/icons/sci-fi-nathan/v6/Memory very weak_2.png
1026
+ data/textures/icons/sci-fi-nathan/v6/Memory very weak_3.png
1027
+ data/textures/icons/sci-fi-nathan/v6/Memory weak_1.png
1028
+ data/textures/icons/sci-fi-nathan/v6/Memory weak_2.png
1029
+ data/textures/icons/sci-fi-nathan/v6/Memory weak_3.png
1030
+ data/textures/icons/sci-fi-nathan/v6/Module normal_1.png
1031
+ data/textures/icons/sci-fi-nathan/v6/Module normal_2.png
1032
+ data/textures/icons/sci-fi-nathan/v6/Module normal_3.png
1033
+ data/textures/icons/sci-fi-nathan/v6/Module strong_1.png
1034
+ data/textures/icons/sci-fi-nathan/v6/Module strong_2.png
1035
+ data/textures/icons/sci-fi-nathan/v6/Module strong_3.png
1036
+ data/textures/icons/sci-fi-nathan/v6/Module very strong_1.png
1037
+ data/textures/icons/sci-fi-nathan/v6/Module very strong_2.png
1038
+ data/textures/icons/sci-fi-nathan/v6/Module very strong_3.png
1039
+ data/textures/icons/sci-fi-nathan/v6/Module very weak_1.png
1040
+ data/textures/icons/sci-fi-nathan/v6/Module very weak_2.png
1041
+ data/textures/icons/sci-fi-nathan/v6/Module very weak_3.png
1042
+ data/textures/icons/sci-fi-nathan/v6/Module weak_1.png
1043
+ data/textures/icons/sci-fi-nathan/v6/Module weak_2.png
1044
+ data/textures/icons/sci-fi-nathan/v6/Module weak_3.png
1045
+ data/textures/icons/sci-fi-nathan/v6/Power normal_1.png
1046
+ data/textures/icons/sci-fi-nathan/v6/Power normal_2.png
1047
+ data/textures/icons/sci-fi-nathan/v6/Power normal_3.png
1048
+ data/textures/icons/sci-fi-nathan/v6/Power strong_1.png
1049
+ data/textures/icons/sci-fi-nathan/v6/Power strong_2.png
1050
+ data/textures/icons/sci-fi-nathan/v6/Power strong_3.png
1051
+ data/textures/icons/sci-fi-nathan/v6/Power very strong_1.png
1052
+ data/textures/icons/sci-fi-nathan/v6/Power very strong_2.png
1053
+ data/textures/icons/sci-fi-nathan/v6/Power very strong_3.png
1054
+ data/textures/icons/sci-fi-nathan/v6/Power very weak_1.png
1055
+ data/textures/icons/sci-fi-nathan/v6/Power very weak_2.png
1056
+ data/textures/icons/sci-fi-nathan/v6/Power very weak_3.png
1057
+ data/textures/icons/sci-fi-nathan/v6/Power weak_1.png
1058
+ data/textures/icons/sci-fi-nathan/v6/Power weak_2.png
1059
+ data/textures/icons/sci-fi-nathan/v6/Power weak_3.png
1060
+ data/textures/icons/sci-fi-nathan/v6/Proc normal_1.png
1061
+ data/textures/icons/sci-fi-nathan/v6/Proc normal_2.png
1062
+ data/textures/utility/sampling-test.png`
1063
+ .split('\n')
1064
+ .map(a => a.trim());
1065
+
1066
+ const samplers = [];
1067
+ const promises = [];
1068
+
1069
+ for (let i = 0; i < decal_urls.length; i++) {
1070
+ const promise = am.promise(decal_urls[i], 'image');
1071
+ promises.push(promise);
1072
+ }
1073
+
1074
+ const assets = await Promise.all(promises);
1075
+
1076
+ for (let i = 0; i < assets.length; i++) {
1077
+ const asset = assets[i];
1078
+
1079
+ samplers[i] = asset.create();
1080
+ }
1081
+
1082
+ const canvas_size = 5;
1083
+
1084
+ const random = seededRandom();
1085
+
1086
+ const COUNT = 1024;
1087
+
1088
+ const ROW_WIDTH = Math.ceil(Math.sqrt(COUNT));
1089
+ const size = canvas_size / ROW_WIDTH;
1090
+
1091
+ for (let i = 0; i < COUNT; i++) {
1092
+
1093
+ const q = new Quaternion();
1094
+ // q.fromEulerAnglesXYZ(0, (90 + randomFloatBetween(random, -60, 60)) * DEG2RAD, 0);
1095
+ q.fromEulerAnglesXYZ(0, (-180) * DEG2RAD, 0);
1096
+
1097
+ const sampler = randomFromArray(random, samplers);
1098
+ // const sampler = samplers[i % samplers.length];
1099
+
1100
+ // const size = randomFloatBetween(random, 1, 3);
1101
+ //const size = 0.5;
1102
+
1103
+ // const position = [
1104
+ // randomFloatBetween(random, -canvas_size * 0.5, canvas_size * 0.5), randomFloatBetween(random, -canvas_size * 0.5, canvas_size * 0.5), -4
1105
+ // ];
1106
+
1107
+ const x = ((i % ROW_WIDTH)) / ROW_WIDTH - 0.5 + 0.5 / ROW_WIDTH;
1108
+ const y = Math.floor(i / ROW_WIDTH) / ROW_WIDTH - 0.5 + 0.5 / ROW_WIDTH;
1109
+ const position = [
1110
+ x * canvas_size, y * canvas_size, -4
1111
+ ];
1112
+
1113
+ addDecal({
1114
+ position: position,
1115
+ scale: [
1116
+ size, size, 1.5
1117
+ ],
1118
+ rotation: q,
1119
+ sampler: sampler,
1120
+ scene,
1121
+ light_manager: lm
1122
+ });
1123
+
1124
+ }
1125
+
1126
+ addBox([0, 0, -4], [canvas_size, canvas_size, 1], [0, 0, 0]);
1127
+ //
1128
+ // addKnot([0, 0, -4], 2, [0, 0, 0])
1129
+
1130
+ scene.add(new AmbientLight(0xFFFFFF, 0.8));
1131
+
1132
+ camera.near = 1;
1133
+ camera.far = 30;
1134
+
1135
+ camera.lookAt(0, 0, -5);
1136
+ camera.position.set(0, 0, 10);
1137
+ }
1138
+
874
1139
 
875
1140
  async function prepare_scene_9() {
876
1141
 
@@ -1295,7 +1560,8 @@ function draw_camera_view_planes() {
1295
1560
 
1296
1561
  // prepare_scene_2();
1297
1562
  // prepare_scene_decal_0();
1298
- prepare_scene_decal_1();
1563
+ // prepare_scene_decal_1();
1564
+ prepare_scene_decal_2();
1299
1565
  // prepare_scene_9();
1300
1566
  // prepare_scene_2();
1301
1567
  // prepare_scene_0();
@@ -1353,7 +1619,7 @@ const debugger_button = new ButtonView({
1353
1619
  }
1354
1620
  });
1355
1621
 
1356
- // debugAtlas(lm.__decal_atlas.atlas, { scale: new Vector2(0.125, 0.125) });
1622
+ debugAtlas(lm.__decal_atlas.atlas, { scale: new Vector2(0.125, 0.125) });
1357
1623
 
1358
1624
  debugger_button.link();
1359
1625
 
@@ -65,15 +65,21 @@ export class AtlasPatch {
65
65
  */
66
66
  updateUV(canvasWidth, canvasHeight) {
67
67
 
68
+ const position = this.position;
68
69
  const size = this.size;
70
+ const uv = this.uv;
69
71
 
70
- const position = this.position;
72
+ const x0 = position.x;
73
+ const y0 = position.y;
74
+
75
+ const sx = size.x;
76
+ const sy = size.y;
71
77
 
72
- this.uv.set(
73
- position.x / canvasWidth,
74
- position.y / canvasHeight,
75
- size.x / canvasWidth,
76
- size.y / canvasHeight
78
+ uv.set(
79
+ x0 / canvasWidth,
80
+ y0 / canvasHeight,
81
+ sx / canvasWidth,
82
+ sy / canvasHeight
77
83
  );
78
84
 
79
85
  }
@@ -1,6 +1,8 @@
1
1
  import { LoggerBackend } from "./LoggerBackend.js";
2
2
  import { LogLevel } from "./LogLevel.js";
3
3
 
4
+ let instance;
5
+
4
6
  export class ConsoleLoggerBackend extends LoggerBackend {
5
7
  log(level, message) {
6
8
  switch (level) {
@@ -19,4 +21,17 @@ export class ConsoleLoggerBackend extends LoggerBackend {
19
21
  console.log(message);
20
22
  }
21
23
  }
24
+
25
+ /**
26
+ * Singleton instance
27
+ * NOTE: you can still create additional instances if you find that useful
28
+ * @return {ConsoleLoggerBackend}
29
+ */
30
+ static get INSTANCE() {
31
+ if (instance === undefined) {
32
+ instance = new ConsoleLoggerBackend();
33
+ }
34
+
35
+ return instance;
36
+ }
22
37
  }
@@ -12,11 +12,34 @@ export class Logger {
12
12
  }
13
13
 
14
14
  /**
15
- *
15
+ * Add a logging backend, this is a structure that handles incoming log messages.
16
+ * There can be multiple backends registered at any given time or even none at all
16
17
  * @param {LoggerBackend} backend
18
+ * @returns {boolean} will return false if backend instance is already attached
17
19
  */
18
20
  addBackend(backend) {
21
+ if (this.backends.includes(backend)) {
22
+ // already registered
23
+ return false;
24
+ }
25
+
19
26
  this.backends.push(backend);
27
+ return true;
28
+ }
29
+
30
+ /**
31
+ * Remove backend instance, counterpart to {@link #addBackend} see {@link #addBackend} for more information
32
+ * @param {LoggerBackend} backend
33
+ * @return {boolean}
34
+ */
35
+ removeBackend(backend) {
36
+ const i = this.backends.indexOf(backend);
37
+ if (i === -1) {
38
+ return false;
39
+ } else {
40
+ this.backends.splice(i, 1);
41
+ return true;
42
+ }
20
43
  }
21
44
 
22
45
  /**
@@ -30,6 +30,7 @@ export class LoggerBackend {
30
30
  *
31
31
  * @param {LogLevel} level
32
32
  * @param {string} message
33
+ * @returns {void}
33
34
  */
34
35
  log(level, message) {
35
36
  throw new Error('Abstract class, method needs to be implemented in the subclass');
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Represents a space where fluid simulation happens
3
+ *
4
+ * @see 2019 GDC talk by Runard Rupert "Wind Simulation in God of War" https://www.youtube.com/watch?v=dDgyBKkSf7A
5
+ * @see Inspired by GDC talk "Interactive Wind and Vegetation in 'God of War'" - https://www.youtube.com/watch?v=MKX45_riWQA
6
+ */
7
+ export class FluidField{
8
+
9
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Base interface for injecting external forces into the simulation
3
+ */
4
+ export class AbstractFluidEffector {
5
+
6
+ }
@@ -0,0 +1,12 @@
1
+ import { AbstractFluidEffector } from "./AbstractFluidEffector.js";
2
+
3
+ /**
4
+ * Affects fluid everywhere inside the field uniformly
5
+ */
6
+ export class GlobalFluidEffector extends AbstractFluidEffector{
7
+ /**
8
+ * 3d force vector
9
+ * @type {number[]}
10
+ */
11
+ force = [0, 0, 0];
12
+ }
@@ -0,0 +1,8 @@
1
+ import { AbstractFluidEffector } from "./AbstractFluidEffector.js";
2
+
3
+ /**
4
+ * Creates force in its "wake" (behind it) as it travels
5
+ */
6
+ export class WakeFluidEffector extends AbstractFluidEffector {
7
+
8
+ }
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "productName": "Meep",
6
6
  "description": "production-ready JavaScript game engine based on Entity Component System Architecture",
7
7
  "author": "Alexander Goldring",
8
- "version": "2.40.0",
8
+ "version": "2.40.1",
9
9
  "dependencies": {
10
10
  "gl-matrix": "3.4.3",
11
11
  "fast-levenshtein": "2.0.6",