matrix-engine-wgpu 1.0.1 → 1.0.4

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 (46) hide show
  1. package/LICENSE +22 -17
  2. package/REFERENCE.md +48 -2
  3. package/app-worker.js +45 -0
  4. package/empty.js +12 -0
  5. package/examples/load-obj-file.js +48 -0
  6. package/examples/unlit-textures.js +27 -0
  7. package/examples.js +7 -0
  8. package/index.js +18 -5
  9. package/main.js +29 -12
  10. package/package.json +11 -2
  11. package/public/app-worker.js +47 -0
  12. package/public/app.js +2833 -279
  13. package/public/css/style.css +1 -2
  14. package/public/empty.html +25 -0
  15. package/public/empty.js +9107 -0
  16. package/public/examples.html +25 -0
  17. package/public/examples.js +9180 -0
  18. package/public/res/meshes/blender/piramyd.blend +0 -0
  19. package/public/res/meshes/blender/piramyd.blend1 +0 -0
  20. package/public/res/meshes/blender/piramyd.js +42 -0
  21. package/public/res/meshes/blender/piramyd.mtl +10 -0
  22. package/public/res/meshes/blender/piramyd.obj +18696 -0
  23. package/public/res/meshes/blender/piramyd1.js +42 -0
  24. package/public/res/meshes/blender/welcomeTextblend.blend +0 -0
  25. package/public/res/meshes/dragon/stanfordDragonData.js +5 -0
  26. package/public/res/meshes/obj/armor.obj +319 -0
  27. package/public/res/meshes/obj/armor.png +0 -0
  28. package/public/worker.html +25 -0
  29. package/readme.md +77 -36
  30. package/src/engine/ball.js +43 -23
  31. package/src/engine/cube.js +112 -87
  32. package/src/engine/engine.js +470 -0
  33. package/src/engine/final/adaptJSON1.js +53 -0
  34. package/src/engine/final/utils2.js +63 -0
  35. package/src/engine/loader-obj.js +469 -0
  36. package/src/engine/matrix-class.js +44 -1
  37. package/src/engine/matrix-mesh.js +49 -0
  38. package/src/engine/mesh-obj.js +526 -0
  39. package/src/engine/mesh.js +477 -0
  40. package/src/engine/utils.js +2 -0
  41. package/src/shaders/fragment.wgsl.js +48 -0
  42. package/src/shaders/shaders.js +4 -124
  43. package/src/shaders/vertex.wgsl.js +49 -0
  44. package/src/shaders/vertexShadow.wgsl.js +20 -0
  45. package/src/world.js +263 -0
  46. package/src/meWGPU.js +0 -92
package/public/app.js CHANGED
@@ -1,31 +1,68 @@
1
1
  (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
2
2
  "use strict";
3
3
 
4
- var _meWGPU = _interopRequireDefault(require("./src/meWGPU"));
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.application = void 0;
8
+ var _world = _interopRequireDefault(require("./src/world.js"));
9
+ var _loaderObj = require("./src/engine/loader-obj.js");
5
10
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
6
- let application = new _meWGPU.default(() => {
7
- let c = {
8
- position: {
9
- x: -1,
10
- y: 3,
11
- z: -10
12
- },
13
- texturesPaths: ['./res/textures/rust.jpg']
14
- };
15
- let o = {
16
- position: {
17
- x: 5,
18
- y: 2,
19
- z: -10
20
- },
21
- texturesPaths: ['./res/textures/rust.jpg']
22
- };
23
- application.addCube(c);
24
- application.addBall(o);
11
+ let application = exports.application = new _world.default({
12
+ useSingleRenderPass: false,
13
+ canvasSize: 'fullscreen'
14
+ }, () => {
15
+ function onLoadObj(m) {
16
+ console.log('Loaded objs:', m);
17
+ application.addMeshObj({
18
+ position: {
19
+ x: -3,
20
+ y: 0,
21
+ z: -5
22
+ },
23
+ rotation: {
24
+ x: 0,
25
+ y: 0,
26
+ z: 0
27
+ },
28
+ rotationSpeed: {
29
+ x: 0,
30
+ y: 10,
31
+ z: 0
32
+ },
33
+ texturesPaths: ['./res/meshes/obj/armor.png'],
34
+ name: 'Armor',
35
+ mesh: m.armor
36
+ });
37
+ application.addMeshObj({
38
+ position: {
39
+ x: 3,
40
+ y: 0,
41
+ z: -5
42
+ },
43
+ rotation: {
44
+ x: -90,
45
+ y: 0,
46
+ z: 0
47
+ },
48
+ rotationSpeed: {
49
+ x: 0,
50
+ y: 0,
51
+ z: 0
52
+ },
53
+ texturesPaths: ['./res/meshes/obj/armor.png'],
54
+ name: 'MyText',
55
+ mesh: m.welcomeText
56
+ });
57
+ }
58
+ (0, _loaderObj.downloadMeshes)({
59
+ welcomeText: "./res/meshes/blender/piramyd.obj",
60
+ armor: "./res/meshes/obj/armor.obj"
61
+ }, onLoadObj);
25
62
  });
26
63
  window.app = application;
27
64
 
28
- },{"./src/meWGPU":6}],2:[function(require,module,exports){
65
+ },{"./src/engine/loader-obj.js":6,"./src/world.js":15}],2:[function(require,module,exports){
29
66
  "use strict";
30
67
 
31
68
  Object.defineProperty(exports, "__esModule", {
@@ -5382,10 +5419,24 @@ exports.default = void 0;
5382
5419
  var _shaders = require("../shaders/shaders");
5383
5420
  var _wgpuMatrix = require("wgpu-matrix");
5384
5421
  var _matrixClass = require("./matrix-class");
5422
+ var _engine = require("./engine");
5385
5423
  class MEBall {
5386
5424
  constructor(canvas, device, context, o) {
5387
5425
  this.context = context;
5388
5426
  this.device = device;
5427
+
5428
+ // The input handler
5429
+ this.inputHandler = (0, _engine.createInputHandler)(window, canvas);
5430
+ this.cameras = o.cameras;
5431
+ this.scale = o.scale;
5432
+ console.log('passed : o.mainCameraParams.responseCoef ', o.mainCameraParams.responseCoef);
5433
+ this.cameraParams = {
5434
+ type: o.mainCameraParams.type,
5435
+ responseCoef: o.mainCameraParams.responseCoef
5436
+ }; // | WASD 'arcball' };
5437
+
5438
+ this.lastFrameMS = 0;
5439
+ this.entityArgPass = o.entityArgPass;
5389
5440
  this.SphereLayout = {
5390
5441
  vertexStride: 8 * 4,
5391
5442
  positionsOffset: 0,
@@ -5397,8 +5448,12 @@ class MEBall {
5397
5448
  this.texturesPaths.push(t);
5398
5449
  });
5399
5450
  this.position = new _matrixClass.Position(o.position.x, o.position.y, o.position.z);
5451
+ this.rotation = new _matrixClass.Rotation(o.rotation.x, o.rotation.y, o.rotation.z);
5452
+ this.rotation.rotationSpeed.x = o.rotationSpeed.x;
5453
+ this.rotation.rotationSpeed.y = o.rotationSpeed.y;
5454
+ this.rotation.rotationSpeed.z = o.rotationSpeed.z;
5400
5455
  this.shaderModule = device.createShaderModule({
5401
- code: _shaders.BALL_SHADER
5456
+ code: _shaders.UNLIT_SHADER
5402
5457
  });
5403
5458
  this.presentationFormat = navigator.gpu.getPreferredCanvasFormat();
5404
5459
  this.pipeline = device.createRenderPipeline({
@@ -5468,7 +5523,6 @@ class MEBall {
5468
5523
  };
5469
5524
  this.loadTex0(this.texturesPaths, device).then(() => {
5470
5525
  this.loadTex1(device).then(() => {
5471
- console.log('NICE THIS', this);
5472
5526
  this.sampler = device.createSampler({
5473
5527
  magFilter: 'linear',
5474
5528
  minFilter: 'linear'
@@ -5477,32 +5531,29 @@ class MEBall {
5477
5531
  _wgpuMatrix.mat4.identity(this.transform);
5478
5532
 
5479
5533
  // Create one large central planet surrounded by a large ring of asteroids
5480
- this.planet = this.createSphereRenderable(1.0);
5534
+ this.planet = this.createGeometry(this.scale);
5481
5535
  this.planet.bindGroup = this.createSphereBindGroup(this.texture0, this.transform);
5482
- var asteroids = [this.createSphereRenderable(0.2, 8, 6, 0.15), this.createSphereRenderable(0.13, 8, 6, 0.15)];
5536
+ var asteroids = [this.createGeometry(12, 8, 6, 0.15)];
5483
5537
  this.renderables = [this.planet];
5484
5538
 
5485
5539
  // this.ensureEnoughAsteroids(asteroids, this.transform);
5486
-
5487
5540
  this.renderPassDescriptor = {
5488
5541
  colorAttachments: [{
5489
5542
  view: undefined,
5490
- // Assigned later
5491
-
5492
5543
  clearValue: {
5493
5544
  r: 0.0,
5494
5545
  g: 0.0,
5495
5546
  b: 0.0,
5496
5547
  a: 1.0
5497
5548
  },
5498
- loadOp: 'clear',
5499
- storeOp: 'store'
5549
+ loadOp: this.entityArgPass.loadOp,
5550
+ storeOp: this.entityArgPass.storeOp
5500
5551
  }],
5501
5552
  depthStencilAttachment: {
5502
5553
  view: this.depthTexture.createView(),
5503
5554
  depthClearValue: 1.0,
5504
- depthLoadOp: 'clear',
5505
- depthStoreOp: 'store'
5555
+ depthLoadOp: this.entityArgPass.depthLoadOp,
5556
+ depthStoreOp: this.entityArgPass.depthStoreOp
5506
5557
  }
5507
5558
  };
5508
5559
  const aspect = canvas.width / canvas.height;
@@ -5561,7 +5612,7 @@ class MEBall {
5561
5612
  this.renderScene(renderBundleEncoder);
5562
5613
  this.renderBundle = renderBundleEncoder.finish();
5563
5614
  }
5564
- createSphereRenderable(radius, widthSegments = 8, heightSegments = 4, randomness = 0) {
5615
+ createGeometry(radius, widthSegments = 8, heightSegments = 4, randomness = 0) {
5565
5616
  const sphereMesh = this.createSphereMesh(radius, widthSegments, heightSegments, randomness);
5566
5617
  // Create a vertex buffer from the sphere data.
5567
5618
  const vertices = this.device.createBuffer({
@@ -5611,12 +5662,18 @@ class MEBall {
5611
5662
  return bindGroup;
5612
5663
  }
5613
5664
  getTransformationMatrix(pos) {
5614
- const viewMatrix = _wgpuMatrix.mat4.identity();
5665
+ // const viewMatrix = mat4.identity();
5666
+ const now = Date.now();
5667
+ const deltaTime = (now - this.lastFrameMS) / this.cameraParams.responseCoef;
5668
+ this.lastFrameMS = now;
5669
+
5670
+ // const viewMatrix = mat4.identity(); ORI
5671
+ const camera = this.cameras[this.cameraParams.type];
5672
+ const viewMatrix = camera.update(deltaTime, this.inputHandler());
5615
5673
  _wgpuMatrix.mat4.translate(viewMatrix, _wgpuMatrix.vec3.fromValues(pos.x, pos.y, pos.z), viewMatrix);
5616
- const now = Date.now() / 1000;
5617
- _wgpuMatrix.mat4.rotateZ(viewMatrix, Math.PI * 0.1, viewMatrix);
5618
- _wgpuMatrix.mat4.rotateX(viewMatrix, Math.PI * 0.1, viewMatrix);
5619
- _wgpuMatrix.mat4.rotateY(viewMatrix, now * 0.05, viewMatrix);
5674
+ _wgpuMatrix.mat4.rotateX(viewMatrix, Math.PI * this.rotation.getRotX(), viewMatrix);
5675
+ _wgpuMatrix.mat4.rotateY(viewMatrix, Math.PI * this.rotation.getRotY(), viewMatrix);
5676
+ _wgpuMatrix.mat4.rotateZ(viewMatrix, Math.PI * this.rotation.getRotZ(), viewMatrix);
5620
5677
  _wgpuMatrix.mat4.multiply(this.projectionMatrix, viewMatrix, this.modelViewProjectionMatrix);
5621
5678
  return this.modelViewProjectionMatrix;
5622
5679
  }
@@ -5722,6 +5779,7 @@ class MEBall {
5722
5779
  indices: new Uint16Array(indices)
5723
5780
  };
5724
5781
  }
5782
+
5725
5783
  // Render bundles function as partial, limited render passes, so we can use the
5726
5784
  // same code both to render the scene normally and to build the render bundle.
5727
5785
  renderScene(passEncoder) {
@@ -5758,7 +5816,7 @@ class MEBall {
5758
5816
  }
5759
5817
  exports.default = MEBall;
5760
5818
 
5761
- },{"../shaders/shaders":7,"./matrix-class":5,"wgpu-matrix":2}],4:[function(require,module,exports){
5819
+ },{"../shaders/shaders":12,"./engine":5,"./matrix-class":7,"wgpu-matrix":2}],4:[function(require,module,exports){
5762
5820
  "use strict";
5763
5821
 
5764
5822
  Object.defineProperty(exports, "__esModule", {
@@ -5768,6 +5826,7 @@ exports.default = void 0;
5768
5826
  var _shaders = require("../shaders/shaders");
5769
5827
  var _wgpuMatrix = require("wgpu-matrix");
5770
5828
  var _matrixClass = require("./matrix-class");
5829
+ var _engine = require("./engine");
5771
5830
  var SphereLayout = {
5772
5831
  vertexStride: 8 * 4,
5773
5832
  positionsOffset: 0,
@@ -5778,8 +5837,18 @@ class MECube {
5778
5837
  constructor(canvas, device, context, o) {
5779
5838
  this.device = device;
5780
5839
  this.context = context;
5840
+ this.entityArgPass = o.entityArgPass;
5841
+ this.inputHandler = (0, _engine.createInputHandler)(window, canvas);
5842
+ this.cameras = o.cameras;
5843
+ console.log('passed : o.mainCameraParams.responseCoef ', o.mainCameraParams.responseCoef);
5844
+ this.cameraParams = {
5845
+ type: o.mainCameraParams.type,
5846
+ responseCoef: o.mainCameraParams.responseCoef
5847
+ }; // | WASD 'arcball' };
5848
+
5849
+ this.lastFrameMS = 0;
5781
5850
  this.shaderModule = device.createShaderModule({
5782
- code: _shaders.BALL_SHADER
5851
+ code: _shaders.UNLIT_SHADER
5783
5852
  });
5784
5853
  this.texturesPaths = [];
5785
5854
  o.texturesPaths.forEach(t => {
@@ -5787,6 +5856,12 @@ class MECube {
5787
5856
  });
5788
5857
  this.presentationFormat = navigator.gpu.getPreferredCanvasFormat();
5789
5858
  this.position = new _matrixClass.Position(o.position.x, o.position.y, o.position.z);
5859
+ console.log('cube added on pos : ', this.position);
5860
+ this.rotation = new _matrixClass.Rotation(o.rotation.x, o.rotation.y, o.rotation.z);
5861
+ this.rotation.rotationSpeed.x = o.rotationSpeed.x;
5862
+ this.rotation.rotationSpeed.y = o.rotationSpeed.y;
5863
+ this.rotation.rotationSpeed.z = o.rotationSpeed.z;
5864
+ this.scale = o.scale;
5790
5865
  this.pipeline = device.createRenderPipeline({
5791
5866
  layout: 'auto',
5792
5867
  vertex: {
@@ -5865,13 +5940,18 @@ class MECube {
5865
5940
  _wgpuMatrix.mat4.identity(this.transform);
5866
5941
 
5867
5942
  // Create one large central planet surrounded by a large ring of asteroids
5868
- this.planet = this.createSphereRenderable(1.0);
5943
+ this.planet = this.createGeometry({
5944
+ scale: this.scale,
5945
+ useUVShema4x2: false
5946
+ });
5869
5947
  this.planet.bindGroup = this.createSphereBindGroup(this.texture0, this.transform);
5870
- var asteroids = [this.createSphereRenderable(0.2, 8, 6, 0.15), this.createSphereRenderable(0.13, 8, 6, 0.15)];
5871
- this.renderables = [this.planet];
5872
5948
 
5949
+ // can be used like instance draws
5950
+ var asteroids = [
5951
+ // this.createGeometry(0.2, 8, 6, 0.15),
5952
+ ];
5953
+ this.renderables = [this.planet];
5873
5954
  // this.ensureEnoughAsteroids(asteroids, this.transform);
5874
-
5875
5955
  this.renderPassDescriptor = {
5876
5956
  colorAttachments: [{
5877
5957
  view: undefined,
@@ -5881,18 +5961,18 @@ class MECube {
5881
5961
  b: 0.0,
5882
5962
  a: 1.0
5883
5963
  },
5884
- loadOp: 'clear',
5885
- storeOp: 'store'
5964
+ loadOp: this.entityArgPass.loadOp,
5965
+ storeOp: this.entityArgPass.storeOp
5886
5966
  }],
5887
5967
  depthStencilAttachment: {
5888
5968
  view: this.depthTexture.createView(),
5889
5969
  depthClearValue: 1.0,
5890
- depthLoadOp: 'clear',
5891
- depthStoreOp: 'store'
5970
+ depthLoadOp: this.entityArgPass.depthLoadOp,
5971
+ depthStoreOp: this.entityArgPass.depthStoreOp
5892
5972
  }
5893
5973
  };
5894
5974
  const aspect = canvas.width / canvas.height;
5895
- this.projectionMatrix = _wgpuMatrix.mat4.perspective(2 * Math.PI / 5, aspect, 1, 100.0);
5975
+ this.projectionMatrix = _wgpuMatrix.mat4.perspective(2 * Math.PI / 5, aspect, 1, 1000.0);
5896
5976
  this.modelViewProjectionMatrix = _wgpuMatrix.mat4.create();
5897
5977
  this.frameBindGroup = device.createBindGroup({
5898
5978
  layout: this.pipeline.getBindGroupLayout(0),
@@ -5939,7 +6019,7 @@ class MECube {
5939
6019
  }
5940
6020
  }
5941
6021
  updateRenderBundle() {
5942
- console.log('sss');
6022
+ console.log('[CUBE] updateRenderBundle');
5943
6023
  const renderBundleEncoder = this.device.createRenderBundleEncoder({
5944
6024
  colorFormats: [this.presentationFormat],
5945
6025
  depthStencilFormat: 'depth24plus'
@@ -5947,27 +6027,27 @@ class MECube {
5947
6027
  this.renderScene(renderBundleEncoder);
5948
6028
  this.renderBundle = renderBundleEncoder.finish();
5949
6029
  }
5950
- createSphereRenderable(radius, widthSegments = 32, heightSegments = 16, randomness = 0) {
5951
- const sphereMesh = this.createCubeVertices();
6030
+ createGeometry(options) {
6031
+ const mesh = this.createCubeVertices(options);
5952
6032
  // Create a vertex buffer from the sphere data.
5953
6033
  const vertices = this.device.createBuffer({
5954
- size: sphereMesh.vertices.byteLength,
6034
+ size: mesh.vertices.byteLength,
5955
6035
  usage: GPUBufferUsage.VERTEX,
5956
6036
  mappedAtCreation: true
5957
6037
  });
5958
- new Float32Array(vertices.getMappedRange()).set(sphereMesh.vertices);
6038
+ new Float32Array(vertices.getMappedRange()).set(mesh.vertices);
5959
6039
  vertices.unmap();
5960
6040
  const indices = this.device.createBuffer({
5961
- size: sphereMesh.indices.byteLength,
6041
+ size: mesh.indices.byteLength,
5962
6042
  usage: GPUBufferUsage.INDEX,
5963
6043
  mappedAtCreation: true
5964
6044
  });
5965
- new Uint16Array(indices.getMappedRange()).set(sphereMesh.indices);
6045
+ new Uint16Array(indices.getMappedRange()).set(mesh.indices);
5966
6046
  indices.unmap();
5967
6047
  return {
5968
6048
  vertices,
5969
6049
  indices,
5970
- indexCount: sphereMesh.indices.length
6050
+ indexCount: mesh.indices.length
5971
6051
  };
5972
6052
  }
5973
6053
  createSphereBindGroup(texture, transform) {
@@ -5997,12 +6077,17 @@ class MECube {
5997
6077
  return bindGroup;
5998
6078
  }
5999
6079
  getTransformationMatrix(pos) {
6000
- const viewMatrix = _wgpuMatrix.mat4.identity();
6080
+ const now = Date.now();
6081
+ const deltaTime = (now - this.lastFrameMS) / this.cameraParams.responseCoef;
6082
+ this.lastFrameMS = now;
6083
+
6084
+ // const viewMatrix = mat4.identity(); ORI
6085
+ const camera = this.cameras[this.cameraParams.type];
6086
+ const viewMatrix = camera.update(deltaTime, this.inputHandler());
6001
6087
  _wgpuMatrix.mat4.translate(viewMatrix, _wgpuMatrix.vec3.fromValues(pos.x, pos.y, pos.z), viewMatrix);
6002
- const now = Date.now() / 1000;
6003
- _wgpuMatrix.mat4.rotateZ(viewMatrix, Math.PI * 0, viewMatrix);
6004
- _wgpuMatrix.mat4.rotateX(viewMatrix, Math.PI * 0, viewMatrix);
6005
- _wgpuMatrix.mat4.rotateY(viewMatrix, -45, viewMatrix);
6088
+ _wgpuMatrix.mat4.rotateX(viewMatrix, Math.PI * this.rotation.getRotX(), viewMatrix);
6089
+ _wgpuMatrix.mat4.rotateY(viewMatrix, Math.PI * this.rotation.getRotY(), viewMatrix);
6090
+ _wgpuMatrix.mat4.rotateZ(viewMatrix, Math.PI * this.rotation.getRotZ(), viewMatrix);
6006
6091
  _wgpuMatrix.mat4.multiply(this.projectionMatrix, viewMatrix, this.modelViewProjectionMatrix);
6007
6092
  return this.modelViewProjectionMatrix;
6008
6093
  }
@@ -6075,6 +6160,7 @@ class MECube {
6075
6160
  useUVShema4x2: false
6076
6161
  };
6077
6162
  }
6163
+ if (typeof options.scale === 'undefined') options.scale = 1;
6078
6164
  let vertices;
6079
6165
  if (options.useUVShema4x2 == true) {
6080
6166
  vertices = new Float32Array([
@@ -6094,20 +6180,20 @@ class MECube {
6094
6180
  -1, 1, 1, 1, 0, 0, 0.5, 0.5, 1, 1, 1, 1, 0, 0, 0.75, 0.5, -1, 1, -1, 1, 0, 0, 0.5, 1, 1, 1, -1, 1, 0, 0, 0.75, 1]);
6095
6181
  } else {
6096
6182
  vertices = new Float32Array([
6097
- // position | texture coordinate
6098
- //-------------+----------------------
6183
+ // position | texture coordinate
6184
+ //------------- +----------------------
6099
6185
  // front face select the top left image 1, 0.5,
6100
- -1, 1, 1, 1, 0, 0, 0, 0, -1, -1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, -1, 1, 1, 0, 0, 1, 1,
6186
+ -1 * options.scale, 1 * options.scale, 1 * options.scale, 1, 0, 0, 0, 0, -1 * options.scale, -1 * options.scale, 1 * options.scale, 1, 0, 0, 0, 1, 1 * options.scale, 1 * options.scale, 1 * options.scale, 1, 0, 0, 1, 0, 1 * options.scale, -1 * options.scale, 1 * options.scale, 1, 0, 0, 1, 1,
6101
6187
  // right face select the top middle image
6102
- 1, 1, -1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, -1, -1, 1, 0, 0, 1, 0, 1, -1, 1, 1, 0, 0, 1, 1,
6188
+ 1 * options.scale, 1 * options.scale, -1 * options.scale, 1, 0, 0, 0, 0, 1 * options.scale, 1 * options.scale, 1 * options.scale, 1, 0, 0, 0, 1, 1 * options.scale, -1 * options.scale, -1 * options.scale, 1, 0, 0, 1, 0, 1 * options.scale, -1 * options.scale, 1 * options.scale, 1, 0, 0, 1, 1,
6103
6189
  // back face select to top right image
6104
- 1, 1, -1, 1, 0, 0, 0, 0, 1, -1, -1, 1, 0, 0, 0, 1, -1, 1, -1, 1, 0, 0, 1, 0, -1, -1, -1, 1, 0, 0, 1, 1,
6190
+ 1 * options.scale, 1 * options.scale, -1 * options.scale, 1, 0, 0, 0, 0, 1 * options.scale, -1 * options.scale, -1 * options.scale, 1, 0, 0, 0, 1, -1 * options.scale, 1 * options.scale, -1 * options.scale, 1, 0, 0, 1, 0, -1 * options.scale, -1 * options.scale, -1 * options.scale, 1, 0, 0, 1, 1,
6105
6191
  // left face select the bottom left image
6106
- -1, 1, 1, 1, 0, 0, 0, 0, -1, 1, -1, 1, 0, 0, 0, 1, -1, -1, 1, 1, 0, 0, 1, 0, -1, -1, -1, 1, 0, 0, 1, 1,
6192
+ -1 * options.scale, 1 * options.scale, 1 * options.scale, 1, 0, 0, 0, 0, -1 * options.scale, 1 * options.scale, -1 * options.scale, 1, 0, 0, 0, 1, -1 * options.scale, -1 * options.scale, 1 * options.scale, 1, 0, 0, 1, 0, -1 * options.scale, -1 * options.scale, -1 * options.scale, 1, 0, 0, 1, 1,
6107
6193
  // bottom face select the bottom middle image
6108
- 1, -1, 1, 1, 0, 0, 0, 0, -1, -1, 1, 1, 0, 0, 0, 1, 1, -1, -1, 1, 0, 0, 1, 0, -1, -1, -1, 1, 0, 0, 1, 1,
6194
+ 1 * options.scale, -1 * options.scale, 1 * options.scale, 1, 0, 0, 0, 0, -1 * options.scale, -1 * options.scale, 1 * options.scale, 1, 0, 0, 0, 1, 1 * options.scale, -1 * options.scale, -1 * options.scale, 1, 0, 0, 1, 0, -1 * options.scale, -1 * options.scale, -1 * options.scale, 1, 0, 0, 1, 1,
6109
6195
  // top face select the bottom right image
6110
- -1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, -1, 1, -1, 1, 0, 0, 1, 0, 1, 1, -1, 1, 0, 0, 1, 1]);
6196
+ -1 * options.scale, 1 * options.scale, 1 * options.scale, 1, 0, 0, 0, 0, 1 * options.scale, 1 * options.scale, 1 * options.scale, 1, 0, 0, 0, 1, -1 * options.scale, 1 * options.scale, -1 * options.scale, 1, 0, 0, 1, 0, 1 * options.scale, 1 * options.scale, -1 * options.scale, 1, 0, 0, 1, 1]);
6111
6197
  }
6112
6198
  const indices = new Uint16Array([0, 1, 2, 2, 1, 3,
6113
6199
  // front
@@ -6139,15 +6225,942 @@ class MECube {
6139
6225
  }
6140
6226
  exports.default = MECube;
6141
6227
 
6142
- },{"../shaders/shaders":7,"./matrix-class":5,"wgpu-matrix":2}],5:[function(require,module,exports){
6228
+ },{"../shaders/shaders":12,"./engine":5,"./matrix-class":7,"wgpu-matrix":2}],5:[function(require,module,exports){
6143
6229
  "use strict";
6144
6230
 
6145
6231
  Object.defineProperty(exports, "__esModule", {
6146
6232
  value: true
6147
6233
  });
6148
- exports.Position = void 0;
6149
- // Sub classes for matrix-wgpu
6234
+ exports.WASDCamera = exports.ArcballCamera = void 0;
6235
+ exports.createInputHandler = createInputHandler;
6236
+ var _wgpuMatrix = require("wgpu-matrix");
6237
+ // Note: The code in this file does not use the 'dst' output parameter of functions in the
6238
+ // 'wgpu-matrix' library, so produces many temporary vectors and matrices.
6239
+ // This is intentional, as this sample prefers readability over performance.
6240
+
6241
+ // import Input from './input';
6242
+
6243
+ // // Common interface for camera implementations
6244
+ // export default interface Camera {
6245
+ // // update updates the camera using the user-input and returns the view matrix.
6246
+ // update(delta_time: number, input: Input): Mat4;
6247
+
6248
+ // // The camera matrix.
6249
+ // // This is the inverse of the view matrix.
6250
+ // matrix: Mat4;
6251
+ // // Alias to column vector 0 of the camera matrix.
6252
+ // right: Vec4;
6253
+ // // Alias to column vector 1 of the camera matrix.
6254
+ // up: Vec4;
6255
+ // // Alias to column vector 2 of the camera matrix.
6256
+ // back: Vec4;
6257
+ // // Alias to column vector 3 of the camera matrix.
6258
+ // position: Vec4;
6259
+ // }
6260
+
6261
+ // The common functionality between camera implementations
6262
+ class CameraBase {
6263
+ // The camera matrix
6264
+ matrix_ = new Float32Array([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]);
6265
+
6266
+ // The calculated view matrix readonly
6267
+ view_ = _wgpuMatrix.mat4.create();
6268
+
6269
+ // Aliases to column vectors of the matrix
6270
+ right_ = new Float32Array(this.matrix_.buffer, 4 * 0, 4);
6271
+ up_ = new Float32Array(this.matrix_.buffer, 4 * 4, 4);
6272
+ back_ = new Float32Array(this.matrix_.buffer, 4 * 8, 4);
6273
+ position_ = new Float32Array(this.matrix_.buffer, 4 * 12, 4);
6274
+
6275
+ // Returns the camera matrix
6276
+ get matrix() {
6277
+ return this.matrix_;
6278
+ }
6279
+ // Assigns `mat` to the camera matrix
6280
+ set matrix(mat) {
6281
+ _wgpuMatrix.mat4.copy(mat, this.matrix_);
6282
+ }
6283
+
6284
+ // Returns the camera view matrix
6285
+ get view() {
6286
+ return this.view_;
6287
+ }
6288
+ // Assigns `mat` to the camera view
6289
+ set view(mat) {
6290
+ _wgpuMatrix.mat4.copy(mat, this.view_);
6291
+ }
6292
+
6293
+ // Returns column vector 0 of the camera matrix
6294
+ get right() {
6295
+ return this.right_;
6296
+ }
6297
+ // Assigns `vec` to the first 3 elements of column vector 0 of the camera matrix
6298
+ set right(vec) {
6299
+ _wgpuMatrix.vec3.copy(vec, this.right_);
6300
+ }
6301
+
6302
+ // Returns column vector 1 of the camera matrix
6303
+ get up() {
6304
+ return this.up_;
6305
+ }
6306
+ // Assigns `vec` to the first 3 elements of column vector 1 of the camera matrix \ Vec3
6307
+ set up(vec) {
6308
+ _wgpuMatrix.vec3.copy(vec, this.up_);
6309
+ }
6310
+
6311
+ // Returns column vector 2 of the camera matrix
6312
+ get back() {
6313
+ return this.back_;
6314
+ }
6315
+ // Assigns `vec` to the first 3 elements of column vector 2 of the camera matrix
6316
+ set back(vec) {
6317
+ _wgpuMatrix.vec3.copy(vec, this.back_);
6318
+ }
6319
+
6320
+ // Returns column vector 3 of the camera matrix
6321
+ get position() {
6322
+ return this.position_;
6323
+ }
6324
+ // Assigns `vec` to the first 3 elements of column vector 3 of the camera matrix
6325
+ set position(vec) {
6326
+ _wgpuMatrix.vec3.copy(vec, this.position_);
6327
+ }
6328
+ }
6329
+
6330
+ // WASDCamera is a camera implementation that behaves similar to first-person-shooter PC games.
6331
+ class WASDCamera extends CameraBase {
6332
+ // The camera absolute pitch angle
6333
+ pitch = 0;
6334
+ // The camera absolute yaw angle
6335
+ yaw = 0;
6336
+
6337
+ // The movement veloicty readonly
6338
+ velocity_ = _wgpuMatrix.vec3.create();
6339
+
6340
+ // Speed multiplier for camera movement
6341
+ movementSpeed = 10;
6342
+
6343
+ // Speed multiplier for camera rotation
6344
+ rotationSpeed = 1;
6345
+
6346
+ // Movement velocity drag coeffient [0 .. 1]
6347
+ // 0: Continues forever
6348
+ // 1: Instantly stops moving
6349
+ frictionCoefficient = 0.99;
6350
+
6351
+ // Returns velocity vector
6352
+ get velocity() {
6353
+ return this.velocity_;
6354
+ }
6355
+ // Assigns `vec` to the velocity vector
6356
+ set velocity(vec) {
6357
+ _wgpuMatrix.vec3.copy(vec, this.velocity_);
6358
+ }
6359
+
6360
+ // Construtor
6361
+ constructor(options) {
6362
+ super();
6363
+ if (options && (options.position || options.target)) {
6364
+ const position = options.position ?? _wgpuMatrix.vec3.create(0, 0, 0);
6365
+ const target = options.target ?? _wgpuMatrix.vec3.create(0, 0, 0);
6366
+ const forward = _wgpuMatrix.vec3.normalize(_wgpuMatrix.vec3.sub(target, position));
6367
+ this.recalculateAngles(forward);
6368
+ this.position = position;
6369
+ console.log('camera postion:', position);
6370
+ }
6371
+ }
6372
+
6373
+ // Returns the camera matrix
6374
+ get matrix() {
6375
+ return super.matrix;
6376
+ }
6377
+
6378
+ // Assigns `mat` to the camera matrix, and recalcuates the camera angles
6379
+ set matrix(mat) {
6380
+ super.matrix = mat;
6381
+ this.recalculateAngles(this.back);
6382
+ }
6383
+ update(deltaTime, input) {
6384
+ const sign = (positive, negative) => (positive ? 1 : 0) - (negative ? 1 : 0);
6385
+
6386
+ // Apply the delta rotation to the pitch and yaw angles
6387
+ this.yaw -= input.analog.x * deltaTime * this.rotationSpeed;
6388
+ this.pitch -= input.analog.y * deltaTime * this.rotationSpeed;
6389
+
6390
+ // Wrap yaw between [0° .. 360°], just to prevent large accumulation.
6391
+ this.yaw = mod(this.yaw, Math.PI * 2);
6392
+ // Clamp pitch between [-90° .. +90°] to prevent somersaults.
6393
+ this.pitch = clamp(this.pitch, -Math.PI / 2, Math.PI / 2);
6394
+
6395
+ // Save the current position, as we're about to rebuild the camera matrix.
6396
+ const position = _wgpuMatrix.vec3.copy(this.position);
6397
+
6398
+ // Reconstruct the camera's rotation, and store into the camera matrix.
6399
+ super.matrix = _wgpuMatrix.mat4.rotateX(_wgpuMatrix.mat4.rotationY(this.yaw), this.pitch);
6400
+
6401
+ // Calculate the new target velocity
6402
+ const digital = input.digital;
6403
+ const deltaRight = sign(digital.right, digital.left);
6404
+ const deltaUp = sign(digital.up, digital.down);
6405
+ const targetVelocity = _wgpuMatrix.vec3.create();
6406
+ const deltaBack = sign(digital.backward, digital.forward);
6407
+ _wgpuMatrix.vec3.addScaled(targetVelocity, this.right, deltaRight, targetVelocity);
6408
+ _wgpuMatrix.vec3.addScaled(targetVelocity, this.up, deltaUp, targetVelocity);
6409
+ _wgpuMatrix.vec3.addScaled(targetVelocity, this.back, deltaBack, targetVelocity);
6410
+ _wgpuMatrix.vec3.normalize(targetVelocity, targetVelocity);
6411
+ _wgpuMatrix.vec3.mulScalar(targetVelocity, this.movementSpeed, targetVelocity);
6412
+
6413
+ // Mix new target velocity
6414
+ this.velocity = lerp(targetVelocity, this.velocity, Math.pow(1 - this.frictionCoefficient, deltaTime));
6415
+
6416
+ // Integrate velocity to calculate new position
6417
+ this.position = _wgpuMatrix.vec3.addScaled(position, this.velocity, deltaTime);
6418
+
6419
+ // Invert the camera matrix to build the view matrix
6420
+ this.view = _wgpuMatrix.mat4.invert(this.matrix);
6421
+ return this.view;
6422
+ }
6423
+
6424
+ // Recalculates the yaw and pitch values from a directional vector
6425
+ recalculateAngles(dir) {
6426
+ this.yaw = Math.atan2(dir[0], dir[2]);
6427
+ this.pitch = -Math.asin(dir[1]);
6428
+ }
6429
+ }
6430
+
6431
+ // ArcballCamera implements a basic orbiting camera around the world origin
6432
+ exports.WASDCamera = WASDCamera;
6433
+ class ArcballCamera extends CameraBase {
6434
+ // The camera distance from the target
6435
+ distance = 0;
6436
+
6437
+ // The current angular velocity
6438
+ angularVelocity = 0;
6439
+
6440
+ // The current rotation axis
6441
+ axis_ = _wgpuMatrix.vec3.create();
6442
+
6443
+ // Returns the rotation axis
6444
+ get axis() {
6445
+ return this.axis_;
6446
+ }
6447
+ // Assigns `vec` to the rotation axis
6448
+ set axis(vec) {
6449
+ _wgpuMatrix.vec3.copy(vec, this.axis_);
6450
+ }
6451
+
6452
+ // Speed multiplier for camera rotation
6453
+ rotationSpeed = 1;
6454
+
6455
+ // Speed multiplier for camera zoom
6456
+ zoomSpeed = 0.1;
6457
+
6458
+ // Rotation velocity drag coeffient [0 .. 1]
6459
+ // 0: Spins forever
6460
+ // 1: Instantly stops spinning
6461
+ frictionCoefficient = 0.999;
6462
+
6463
+ // Construtor
6464
+ constructor(options) {
6465
+ super();
6466
+ if (options && options.position) {
6467
+ this.position = options.position;
6468
+ this.distance = _wgpuMatrix.vec3.len(this.position);
6469
+ this.back = _wgpuMatrix.vec3.normalize(this.position);
6470
+ this.recalcuateRight();
6471
+ this.recalcuateUp();
6472
+ }
6473
+ }
6474
+
6475
+ // Returns the camera matrix
6476
+ get matrix() {
6477
+ return super.matrix;
6478
+ }
6479
+
6480
+ // Assigns `mat` to the camera matrix, and recalcuates the distance
6481
+ set matrix(mat) {
6482
+ super.matrix = mat;
6483
+ this.distance = _wgpuMatrix.vec3.len(this.position);
6484
+ }
6485
+ update(deltaTime, input) {
6486
+ const epsilon = 0.0000001;
6487
+ if (input.analog.touching) {
6488
+ // Currently being dragged.
6489
+ this.angularVelocity = 0;
6490
+ } else {
6491
+ // Dampen any existing angular velocity
6492
+ this.angularVelocity *= Math.pow(1 - this.frictionCoefficient, deltaTime);
6493
+ }
6494
+
6495
+ // Calculate the movement vector
6496
+ const movement = _wgpuMatrix.vec3.create();
6497
+ _wgpuMatrix.vec3.addScaled(movement, this.right, input.analog.x, movement);
6498
+ _wgpuMatrix.vec3.addScaled(movement, this.up, -input.analog.y, movement);
6499
+
6500
+ // Cross the movement vector with the view direction to calculate the rotation axis x magnitude
6501
+ const crossProduct = _wgpuMatrix.vec3.cross(movement, this.back);
6502
+
6503
+ // Calculate the magnitude of the drag
6504
+ const magnitude = _wgpuMatrix.vec3.len(crossProduct);
6505
+ if (magnitude > epsilon) {
6506
+ // Normalize the crossProduct to get the rotation axis
6507
+ this.axis = _wgpuMatrix.vec3.scale(crossProduct, 1 / magnitude);
6508
+
6509
+ // Remember the current angular velocity. This is used when the touch is released for a fling.
6510
+ this.angularVelocity = magnitude * this.rotationSpeed;
6511
+ }
6512
+
6513
+ // The rotation around this.axis to apply to the camera matrix this update
6514
+ const rotationAngle = this.angularVelocity * deltaTime;
6515
+ if (rotationAngle > epsilon) {
6516
+ // Rotate the matrix around axis
6517
+ // Note: The rotation is not done as a matrix-matrix multiply as the repeated multiplications
6518
+ // will quickly introduce substantial error into the matrix.
6519
+ this.back = _wgpuMatrix.vec3.normalize(rotate(this.back, this.axis, rotationAngle));
6520
+ this.recalcuateRight();
6521
+ this.recalcuateUp();
6522
+ }
6523
+
6524
+ // recalculate `this.position` from `this.back` considering zoom
6525
+ if (input.analog.zoom !== 0) {
6526
+ this.distance *= 1 + input.analog.zoom * this.zoomSpeed;
6527
+ }
6528
+ this.position = _wgpuMatrix.vec3.scale(this.back, this.distance);
6529
+
6530
+ // Invert the camera matrix to build the view matrix
6531
+ this.view = _wgpuMatrix.mat4.invert(this.matrix);
6532
+ return this.view;
6533
+ }
6534
+
6535
+ // Assigns `this.right` with the cross product of `this.up` and `this.back`
6536
+ recalcuateRight() {
6537
+ this.right = _wgpuMatrix.vec3.normalize(_wgpuMatrix.vec3.cross(this.up, this.back));
6538
+ }
6539
+
6540
+ // Assigns `this.up` with the cross product of `this.back` and `this.right`
6541
+ recalcuateUp() {
6542
+ this.up = _wgpuMatrix.vec3.normalize(_wgpuMatrix.vec3.cross(this.back, this.right));
6543
+ }
6544
+ }
6545
+
6546
+ // Returns `x` clamped between [`min` .. `max`]
6547
+ exports.ArcballCamera = ArcballCamera;
6548
+ function clamp(x, min, max) {
6549
+ return Math.min(Math.max(x, min), max);
6550
+ }
6551
+
6552
+ // Returns `x` float-modulo `div`
6553
+ function mod(x, div) {
6554
+ return x - Math.floor(Math.abs(x) / div) * div * Math.sign(x);
6555
+ }
6556
+
6557
+ // Returns `vec` rotated `angle` radians around `axis`
6558
+ function rotate(vec, axis, angle) {
6559
+ return _wgpuMatrix.vec3.transformMat4Upper3x3(vec, _wgpuMatrix.mat4.rotation(axis, angle));
6560
+ }
6150
6561
 
6562
+ // Returns the linear interpolation between 'a' and 'b' using 's'
6563
+ function lerp(a, b, s) {
6564
+ return _wgpuMatrix.vec3.addScaled(a, _wgpuMatrix.vec3.sub(b, a), s);
6565
+ }
6566
+
6567
+ // IMPUT
6568
+
6569
+ // // Input holds as snapshot of input state
6570
+ // export default interface Input {
6571
+ // // Digital input (e.g keyboard state)
6572
+ // readonly digital: {
6573
+ // readonly forward: boolean;
6574
+ // readonly backward: boolean;
6575
+ // readonly left: boolean;
6576
+ // readonly right: boolean;
6577
+ // readonly up: boolean;
6578
+ // readonly down: boolean;
6579
+ // };
6580
+ // // Analog input (e.g mouse, touchscreen)
6581
+ // readonly analog: {
6582
+ // readonly x: number;
6583
+ // readonly y: number;
6584
+ // readonly zoom: number;
6585
+ // readonly touching: boolean;
6586
+ // };
6587
+ // }
6588
+
6589
+ // InputHandler is a function that when called, returns the current Input state.
6590
+ // export type InputHandler = () => Input;
6591
+
6592
+ // createInputHandler returns an InputHandler by attaching event handlers to the window and canvas.
6593
+ function createInputHandler(window, canvas) {
6594
+ let digital = {
6595
+ forward: false,
6596
+ backward: false,
6597
+ left: false,
6598
+ right: false,
6599
+ up: false,
6600
+ down: false
6601
+ };
6602
+ let analog = {
6603
+ x: 0,
6604
+ y: 0,
6605
+ zoom: 0
6606
+ };
6607
+ let mouseDown = false;
6608
+ const setDigital = (e, value) => {
6609
+ switch (e.code) {
6610
+ case 'KeyW':
6611
+ digital.forward = value;
6612
+ e.preventDefault();
6613
+ e.stopPropagation();
6614
+ break;
6615
+ case 'KeyS':
6616
+ digital.backward = value;
6617
+ e.preventDefault();
6618
+ e.stopPropagation();
6619
+ break;
6620
+ case 'KeyA':
6621
+ digital.left = value;
6622
+ e.preventDefault();
6623
+ e.stopPropagation();
6624
+ break;
6625
+ case 'KeyD':
6626
+ digital.right = value;
6627
+ e.preventDefault();
6628
+ e.stopPropagation();
6629
+ break;
6630
+ case 'Space':
6631
+ digital.up = value;
6632
+ e.preventDefault();
6633
+ e.stopPropagation();
6634
+ break;
6635
+ case 'ShiftLeft':
6636
+ case 'ControlLeft':
6637
+ case 'KeyC':
6638
+ digital.down = value;
6639
+ e.preventDefault();
6640
+ e.stopPropagation();
6641
+ break;
6642
+ }
6643
+ };
6644
+ window.addEventListener('keydown', e => setDigital(e, true));
6645
+ window.addEventListener('keyup', e => setDigital(e, false));
6646
+ canvas.style.touchAction = 'pinch-zoom';
6647
+ canvas.addEventListener('pointerdown', () => {
6648
+ mouseDown = true;
6649
+ });
6650
+ canvas.addEventListener('pointerup', () => {
6651
+ mouseDown = false;
6652
+ });
6653
+ canvas.addEventListener('pointermove', e => {
6654
+ mouseDown = e.pointerType == 'mouse' ? (e.buttons & 1) !== 0 : true;
6655
+ if (mouseDown) {
6656
+ // console.log('TEST ', analog)
6657
+ analog.x += e.movementX / 10;
6658
+ analog.y += e.movementY / 10;
6659
+ }
6660
+ });
6661
+ canvas.addEventListener('wheel', e => {
6662
+ mouseDown = (e.buttons & 1) !== 0;
6663
+ if (mouseDown) {
6664
+ // The scroll value varies substantially between user agents / browsers.
6665
+ // Just use the sign.
6666
+ analog.zoom += Math.sign(e.deltaY);
6667
+ e.preventDefault();
6668
+ e.stopPropagation();
6669
+ }
6670
+ }, {
6671
+ passive: false
6672
+ });
6673
+ return () => {
6674
+ const out = {
6675
+ digital,
6676
+ analog: {
6677
+ x: analog.x,
6678
+ y: analog.y,
6679
+ zoom: analog.zoom,
6680
+ touching: mouseDown
6681
+ }
6682
+ };
6683
+ // Clear the analog values, as these accumulate.
6684
+ analog.x = 0;
6685
+ analog.y = 0;
6686
+ analog.zoom = 0;
6687
+ return out;
6688
+ };
6689
+ }
6690
+
6691
+ },{"wgpu-matrix":2}],6:[function(require,module,exports){
6692
+ "use strict";
6693
+
6694
+ Object.defineProperty(exports, "__esModule", {
6695
+ value: true
6696
+ });
6697
+ exports.makeObjSeqArg = exports.initMeshBuffers = exports.downloadMeshes = exports.constructMesh = void 0;
6698
+ exports.play = play;
6699
+ /**
6700
+ * The main Mesh class. The constructor will parse through the OBJ file data
6701
+ * and collect the vertex, vertex normal, texture, and face information. This
6702
+ * information can then be used later on when creating your VBOs. See
6703
+ * OBJ.initMeshBuffers for an example of how to use the newly created Mesh
6704
+ *
6705
+ * @class Mesh
6706
+ * @constructor
6707
+ *
6708
+ * @param {String} objectData a string representation of an OBJ file with newlines preserved.
6709
+ */
6710
+
6711
+ class constructMesh {
6712
+ constructor(objectData, inputArg) {
6713
+ this.inputArg = inputArg;
6714
+ this.objectData = objectData;
6715
+ this.create(objectData, inputArg);
6716
+ this.setScale = s => {
6717
+ this.inputArg.scale = s;
6718
+ this.create(this.objectData, this.inputArg);
6719
+ };
6720
+ this.updateBuffers = () => {
6721
+ this.inputArg.scale = 1;
6722
+ this.create(this.objectData, this.inputArg);
6723
+ };
6724
+ }
6725
+ create = (objectData, inputArg, callback) => {
6726
+ if (typeof callback === 'undefined') callback = function () {};
6727
+ let initOrientation = [0, 1, 2];
6728
+ /*
6729
+ The OBJ file format does a sort of compression when saving a model in a
6730
+ program like Blender. There are at least 3 sections (4 including textures)
6731
+ within the file. Each line in a section begins with the same string:
6732
+ * 'v': indicates vertex section
6733
+ * 'vn': indicates vertex normal section
6734
+ * 'f': indicates the faces section
6735
+ * 'vt': indicates vertex texture section (if textures were used on the model)
6736
+ Each of the above sections (except for the faces section) is a list/set of
6737
+ unique vertices.
6738
+ Each line of the faces section contains a list of
6739
+ (vertex, [texture], normal) groups
6740
+ Some examples:
6741
+ // the texture index is optional, both formats are possible for models
6742
+ // without a texture applied
6743
+ f 1/25 18/46 12/31
6744
+ f 1//25 18//46 12//31
6745
+ // A 3 vertex face with texture indices
6746
+ f 16/92/11 14/101/22 1/69/1
6747
+ // A 4 vertex face
6748
+ f 16/92/11 40/109/40 38/114/38 14/101/22
6749
+ The first two lines are examples of a 3 vertex face without a texture applied.
6750
+ The second is an example of a 3 vertex face with a texture applied.
6751
+ The third is an example of a 4 vertex face. Note: a face can contain N
6752
+ number of vertices.
6753
+ Each number that appears in one of the groups is a 1-based index
6754
+ corresponding to an item from the other sections (meaning that indexing
6755
+ starts at one and *not* zero).
6756
+ For example:
6757
+ `f 16/92/11` is saying to
6758
+ - take the 16th element from the [v] vertex array
6759
+ - take the 92nd element from the [vt] texture array
6760
+ - take the 11th element from the [vn] normal array
6761
+ and together they make a unique vertex.
6762
+ Using all 3+ unique Vertices from the face line will produce a polygon.
6763
+ Now, you could just go through the OBJ file and create a new vertex for
6764
+ each face line and WebGL will draw what appears to be the same model.
6765
+ However, vertices will be overlapped and duplicated all over the place.
6766
+ Consider a cube in 3D space centered about the origin and each side is
6767
+ 2 units long. The front face (with the positive Z-axis pointing towards
6768
+ you) would have a Top Right vertex (looking orthogonal to its normal)
6769
+ mapped at (1,1,1) The right face would have a Top Left vertex (looking
6770
+ orthogonal to its normal) at (1,1,1) and the top face would have a Bottom
6771
+ Right vertex (looking orthogonal to its normal) at (1,1,1). Each face
6772
+ has a vertex at the same coordinates, however, three distinct vertices
6773
+ will be drawn at the same spot.
6774
+ To solve the issue of duplicate Vertices (the `(vertex, [texture], normal)`
6775
+ groups), while iterating through the face lines, when a group is encountered
6776
+ the whole group string ('16/92/11') is checked to see if it exists in the
6777
+ packed.hashindices object, and if it doesn't, the indices it specifies
6778
+ are used to look up each attribute in the corresponding attribute arrays
6779
+ already created. The values are then copied to the corresponding unpacked
6780
+ array (flattened to play nice with WebGL's ELEMENT_ARRAY_BUFFER indexing),
6781
+ the group string is added to the hashindices set and the current unpacked
6782
+ index is used as this hashindices value so that the group of elements can
6783
+ be reused. The unpacked index is incremented. If the group string already
6784
+ exists in the hashindices object, its corresponding value is the index of
6785
+ that group and is appended to the unpacked indices array.
6786
+ */
6787
+ var verts = [],
6788
+ vertNormals = [],
6789
+ textures = [],
6790
+ unpacked = {};
6791
+ // unpacking stuff
6792
+ unpacked.verts = [];
6793
+ unpacked.norms = [];
6794
+ unpacked.textures = [];
6795
+ unpacked.hashindices = {};
6796
+ unpacked.indices = [];
6797
+ unpacked.index = 0;
6798
+ // array of lines separated by the newline
6799
+ var lines = objectData.split('\n');
6800
+
6801
+ // update swap orientation
6802
+ if (inputArg.swap[0] !== null) {
6803
+ swap(inputArg.swap[0], inputArg.swap[1], initOrientation);
6804
+ }
6805
+ var VERTEX_RE = /^v\s/;
6806
+ var NORMAL_RE = /^vn\s/;
6807
+ var TEXTURE_RE = /^vt\s/;
6808
+ var FACE_RE = /^f\s/;
6809
+ var WHITESPACE_RE = /\s+/;
6810
+ for (var i = 0; i < lines.length; i++) {
6811
+ var line = lines[i].trim();
6812
+ var elements = line.split(WHITESPACE_RE);
6813
+ elements.shift();
6814
+ if (VERTEX_RE.test(line)) {
6815
+ // if this is a vertex
6816
+ verts.push.apply(verts, elements);
6817
+ } else if (NORMAL_RE.test(line)) {
6818
+ // if this is a vertex normal
6819
+ vertNormals.push.apply(vertNormals, elements);
6820
+ } else if (TEXTURE_RE.test(line)) {
6821
+ // if this is a texture
6822
+ textures.push.apply(textures, elements);
6823
+ } else if (FACE_RE.test(line)) {
6824
+ // if this is a face
6825
+ /*
6826
+ split this face into an array of vertex groups
6827
+ for example:
6828
+ f 16/92/11 14/101/22 1/69/1
6829
+ becomes:
6830
+ ['16/92/11', '14/101/22', '1/69/1'];
6831
+ */
6832
+ var quad = false;
6833
+ for (var j = 0, eleLen = elements.length; j < eleLen; j++) {
6834
+ // Triangulating quads
6835
+ // quad: 'f v0/t0/vn0 v1/t1/vn1 v2/t2/vn2 v3/t3/vn3/'
6836
+ // corresponding triangles:
6837
+ // 'f v0/t0/vn0 v1/t1/vn1 v2/t2/vn2'
6838
+ // 'f v2/t2/vn2 v3/t3/vn3 v0/t0/vn0'
6839
+ if (j === 3 && !quad) {
6840
+ // add v2/t2/vn2 in again before continuing to 3
6841
+ j = 2;
6842
+ quad = true;
6843
+ }
6844
+ if (elements[j] in unpacked.hashindices) {
6845
+ unpacked.indices.push(unpacked.hashindices[elements[j]]);
6846
+ } else {
6847
+ /*
6848
+ Each element of the face line array is a vertex which has its
6849
+ attributes delimited by a forward slash. This will separate
6850
+ each attribute into another array:
6851
+ '19/92/11'
6852
+ becomes:
6853
+ vertex = ['19', '92', '11'];
6854
+ where
6855
+ vertex[0] is the vertex index
6856
+ vertex[1] is the texture index
6857
+ vertex[2] is the normal index
6858
+ Think of faces having Vertices which are comprised of the
6859
+ attributes location (v), texture (vt), and normal (vn).
6860
+ */
6861
+ var vertex = elements[j].split('/');
6862
+ /*
6863
+ The verts, textures, and vertNormals arrays each contain a
6864
+ flattend array of coordinates.
6865
+ Because it gets confusing by referring to vertex and then
6866
+ vertex (both are different in my descriptions) I will explain
6867
+ what's going on using the vertexNormals array:
6868
+ vertex[2] will contain the one-based index of the vertexNormals
6869
+ section (vn). One is subtracted from this index number to play
6870
+ nice with javascript's zero-based array indexing.
6871
+ Because vertexNormal is a flattened array of x, y, z values,
6872
+ simple pointer arithmetic is used to skip to the start of the
6873
+ vertexNormal, then the offset is added to get the correct
6874
+ component: +0 is x, +1 is y, +2 is z.
6875
+ This same process is repeated for verts and textures.
6876
+ */
6877
+ // vertex position
6878
+ unpacked.verts.push(+verts[(vertex[0] - 1) * 3 + initOrientation[0]] * inputArg.scale);
6879
+ unpacked.verts.push(+verts[(vertex[0] - 1) * 3 + initOrientation[1]] * inputArg.scale);
6880
+ unpacked.verts.push(+verts[(vertex[0] - 1) * 3 + initOrientation[2]] * inputArg.scale);
6881
+
6882
+ // vertex textures
6883
+ if (textures.length) {
6884
+ unpacked.textures.push(+textures[(vertex[1] - 1) * 2 + 0]);
6885
+ unpacked.textures.push(+textures[(vertex[1] - 1) * 2 + 1]);
6886
+ }
6887
+ // vertex normals
6888
+ unpacked.norms.push(+vertNormals[(vertex[2] - 1) * 3 + 0]);
6889
+ unpacked.norms.push(+vertNormals[(vertex[2] - 1) * 3 + 1]);
6890
+ unpacked.norms.push(+vertNormals[(vertex[2] - 1) * 3 + 2]);
6891
+ // add the newly created vertex to the list of indices
6892
+ unpacked.hashindices[elements[j]] = unpacked.index;
6893
+ unpacked.indices.push(unpacked.index);
6894
+ // increment the counter
6895
+ unpacked.index += 1;
6896
+ }
6897
+ if (j === 3 && quad) {
6898
+ // add v0/t0/vn0 onto the second triangle
6899
+ unpacked.indices.push(unpacked.hashindices[elements[0]]);
6900
+ }
6901
+ }
6902
+ }
6903
+ }
6904
+ this.vertices = unpacked.verts;
6905
+ this.vertexNormals = unpacked.norms;
6906
+ this.textures = unpacked.textures;
6907
+ this.indices = unpacked.indices;
6908
+ callback();
6909
+ return this;
6910
+ };
6911
+ }
6912
+ exports.constructMesh = constructMesh;
6913
+ var Ajax = function () {
6914
+ // this is just a helper class to ease ajax calls
6915
+ var _this = this;
6916
+ this.xmlhttp = new XMLHttpRequest();
6917
+ this.get = function (url, callback) {
6918
+ _this.xmlhttp.onreadystatechange = function () {
6919
+ if (_this.xmlhttp.readyState === 4) {
6920
+ callback(_this.xmlhttp.responseText, _this.xmlhttp.status);
6921
+ }
6922
+ };
6923
+ _this.xmlhttp.open('GET', url, true);
6924
+ _this.xmlhttp.send();
6925
+ };
6926
+ };
6927
+
6928
+ /**
6929
+ * Takes in an object of `mesh_name`, `'/url/to/OBJ/file'` pairs and a callback
6930
+ * function. Each OBJ file will be ajaxed in and automatically converted to
6931
+ * an OBJ.Mesh. When all files have successfully downloaded the callback
6932
+ * function provided will be called and passed in an object containing
6933
+ * the newly created meshes.
6934
+ *
6935
+ * **Note:** In order to use this function as a way to download meshes, a
6936
+ * webserver of some sort must be used.
6937
+ *
6938
+ * @param {Object} nameAndURLs an object where the key is the name of the mesh and the value is the url to that mesh's OBJ file
6939
+ *
6940
+ * @param {Function} completionCallback should contain a function that will take one parameter: an object array where the keys will be the unique object name and the value will be a Mesh object
6941
+ *
6942
+ * @param {Object} meshes In case other meshes are loaded separately or if a previously declared variable is desired to be used, pass in a (possibly empty) json object of the pattern: { '<mesh_name>': OBJ.Mesh }
6943
+ *
6944
+ */
6945
+ var downloadMeshes = function (nameAndURLs, completionCallback, inputArg) {
6946
+ // the total number of meshes. this is used to implement "blocking"
6947
+ var semaphore = Object.keys(nameAndURLs).length;
6948
+ // if error is true, an alert will given
6949
+ var error = false;
6950
+ // this is used to check if all meshes have been downloaded
6951
+ // if meshes is supplied, then it will be populated, otherwise
6952
+ // a new object is created. this will be passed into the completionCallback
6953
+ if (typeof inputArg === 'undefined') {
6954
+ var inputArg = {
6955
+ scale: 1,
6956
+ swap: [null]
6957
+ };
6958
+ }
6959
+ if (typeof inputArg.scale === 'undefined') inputArg.scale = 0.1;
6960
+ if (typeof inputArg.swap === 'undefined') inputArg.swap = [null];
6961
+ var meshes = {};
6962
+
6963
+ // loop over the mesh_name,url key,value pairs
6964
+ for (var mesh_name in nameAndURLs) {
6965
+ if (nameAndURLs.hasOwnProperty(mesh_name)) {
6966
+ new Ajax().get(nameAndURLs[mesh_name], function (name) {
6967
+ return function (data, status) {
6968
+ if (status === 200) {
6969
+ meshes[name] = new constructMesh(data, inputArg);
6970
+ } else {
6971
+ error = true;
6972
+ console.error('An error has occurred and the mesh "' + name + '" could not be downloaded.');
6973
+ }
6974
+ // the request has finished, decrement the counter
6975
+ semaphore--;
6976
+ if (semaphore === 0) {
6977
+ if (error) {
6978
+ // if an error has occurred, the user is notified here and the
6979
+ // callback is not called
6980
+ console.error('An error has occurred and one or meshes has not been ' + 'downloaded. The execution of the script has terminated.');
6981
+ throw '';
6982
+ }
6983
+ // there haven't been any errors in retrieving the meshes
6984
+ // call the callback
6985
+ completionCallback(meshes);
6986
+ }
6987
+ };
6988
+ }(mesh_name));
6989
+ }
6990
+ }
6991
+ };
6992
+
6993
+ /**
6994
+ * Takes in the WebGL context and a Mesh, then creates and appends the buffers
6995
+ * to the mesh object as attributes.
6996
+ *
6997
+ * @param {WebGLRenderingContext} gl the `canvas.getContext('webgl')` context instance
6998
+ * @param {Mesh} mesh a single `OBJ.Mesh` instance
6999
+ *
7000
+ * The newly created mesh attributes are:
7001
+ *
7002
+ * Attrbute | Description
7003
+ * :--- | ---
7004
+ * **normalBuffer** |contains the model&#39;s Vertex Normals
7005
+ * normalBuffer.itemSize |set to 3 items
7006
+ * normalBuffer.numItems |the total number of vertex normals
7007
+ * |
7008
+ * **textureBuffer** |contains the model&#39;s Texture Coordinates
7009
+ * textureBuffer.itemSize |set to 2 items
7010
+ * textureBuffer.numItems |the number of texture coordinates
7011
+ * |
7012
+ * **vertexBuffer** |contains the model&#39;s Vertex Position Coordinates (does not include w)
7013
+ * vertexBuffer.itemSize |set to 3 items
7014
+ * vertexBuffer.numItems |the total number of vertices
7015
+ * |
7016
+ * **indexBuffer** |contains the indices of the faces
7017
+ * indexBuffer.itemSize |is set to 1
7018
+ * indexBuffer.numItems |the total number of indices
7019
+ *
7020
+ * A simple example (a lot of steps are missing, so don't copy and paste):
7021
+ *
7022
+ * var gl = canvas.getContext('webgl'),
7023
+ * mesh = OBJ.Mesh(obj_file_data);
7024
+ * // compile the shaders and create a shader program
7025
+ * var shaderProgram = gl.createProgram();
7026
+ * // compilation stuff here
7027
+ * ...
7028
+ * // make sure you have vertex, vertex normal, and texture coordinate
7029
+ * // attributes located in your shaders and attach them to the shader program
7030
+ * shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
7031
+ * gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);
7032
+ *
7033
+ * shaderProgram.vertexNormalAttribute = gl.getAttribLocation(shaderProgram, "aVertexNormal");
7034
+ * gl.enableVertexAttribArray(shaderProgram.vertexNormalAttribute);
7035
+ *
7036
+ * shaderProgram.textureCoordAttribute = gl.getAttribLocation(shaderProgram, "aTextureCoord");
7037
+ * gl.enableVertexAttribArray(shaderProgram.textureCoordAttribute);
7038
+ *
7039
+ * // create and initialize the vertex, vertex normal, and texture coordinate buffers
7040
+ * // and save on to the mesh object
7041
+ * OBJ.initMeshBuffers(gl, mesh);
7042
+ *
7043
+ * // now to render the mesh
7044
+ * gl.bindBuffer(gl.ARRAY_BUFFER, mesh.vertexBuffer);
7045
+ * gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, mesh.vertexBuffer.itemSize, gl.FLOAT, false, 0, 0);
7046
+ * // it's possible that the mesh doesn't contain
7047
+ * // any texture coordinates (e.g. suzanne.obj in the development branch).
7048
+ * // in this case, the texture vertexAttribArray will need to be disabled
7049
+ * // before the call to drawElements
7050
+ * if(!mesh.textures.length){
7051
+ * gl.disableVertexAttribArray(shaderProgram.textureCoordAttribute);
7052
+ * }
7053
+ * else{
7054
+ * // if the texture vertexAttribArray has been previously
7055
+ * // disabled, then it needs to be re-enabled
7056
+ * gl.enableVertexAttribArray(shaderProgram.textureCoordAttribute);
7057
+ * gl.bindBuffer(gl.ARRAY_BUFFER, mesh.textureBuffer);
7058
+ * gl.vertexAttribPointer(shaderProgram.textureCoordAttribute, mesh.textureBuffer.itemSize, gl.FLOAT, false, 0, 0);
7059
+ * }
7060
+ *
7061
+ * gl.bindBuffer(gl.ARRAY_BUFFER, mesh.normalBuffer);
7062
+ * gl.vertexAttribPointer(shaderProgram.vertexNormalAttribute, mesh.normalBuffer.itemSize, gl.FLOAT, false, 0, 0);
7063
+ *
7064
+ * gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, model.mesh.indexBuffer);
7065
+ * gl.drawElements(gl.TRIANGLES, model.mesh.indexBuffer.numItems, gl.UNSIGNED_SHORT, 0);
7066
+ */
7067
+ exports.downloadMeshes = downloadMeshes;
7068
+ var initMeshBuffers = function (gl, mesh) {
7069
+ // mesh.vertexNormals
7070
+ // mesh.textures
7071
+ // mesh.vertices
7072
+ // mesh.indices
7073
+ };
7074
+
7075
+ /**
7076
+ * @description
7077
+ * Construct sequence list argument for downloadMeshes.
7078
+ * This is adaptation for blender obj animation export.
7079
+ * For example:
7080
+ * matrixEngine.objLoader.downloadMeshes(
7081
+ matrixEngine.objLoader.makeObjSeqArg(
7082
+ {
7083
+ id: objName,
7084
+ joinMultiPahts: [
7085
+ {
7086
+ path: "res/bvh-skeletal-base/swat-guy/seq-walk/low/swat",
7087
+ id: objName,
7088
+ from: 1, to: 34
7089
+ },
7090
+ {
7091
+ path: "res/bvh-skeletal-base/swat-guy/seq-walk-pistol/low/swat-walk-pistol",
7092
+ id: objName,
7093
+ from: 35, to: 54
7094
+ }
7095
+ ]
7096
+ }),
7097
+ onLoadObj
7098
+ );
7099
+ */
7100
+ exports.initMeshBuffers = initMeshBuffers;
7101
+ const makeObjSeqArg = arg => {
7102
+ // Adaptation for blender (animation) obj exporter.
7103
+ var local = {};
7104
+ function localCalc(arg, noInitial = false) {
7105
+ var zeros = '00000';
7106
+ var l = {};
7107
+ var helper = arg.from;
7108
+ for (let j = arg.from, z = 1; j <= arg.to; j++) {
7109
+ if (z > 9 && z < 99) {
7110
+ zeros = '0000';
7111
+ } else if (z > 99 && z < 999) {
7112
+ zeros = '000';
7113
+ } // no need more then 999
7114
+
7115
+ if (helper == arg.from && noInitial === false) {
7116
+ l[arg.id] = arg.path + '_' + zeros + z + '.obj';
7117
+ } else {
7118
+ l[arg.id + (helper - 1)] = arg.path + '_' + zeros + z + '.obj';
7119
+ }
7120
+ helper++;
7121
+ z++;
7122
+ }
7123
+ return l;
7124
+ }
7125
+ if (typeof arg.path === 'string') {
7126
+ local = localCalc(arg);
7127
+ } else if (typeof arg.path === 'undefined') {
7128
+ if (typeof arg.joinMultiPahts !== 'undefined') {
7129
+ console.log("ITS joinMultiPahts!");
7130
+ var localFinal = {};
7131
+ arg.joinMultiPahts.forEach((arg, index) => {
7132
+ if (index === 0) {
7133
+ localFinal = Object.assign(local, localCalc(arg));
7134
+ } else {
7135
+ localFinal = Object.assign(local, localCalc(arg, true));
7136
+ }
7137
+ });
7138
+ console.log("joinMultiPahts LOCAL => ", localFinal);
7139
+ return localFinal;
7140
+ }
7141
+ }
7142
+ return local;
7143
+ };
7144
+
7145
+ /**
7146
+ * @description
7147
+ * Switching obj seq animations frames range.
7148
+ */
7149
+ exports.makeObjSeqArg = makeObjSeqArg;
7150
+ function play(nameAni) {
7151
+ this.animation.anims.active = nameAni;
7152
+ this.animation.currentAni = this.animation.anims[this.animation.anims.active].from;
7153
+ }
7154
+
7155
+ },{}],7:[function(require,module,exports){
7156
+ "use strict";
7157
+
7158
+ Object.defineProperty(exports, "__esModule", {
7159
+ value: true
7160
+ });
7161
+ exports.Rotation = exports.Position = void 0;
7162
+ var _utils = require("./utils");
7163
+ // Sub classes for matrix-wgpu
6151
7164
  /**
6152
7165
  * @description Base class
6153
7166
  * Position { x, y, z }
@@ -6296,32 +7309,1531 @@ class Position {
6296
7309
  }
6297
7310
  }
6298
7311
  exports.Position = Position;
7312
+ class Rotation {
7313
+ constructor(x, y, z) {
7314
+ // Not in use for nwo this is from matrix-engine project [nameUniq]
7315
+ this.nameUniq = null;
7316
+ if (typeof x == 'undefined') x = 0;
7317
+ if (typeof y == 'undefined') y = 0;
7318
+ if (typeof z == 'undefined') z = 0;
7319
+ this.x = x;
7320
+ this.y = y;
7321
+ this.z = z;
7322
+ this.rotationSpeed = {
7323
+ x: 0,
7324
+ y: 0,
7325
+ z: 0
7326
+ };
7327
+ }
7328
+ getRotX() {
7329
+ if (this.rotationSpeed.x == 0) {
7330
+ return (0, _utils.degToRad)(this.x);
7331
+ } else {
7332
+ this.x = this.x + this.rotationSpeed.x * 0.001;
7333
+ return this.x;
7334
+ }
7335
+ }
7336
+ getRotY() {
7337
+ if (this.rotationSpeed.y == 0) {
7338
+ return (0, _utils.degToRad)(this.y);
7339
+ } else {
7340
+ this.y = this.y + this.rotationSpeed.y * 0.001;
7341
+ return this.y;
7342
+ }
7343
+ }
7344
+ getRotZ() {
7345
+ if (this.rotationSpeed.z == 0) {
7346
+ return (0, _utils.degToRad)(this.z);
7347
+ } else {
7348
+ this.z = this.z + this.rotationSpeed.z * 0.001;
7349
+ return this.z;
7350
+ }
7351
+ }
7352
+ }
7353
+ exports.Rotation = Rotation;
6299
7354
 
6300
- },{}],6:[function(require,module,exports){
7355
+ },{"./utils":10}],8:[function(require,module,exports){
6301
7356
  "use strict";
6302
7357
 
6303
7358
  Object.defineProperty(exports, "__esModule", {
6304
7359
  value: true
6305
7360
  });
6306
7361
  exports.default = void 0;
6307
- var _ball = _interopRequireDefault(require("./engine/ball.js"));
6308
- var _cube = _interopRequireDefault(require("./engine/cube.js"));
6309
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
6310
- // import { mat4, vec3 } from 'wgpu-matrix';
6311
- // import { createSphereMesh, SphereLayout } from './src/engine/ballsBuffer.js';
7362
+ var _wgpuMatrix = require("wgpu-matrix");
7363
+ var _matrixClass = require("./matrix-class");
7364
+ var _engine = require("./engine");
7365
+ var _vertexShadow = require("../shaders/vertexShadow.wgsl");
7366
+ var _fragment = require("../shaders/fragment.wgsl");
7367
+ var _vertex = require("../shaders/vertex.wgsl");
7368
+ class MEMeshObj {
7369
+ constructor(canvas, device, context, o) {
7370
+ this.done = false;
7371
+ this.device = device;
7372
+ this.context = context;
7373
+ this.entityArgPass = o.entityArgPass;
6312
7374
 
6313
- class MatrixEngineWGPU {
6314
- mainRenderBundle = [];
6315
- rbContainer = [];
6316
- constructor(callback) {
6317
- var canvas = document.createElement('canvas');
6318
- canvas.width = window.innerWidth;
6319
- canvas.height = window.innerHeight;
6320
- document.body.append(canvas);
6321
- this.init({
6322
- canvas,
6323
- callback
6324
- });
7375
+ // Mesh stuff
7376
+ this.mesh = o.mesh;
7377
+ this.mesh.uvs = this.mesh.textures;
7378
+ console.log('mesh obj: ', this.mesh);
7379
+ this.inputHandler = (0, _engine.createInputHandler)(window, canvas);
7380
+ this.cameras = o.cameras;
7381
+ this.cameraParams = {
7382
+ type: o.mainCameraParams.type,
7383
+ responseCoef: o.mainCameraParams.responseCoef
7384
+ };
7385
+ this.lastFrameMS = 0;
7386
+ this.texturesPaths = [];
7387
+ o.texturesPaths.forEach(t => {
7388
+ this.texturesPaths.push(t);
7389
+ });
7390
+ this.presentationFormat = navigator.gpu.getPreferredCanvasFormat();
7391
+ this.position = new _matrixClass.Position(o.position.x, o.position.y, o.position.z);
7392
+ this.rotation = new _matrixClass.Rotation(o.rotation.x, o.rotation.y, o.rotation.z);
7393
+ this.rotation.rotationSpeed.x = o.rotationSpeed.x;
7394
+ this.rotation.rotationSpeed.y = o.rotationSpeed.y;
7395
+ this.rotation.rotationSpeed.z = o.rotationSpeed.z;
7396
+ this.scale = o.scale;
7397
+ this.runProgram = () => {
7398
+ return new Promise(async resolve => {
7399
+ this.shadowDepthTextureSize = 1024;
7400
+ const aspect = canvas.width / canvas.height;
7401
+ this.projectionMatrix = _wgpuMatrix.mat4.perspective(2 * Math.PI / 5, aspect, 1, 2000.0);
7402
+ this.modelViewProjectionMatrix = _wgpuMatrix.mat4.create();
7403
+ // console.log('cube added texturesPaths: ', this.texturesPaths)
7404
+ this.loadTex0(this.texturesPaths, device).then(() => {
7405
+ console.log('loaded tex buffer for mesh:', this.texture0);
7406
+ resolve();
7407
+ });
7408
+ });
7409
+ };
7410
+ this.runProgram().then(() => {
7411
+ const aspect = canvas.width / canvas.height;
7412
+ const presentationFormat = navigator.gpu.getPreferredCanvasFormat();
7413
+ this.context.configure({
7414
+ device: this.device,
7415
+ format: presentationFormat,
7416
+ alphaMode: 'premultiplied'
7417
+ });
7418
+
7419
+ // Create the model vertex buffer.
7420
+ this.vertexBuffer = this.device.createBuffer({
7421
+ size: this.mesh.vertices.length * Float32Array.BYTES_PER_ELEMENT,
7422
+ usage: GPUBufferUsage.VERTEX,
7423
+ mappedAtCreation: true
7424
+ });
7425
+ {
7426
+ // const mapping = new Float32Array(this.vertexBuffer.getMappedRange());
7427
+ // // for(let i = 0;i < this.mesh.vertices.length;++i) {
7428
+ // // mapping.set(this.mesh.vertices[i], 6 * i);
7429
+ // // mapping.set(this.mesh.normals[i], 6 * i + 3);
7430
+ // // }
7431
+ // this.vertexBuffer.unmap();
7432
+ new Float32Array(this.vertexBuffer.getMappedRange()).set(this.mesh.vertices);
7433
+ this.vertexBuffer.unmap();
7434
+ }
7435
+
7436
+ // NIDZA TEST SECOUND BUFFER
7437
+ // Create the model vertex buffer.
7438
+ this.vertexNormalsBuffer = this.device.createBuffer({
7439
+ size: this.mesh.vertexNormals.length * Float32Array.BYTES_PER_ELEMENT,
7440
+ usage: GPUBufferUsage.VERTEX,
7441
+ mappedAtCreation: true
7442
+ });
7443
+ {
7444
+ new Float32Array(this.vertexNormalsBuffer.getMappedRange()).set(this.mesh.vertexNormals);
7445
+ this.vertexNormalsBuffer.unmap();
7446
+ }
7447
+ this.vertexTexCoordsBuffer = this.device.createBuffer({
7448
+ size: this.mesh.textures.length * Float32Array.BYTES_PER_ELEMENT,
7449
+ usage: GPUBufferUsage.VERTEX,
7450
+ mappedAtCreation: true
7451
+ });
7452
+ {
7453
+ new Float32Array(this.vertexTexCoordsBuffer.getMappedRange()).set(this.mesh.textures);
7454
+ this.vertexTexCoordsBuffer.unmap();
7455
+ }
7456
+
7457
+ // Create the model index buffer.
7458
+ this.indexCount = this.mesh.indices.length;
7459
+ this.indexBuffer = this.device.createBuffer({
7460
+ size: this.indexCount * Uint16Array.BYTES_PER_ELEMENT,
7461
+ usage: GPUBufferUsage.INDEX,
7462
+ mappedAtCreation: true
7463
+ });
7464
+ {
7465
+ // const mapping = new Uint16Array(this.indexBuffer.getMappedRange());
7466
+ // for(let i = 0;i < this.mesh.indices.length;++i) {
7467
+ // mapping.set(this.mesh.indices[i], i);
7468
+ // }
7469
+ new Uint16Array(this.indexBuffer.getMappedRange()).set(this.mesh.indices);
7470
+ this.indexBuffer.unmap();
7471
+ }
7472
+
7473
+ // Create the depth texture for rendering/sampling the shadow map.
7474
+ this.shadowDepthTexture = this.device.createTexture({
7475
+ size: [this.shadowDepthTextureSize, this.shadowDepthTextureSize, 1],
7476
+ usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING,
7477
+ format: 'depth32float'
7478
+ });
7479
+ this.shadowDepthTextureView = this.shadowDepthTexture.createView();
7480
+
7481
+ // Create some common descriptors used for both the shadow pipeline
7482
+ // and the color rendering pipeline.
7483
+ this.vertexBuffers = [{
7484
+ arrayStride: Float32Array.BYTES_PER_ELEMENT * 3,
7485
+ attributes: [{
7486
+ // position
7487
+ shaderLocation: 0,
7488
+ offset: 0,
7489
+ format: "float32x3"
7490
+ }]
7491
+ }, {
7492
+ arrayStride: Float32Array.BYTES_PER_ELEMENT * 3,
7493
+ attributes: [{
7494
+ // normal
7495
+ shaderLocation: 1,
7496
+ offset: 0,
7497
+ format: "float32x3"
7498
+ }]
7499
+ }, {
7500
+ arrayStride: Float32Array.BYTES_PER_ELEMENT * 2,
7501
+ attributes: [{
7502
+ // uvs
7503
+ shaderLocation: 2,
7504
+ offset: 0,
7505
+ format: "float32x2"
7506
+ }]
7507
+ }];
7508
+ const primitive = {
7509
+ topology: 'triangle-list',
7510
+ cullMode: 'back'
7511
+ };
7512
+ this.uniformBufferBindGroupLayout = this.device.createBindGroupLayout({
7513
+ entries: [{
7514
+ binding: 0,
7515
+ visibility: GPUShaderStage.VERTEX,
7516
+ buffer: {
7517
+ type: 'uniform'
7518
+ }
7519
+ }]
7520
+ });
7521
+ this.shadowPipeline = this.device.createRenderPipeline({
7522
+ layout: this.device.createPipelineLayout({
7523
+ bindGroupLayouts: [this.uniformBufferBindGroupLayout, this.uniformBufferBindGroupLayout]
7524
+ }),
7525
+ vertex: {
7526
+ module: this.device.createShaderModule({
7527
+ code: _vertexShadow.vertexShadowWGSL
7528
+ }),
7529
+ buffers: this.vertexBuffers
7530
+ },
7531
+ depthStencil: {
7532
+ depthWriteEnabled: true,
7533
+ depthCompare: 'less',
7534
+ format: 'depth32float'
7535
+ },
7536
+ primitive
7537
+ });
7538
+
7539
+ // Create a bind group layout which holds the scene uniforms and
7540
+ // the texture+sampler for depth. We create it manually because the WebPU
7541
+ // implementation doesn't infer this from the shader (yet).
7542
+ this.bglForRender = this.device.createBindGroupLayout({
7543
+ entries: [{
7544
+ binding: 0,
7545
+ visibility: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT,
7546
+ buffer: {
7547
+ type: 'uniform'
7548
+ }
7549
+ }, {
7550
+ binding: 1,
7551
+ visibility: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT,
7552
+ texture: {
7553
+ sampleType: 'depth'
7554
+ }
7555
+ }, {
7556
+ binding: 2,
7557
+ visibility: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT,
7558
+ sampler: {
7559
+ type: 'comparison'
7560
+ }
7561
+ }, {
7562
+ binding: 3,
7563
+ visibility: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT,
7564
+ texture: {
7565
+ sampleType: 'float'
7566
+ }
7567
+ }, {
7568
+ binding: 4,
7569
+ visibility: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT,
7570
+ sampler: {
7571
+ type: 'filtering'
7572
+ }
7573
+ }]
7574
+ });
7575
+ this.pipeline = this.device.createRenderPipeline({
7576
+ layout: this.device.createPipelineLayout({
7577
+ bindGroupLayouts: [this.bglForRender, this.uniformBufferBindGroupLayout]
7578
+ }),
7579
+ vertex: {
7580
+ module: this.device.createShaderModule({
7581
+ code: _vertex.vertexWGSL
7582
+ }),
7583
+ buffers: this.vertexBuffers
7584
+ },
7585
+ fragment: {
7586
+ module: this.device.createShaderModule({
7587
+ code: _fragment.fragmentWGSL
7588
+ }),
7589
+ targets: [{
7590
+ format: presentationFormat
7591
+ }],
7592
+ constants: {
7593
+ shadowDepthTextureSize: this.shadowDepthTextureSize
7594
+ }
7595
+ },
7596
+ depthStencil: {
7597
+ depthWriteEnabled: true,
7598
+ depthCompare: 'less',
7599
+ format: 'depth24plus-stencil8'
7600
+ },
7601
+ primitive
7602
+ });
7603
+ const depthTexture = this.device.createTexture({
7604
+ size: [canvas.width, canvas.height],
7605
+ format: 'depth24plus-stencil8',
7606
+ usage: GPUTextureUsage.RENDER_ATTACHMENT
7607
+ });
7608
+ this.renderPassDescriptor = {
7609
+ colorAttachments: [{
7610
+ // view is acquired and set in render loop.
7611
+ view: undefined,
7612
+ clearValue: {
7613
+ r: 0.5,
7614
+ g: 0.5,
7615
+ b: 0.5,
7616
+ a: 1.0
7617
+ },
7618
+ loadOp: 'load',
7619
+ storeOp: 'store'
7620
+ }],
7621
+ depthStencilAttachment: {
7622
+ view: depthTexture.createView(),
7623
+ depthClearValue: 1.0,
7624
+ depthLoadOp: 'clear',
7625
+ depthStoreOp: 'store',
7626
+ stencilClearValue: 0,
7627
+ stencilLoadOp: 'clear',
7628
+ stencilStoreOp: 'store'
7629
+ }
7630
+ };
7631
+ this.modelUniformBuffer = this.device.createBuffer({
7632
+ size: 4 * 16,
7633
+ // 4x4 matrix
7634
+ usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
7635
+ });
7636
+ this.sceneUniformBuffer = this.device.createBuffer({
7637
+ // Two 4x4 viewProj matrices,
7638
+ // one for the camera and one for the light.
7639
+ // Then a vec3 for the light position.
7640
+ // Rounded to the nearest multiple of 16.
7641
+ size: 2 * 4 * 16 + 4 * 4,
7642
+ usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
7643
+ });
7644
+ this.sceneBindGroupForShadow = this.device.createBindGroup({
7645
+ layout: this.uniformBufferBindGroupLayout,
7646
+ entries: [{
7647
+ binding: 0,
7648
+ resource: {
7649
+ buffer: this.sceneUniformBuffer
7650
+ }
7651
+ }]
7652
+ });
7653
+ this.sceneBindGroupForRender = this.device.createBindGroup({
7654
+ layout: this.bglForRender,
7655
+ entries: [{
7656
+ binding: 0,
7657
+ resource: {
7658
+ buffer: this.sceneUniformBuffer
7659
+ }
7660
+ }, {
7661
+ binding: 1,
7662
+ resource: this.shadowDepthTextureView
7663
+ }, {
7664
+ binding: 2,
7665
+ resource: this.device.createSampler({
7666
+ compare: 'less'
7667
+ })
7668
+ }, {
7669
+ binding: 3,
7670
+ resource: this.texture0.createView()
7671
+ }, {
7672
+ binding: 4,
7673
+ resource: this.sampler
7674
+ }]
7675
+ });
7676
+ this.modelBindGroup = this.device.createBindGroup({
7677
+ layout: this.uniformBufferBindGroupLayout,
7678
+ entries: [{
7679
+ binding: 0,
7680
+ resource: {
7681
+ buffer: this.modelUniformBuffer
7682
+ }
7683
+ }]
7684
+ });
7685
+
7686
+ // Rotates the camera around the origin based on time.
7687
+ this.getTransformationMatrix = pos => {
7688
+ const now = Date.now();
7689
+ const deltaTime = (now - this.lastFrameMS) / this.cameraParams.responseCoef;
7690
+ this.lastFrameMS = now;
7691
+
7692
+ // const this.viewMatrix = mat4.identity()
7693
+ const camera = this.cameras[this.cameraParams.type];
7694
+ this.viewMatrix = camera.update(deltaTime, this.inputHandler());
7695
+ _wgpuMatrix.mat4.translate(this.viewMatrix, _wgpuMatrix.vec3.fromValues(pos.x, pos.y, pos.z), this.viewMatrix);
7696
+ _wgpuMatrix.mat4.rotateX(this.viewMatrix, Math.PI * this.rotation.getRotX(), this.viewMatrix);
7697
+ _wgpuMatrix.mat4.rotateY(this.viewMatrix, Math.PI * this.rotation.getRotY(), this.viewMatrix);
7698
+ _wgpuMatrix.mat4.rotateZ(this.viewMatrix, Math.PI * this.rotation.getRotZ(), this.viewMatrix);
7699
+ _wgpuMatrix.mat4.multiply(this.projectionMatrix, this.viewMatrix, this.modelViewProjectionMatrix);
7700
+ return this.modelViewProjectionMatrix;
7701
+ };
7702
+ this.upVector = _wgpuMatrix.vec3.fromValues(0, 1, 0);
7703
+ this.origin = _wgpuMatrix.vec3.fromValues(0, 0, 0);
7704
+ const lightPosition = _wgpuMatrix.vec3.fromValues(50, 100, -100);
7705
+ const lightViewMatrix = _wgpuMatrix.mat4.lookAt(lightPosition, this.origin, this.upVector);
7706
+ const lightProjectionMatrix = _wgpuMatrix.mat4.create();
7707
+ {
7708
+ const left = -80;
7709
+ const right = 80;
7710
+ const bottom = -80;
7711
+ const top = 80;
7712
+ const near = -200;
7713
+ const far = 300;
7714
+ _wgpuMatrix.mat4.ortho(left, right, bottom, top, near, far, lightProjectionMatrix);
7715
+ }
7716
+ const lightViewProjMatrix = _wgpuMatrix.mat4.multiply(lightProjectionMatrix, lightViewMatrix);
7717
+
7718
+ // looks like affect on transformations for now const 0
7719
+ const modelMatrix = _wgpuMatrix.mat4.translation([0, 0, 0]);
7720
+ // The camera/light aren't moving, so write them into buffers now.
7721
+ {
7722
+ const lightMatrixData = lightViewProjMatrix; // as Float32Array;
7723
+ this.device.queue.writeBuffer(this.sceneUniformBuffer, 0, lightMatrixData.buffer, lightMatrixData.byteOffset, lightMatrixData.byteLength);
7724
+ const lightData = lightPosition;
7725
+ this.device.queue.writeBuffer(this.sceneUniformBuffer, 128, lightData.buffer, lightData.byteOffset, lightData.byteLength);
7726
+ const modelData = modelMatrix;
7727
+ this.device.queue.writeBuffer(this.modelUniformBuffer, 0, modelData.buffer, modelData.byteOffset, modelData.byteLength);
7728
+ }
7729
+ this.shadowPassDescriptor = {
7730
+ colorAttachments: [],
7731
+ depthStencilAttachment: {
7732
+ view: this.shadowDepthTextureView,
7733
+ depthClearValue: 1.0,
7734
+ depthLoadOp: 'clear',
7735
+ depthStoreOp: 'store'
7736
+ }
7737
+ };
7738
+ this.done = true;
7739
+ });
7740
+ }
7741
+ async loadTex0(texturesPaths, device) {
7742
+ this.sampler = device.createSampler({
7743
+ magFilter: 'linear',
7744
+ minFilter: 'linear'
7745
+ });
7746
+ return new Promise(async resolve => {
7747
+ const response = await fetch(texturesPaths[0]);
7748
+ const imageBitmap = await createImageBitmap(await response.blob());
7749
+ this.texture0 = device.createTexture({
7750
+ size: [imageBitmap.width, imageBitmap.height, 1],
7751
+ format: 'rgba8unorm',
7752
+ usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT
7753
+ });
7754
+ device.queue.copyExternalImageToTexture({
7755
+ source: imageBitmap
7756
+ }, {
7757
+ texture: this.texture0
7758
+ }, [imageBitmap.width, imageBitmap.height]);
7759
+ resolve();
7760
+ });
7761
+ }
7762
+ draw = commandEncoder => {
7763
+ if (this.done == false) return;
7764
+ const transformationMatrix = this.getTransformationMatrix(this.position);
7765
+ this.device.queue.writeBuffer(this.sceneUniformBuffer, 64, transformationMatrix.buffer, transformationMatrix.byteOffset, transformationMatrix.byteLength);
7766
+ this.renderPassDescriptor.colorAttachments[0].view = this.context.getCurrentTexture().createView();
7767
+ {
7768
+ const shadowPass = commandEncoder.beginRenderPass(this.shadowPassDescriptor);
7769
+ shadowPass.setPipeline(this.shadowPipeline);
7770
+ shadowPass.setBindGroup(0, this.sceneBindGroupForShadow);
7771
+ shadowPass.setBindGroup(1, this.modelBindGroup);
7772
+ shadowPass.setVertexBuffer(0, this.vertexBuffer);
7773
+ shadowPass.setVertexBuffer(1, this.vertexNormalsBuffer);
7774
+ shadowPass.setVertexBuffer(2, this.vertexTexCoordsBuffer);
7775
+ shadowPass.setIndexBuffer(this.indexBuffer, 'uint16');
7776
+ shadowPass.drawIndexed(this.indexCount);
7777
+ shadowPass.end();
7778
+ }
7779
+ {
7780
+ const renderPass = commandEncoder.beginRenderPass(this.renderPassDescriptor);
7781
+ renderPass.setPipeline(this.pipeline);
7782
+ renderPass.setBindGroup(0, this.sceneBindGroupForRender);
7783
+ renderPass.setBindGroup(1, this.modelBindGroup);
7784
+ renderPass.setVertexBuffer(0, this.vertexBuffer);
7785
+ renderPass.setVertexBuffer(1, this.vertexNormalsBuffer);
7786
+ renderPass.setVertexBuffer(2, this.vertexTexCoordsBuffer);
7787
+ renderPass.setIndexBuffer(this.indexBuffer, 'uint16');
7788
+ renderPass.drawIndexed(this.indexCount);
7789
+ renderPass.end();
7790
+ }
7791
+ };
7792
+ }
7793
+ exports.default = MEMeshObj;
7794
+
7795
+ },{"../shaders/fragment.wgsl":11,"../shaders/vertex.wgsl":13,"../shaders/vertexShadow.wgsl":14,"./engine":5,"./matrix-class":7,"wgpu-matrix":2}],9:[function(require,module,exports){
7796
+ "use strict";
7797
+
7798
+ Object.defineProperty(exports, "__esModule", {
7799
+ value: true
7800
+ });
7801
+ exports.default = void 0;
7802
+ var _wgpuMatrix = require("wgpu-matrix");
7803
+ var _matrixClass = require("./matrix-class");
7804
+ var _engine = require("./engine");
7805
+ var _vertexShadow = require("../shaders/vertexShadow.wgsl");
7806
+ var _fragment = require("../shaders/fragment.wgsl");
7807
+ var _vertex = require("../shaders/vertex.wgsl");
7808
+ var _loaderObj = require("./loader-obj");
7809
+ class MEMesh {
7810
+ constructor(canvas, device, context, o) {
7811
+ this.done = false;
7812
+ this.device = device;
7813
+ this.context = context;
7814
+ this.entityArgPass = o.entityArgPass;
7815
+ this.mesh = o.mesh;
7816
+ this.inputHandler = (0, _engine.createInputHandler)(window, canvas);
7817
+ this.cameras = o.cameras;
7818
+ console.log('passed : o.mainCameraParams.responseCoef ', o.mainCameraParams.responseCoef);
7819
+ this.cameraParams = {
7820
+ type: o.mainCameraParams.type,
7821
+ responseCoef: o.mainCameraParams.responseCoef
7822
+ };
7823
+ this.lastFrameMS = 0;
7824
+ this.texturesPaths = [];
7825
+ o.texturesPaths.forEach(t => {
7826
+ this.texturesPaths.push(t);
7827
+ });
7828
+ this.presentationFormat = navigator.gpu.getPreferredCanvasFormat();
7829
+ this.position = new _matrixClass.Position(o.position.x, o.position.y, o.position.z);
7830
+ console.log('cube added on pos : ', this.position);
7831
+ this.rotation = new _matrixClass.Rotation(o.rotation.x, o.rotation.y, o.rotation.z);
7832
+ this.rotation.rotationSpeed.x = o.rotationSpeed.x;
7833
+ this.rotation.rotationSpeed.y = o.rotationSpeed.y;
7834
+ this.rotation.rotationSpeed.z = o.rotationSpeed.z;
7835
+ this.scale = o.scale;
7836
+
7837
+ // new
7838
+ this.runProgram = () => {
7839
+ return new Promise(async resolve => {
7840
+ this.shadowDepthTextureSize = 1024;
7841
+ const aspect = canvas.width / canvas.height;
7842
+ this.projectionMatrix = _wgpuMatrix.mat4.perspective(2 * Math.PI / 5, aspect, 1, 2000.0);
7843
+ this.modelViewProjectionMatrix = _wgpuMatrix.mat4.create();
7844
+ this.loadTex0(this.texturesPaths, device).then(() => {
7845
+ resolve();
7846
+ console.log('load tex for mesh', this.texture0);
7847
+ });
7848
+ });
7849
+ };
7850
+ this.runProgram().then(() => {
7851
+ const aspect = canvas.width / canvas.height;
7852
+ const presentationFormat = navigator.gpu.getPreferredCanvasFormat();
7853
+ this.context.configure({
7854
+ device: this.device,
7855
+ format: presentationFormat,
7856
+ alphaMode: 'premultiplied'
7857
+ });
7858
+
7859
+ // Create the model vertex buffer.
7860
+ this.vertexBuffer = this.device.createBuffer({
7861
+ size: this.mesh.positions.length * 3 * 2 * Float32Array.BYTES_PER_ELEMENT,
7862
+ usage: GPUBufferUsage.VERTEX,
7863
+ mappedAtCreation: true
7864
+ });
7865
+ {
7866
+ const mapping = new Float32Array(this.vertexBuffer.getMappedRange());
7867
+ for (let i = 0; i < this.mesh.positions.length; ++i) {
7868
+ mapping.set(this.mesh.positions[i], 6 * i);
7869
+ mapping.set(this.mesh.normals[i], 6 * i + 3);
7870
+ }
7871
+ this.vertexBuffer.unmap();
7872
+ }
7873
+
7874
+ // Create the model index buffer.
7875
+ this.indexCount = this.mesh.triangles.length * 3;
7876
+ this.indexBuffer = this.device.createBuffer({
7877
+ size: this.indexCount * Uint16Array.BYTES_PER_ELEMENT,
7878
+ usage: GPUBufferUsage.INDEX,
7879
+ mappedAtCreation: true
7880
+ });
7881
+ {
7882
+ const mapping = new Uint16Array(this.indexBuffer.getMappedRange());
7883
+ for (let i = 0; i < this.mesh.triangles.length; ++i) {
7884
+ mapping.set(this.mesh.triangles[i], 3 * i);
7885
+ }
7886
+ this.indexBuffer.unmap();
7887
+ }
7888
+
7889
+ // Create the depth texture for rendering/sampling the shadow map.
7890
+ this.shadowDepthTexture = this.device.createTexture({
7891
+ size: [this.shadowDepthTextureSize, this.shadowDepthTextureSize, 1],
7892
+ usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING,
7893
+ format: 'depth32float'
7894
+ });
7895
+ this.shadowDepthTextureView = this.shadowDepthTexture.createView();
7896
+
7897
+ // Create some common descriptors used for both the shadow pipeline
7898
+ // and the color rendering pipeline.
7899
+ this.vertexBuffers = [{
7900
+ arrayStride: Float32Array.BYTES_PER_ELEMENT * 6,
7901
+ attributes: [{
7902
+ // position
7903
+ shaderLocation: 0,
7904
+ offset: 0,
7905
+ format: 'float32x3'
7906
+ }, {
7907
+ // normal
7908
+ shaderLocation: 1,
7909
+ offset: Float32Array.BYTES_PER_ELEMENT * 3,
7910
+ format: 'float32x3'
7911
+ }]
7912
+ }];
7913
+ const primitive = {
7914
+ topology: 'triangle-list',
7915
+ cullMode: 'back'
7916
+ };
7917
+ this.uniformBufferBindGroupLayout = this.device.createBindGroupLayout({
7918
+ entries: [{
7919
+ binding: 0,
7920
+ visibility: GPUShaderStage.VERTEX,
7921
+ buffer: {
7922
+ type: 'uniform'
7923
+ }
7924
+ }]
7925
+ });
7926
+ this.shadowPipeline = this.device.createRenderPipeline({
7927
+ layout: this.device.createPipelineLayout({
7928
+ bindGroupLayouts: [this.uniformBufferBindGroupLayout, this.uniformBufferBindGroupLayout]
7929
+ }),
7930
+ vertex: {
7931
+ module: this.device.createShaderModule({
7932
+ code: _vertexShadow.vertexShadowWGSL
7933
+ }),
7934
+ buffers: this.vertexBuffers
7935
+ },
7936
+ depthStencil: {
7937
+ depthWriteEnabled: true,
7938
+ depthCompare: 'less',
7939
+ format: 'depth32float'
7940
+ },
7941
+ primitive
7942
+ });
7943
+
7944
+ // Create a bind group layout which holds the scene uniforms and
7945
+ // the texture+sampler for depth. We create it manually because the WebPU
7946
+ // implementation doesn't infer this from the shader (yet).
7947
+ this.bglForRender = this.device.createBindGroupLayout({
7948
+ entries: [{
7949
+ binding: 0,
7950
+ visibility: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT,
7951
+ buffer: {
7952
+ type: 'uniform'
7953
+ }
7954
+ }, {
7955
+ binding: 1,
7956
+ visibility: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT,
7957
+ texture: {
7958
+ sampleType: 'depth'
7959
+ }
7960
+ }, {
7961
+ binding: 2,
7962
+ visibility: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT,
7963
+ sampler: {
7964
+ type: 'comparison'
7965
+ }
7966
+ }, {
7967
+ binding: 3,
7968
+ visibility: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT,
7969
+ texture: {
7970
+ sampleType: 'float'
7971
+ }
7972
+ }, {
7973
+ binding: 4,
7974
+ visibility: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT,
7975
+ sampler: {
7976
+ type: 'filtering'
7977
+ }
7978
+ }]
7979
+ });
7980
+ this.pipeline = this.device.createRenderPipeline({
7981
+ layout: this.device.createPipelineLayout({
7982
+ bindGroupLayouts: [this.bglForRender, this.uniformBufferBindGroupLayout]
7983
+ }),
7984
+ vertex: {
7985
+ module: this.device.createShaderModule({
7986
+ code: _vertex.vertexWGSL
7987
+ }),
7988
+ buffers: this.vertexBuffers
7989
+ },
7990
+ fragment: {
7991
+ module: this.device.createShaderModule({
7992
+ code: _fragment.fragmentWGSL
7993
+ }),
7994
+ targets: [{
7995
+ format: presentationFormat
7996
+ }],
7997
+ constants: {
7998
+ shadowDepthTextureSize: this.shadowDepthTextureSize
7999
+ }
8000
+ },
8001
+ depthStencil: {
8002
+ depthWriteEnabled: true,
8003
+ depthCompare: 'less',
8004
+ format: 'depth24plus-stencil8'
8005
+ },
8006
+ primitive
8007
+ });
8008
+ const depthTexture = this.device.createTexture({
8009
+ size: [canvas.width, canvas.height],
8010
+ format: 'depth24plus-stencil8',
8011
+ usage: GPUTextureUsage.RENDER_ATTACHMENT
8012
+ });
8013
+ this.renderPassDescriptor = {
8014
+ colorAttachments: [{
8015
+ // view is acquired and set in render loop.
8016
+ view: undefined,
8017
+ clearValue: {
8018
+ r: 0.5,
8019
+ g: 0.5,
8020
+ b: 0.5,
8021
+ a: 1.0
8022
+ },
8023
+ loadOp: 'load',
8024
+ storeOp: 'store'
8025
+ }],
8026
+ depthStencilAttachment: {
8027
+ view: depthTexture.createView(),
8028
+ depthClearValue: 1.0,
8029
+ depthLoadOp: 'clear',
8030
+ depthStoreOp: 'store',
8031
+ stencilClearValue: 0,
8032
+ stencilLoadOp: 'clear',
8033
+ stencilStoreOp: 'store'
8034
+ }
8035
+ };
8036
+ this.modelUniformBuffer = this.device.createBuffer({
8037
+ size: 4 * 16,
8038
+ // 4x4 matrix
8039
+ usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
8040
+ });
8041
+ this.sceneUniformBuffer = this.device.createBuffer({
8042
+ // Two 4x4 viewProj matrices,
8043
+ // one for the camera and one for the light.
8044
+ // Then a vec3 for the light position.
8045
+ // Rounded to the nearest multiple of 16.
8046
+ size: 2 * 4 * 16 + 4 * 4,
8047
+ usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
8048
+ });
8049
+ this.sceneBindGroupForShadow = this.device.createBindGroup({
8050
+ layout: this.uniformBufferBindGroupLayout,
8051
+ entries: [{
8052
+ binding: 0,
8053
+ resource: {
8054
+ buffer: this.sceneUniformBuffer
8055
+ }
8056
+ }]
8057
+ });
8058
+ this.sceneBindGroupForRender = this.device.createBindGroup({
8059
+ layout: this.bglForRender,
8060
+ entries: [{
8061
+ binding: 0,
8062
+ resource: {
8063
+ buffer: this.sceneUniformBuffer
8064
+ }
8065
+ }, {
8066
+ binding: 1,
8067
+ resource: this.shadowDepthTextureView
8068
+ }, {
8069
+ binding: 2,
8070
+ resource: this.device.createSampler({
8071
+ compare: 'less'
8072
+ })
8073
+ }, {
8074
+ binding: 3,
8075
+ resource: this.texture0.createView()
8076
+ }, {
8077
+ binding: 4,
8078
+ resource: this.sampler
8079
+ }]
8080
+ });
8081
+ this.modelBindGroup = this.device.createBindGroup({
8082
+ layout: this.uniformBufferBindGroupLayout,
8083
+ entries: [{
8084
+ binding: 0,
8085
+ resource: {
8086
+ buffer: this.modelUniformBuffer
8087
+ }
8088
+ }]
8089
+ });
8090
+
8091
+ // Rotates the camera around the origin based on time.
8092
+ this.getTransformationMatrix = pos => {
8093
+ const now = Date.now();
8094
+ const deltaTime = (now - this.lastFrameMS) / this.cameraParams.responseCoef;
8095
+ this.lastFrameMS = now;
8096
+ const camera = this.cameras[this.cameraParams.type];
8097
+ this.viewMatrix = camera.update(deltaTime, this.inputHandler());
8098
+ _wgpuMatrix.mat4.translate(this.viewMatrix, _wgpuMatrix.vec3.fromValues(pos.x, pos.y, pos.z), this.viewMatrix);
8099
+ _wgpuMatrix.mat4.rotateX(this.viewMatrix, Math.PI * this.rotation.getRotX(), this.viewMatrix);
8100
+ _wgpuMatrix.mat4.rotateY(this.viewMatrix, Math.PI * this.rotation.getRotY(), this.viewMatrix);
8101
+ _wgpuMatrix.mat4.rotateZ(this.viewMatrix, Math.PI * this.rotation.getRotZ(), this.viewMatrix);
8102
+ _wgpuMatrix.mat4.multiply(this.projectionMatrix, this.viewMatrix, this.modelViewProjectionMatrix);
8103
+ return this.modelViewProjectionMatrix;
8104
+ };
8105
+ this.upVector = _wgpuMatrix.vec3.fromValues(0, 1, 0);
8106
+ this.origin = _wgpuMatrix.vec3.fromValues(0, 0, 0);
8107
+ const lightPosition = _wgpuMatrix.vec3.fromValues(50, 100, -100);
8108
+ const lightViewMatrix = _wgpuMatrix.mat4.lookAt(lightPosition, this.origin, this.upVector);
8109
+ const lightProjectionMatrix = _wgpuMatrix.mat4.create();
8110
+ {
8111
+ const left = -80;
8112
+ const right = 80;
8113
+ const bottom = -80;
8114
+ const top = 80;
8115
+ const near = -200;
8116
+ const far = 300;
8117
+ _wgpuMatrix.mat4.ortho(left, right, bottom, top, near, far, lightProjectionMatrix);
8118
+ }
8119
+ const lightViewProjMatrix = _wgpuMatrix.mat4.multiply(lightProjectionMatrix, lightViewMatrix);
8120
+
8121
+ // looks like affect on transformations for now const 0
8122
+ const modelMatrix = _wgpuMatrix.mat4.translation([0, 0, 0]);
8123
+ // The camera/light aren't moving, so write them into buffers now.
8124
+ {
8125
+ const lightMatrixData = lightViewProjMatrix; // as Float32Array;
8126
+ this.device.queue.writeBuffer(this.sceneUniformBuffer, 0, lightMatrixData.buffer, lightMatrixData.byteOffset, lightMatrixData.byteLength);
8127
+ const lightData = lightPosition;
8128
+ this.device.queue.writeBuffer(this.sceneUniformBuffer, 128, lightData.buffer, lightData.byteOffset, lightData.byteLength);
8129
+ const modelData = modelMatrix;
8130
+ this.device.queue.writeBuffer(this.modelUniformBuffer, 0, modelData.buffer, modelData.byteOffset, modelData.byteLength);
8131
+ }
8132
+ this.shadowPassDescriptor = {
8133
+ colorAttachments: [],
8134
+ depthStencilAttachment: {
8135
+ view: this.shadowDepthTextureView,
8136
+ depthClearValue: 1.0,
8137
+ depthLoadOp: 'clear',
8138
+ depthStoreOp: 'store'
8139
+ }
8140
+ };
8141
+ this.done = true;
8142
+ });
8143
+ }
8144
+ async loadTex0(texturesPaths, device) {
8145
+ this.sampler = device.createSampler({
8146
+ magFilter: 'linear',
8147
+ minFilter: 'linear'
8148
+ });
8149
+ return new Promise(async resolve => {
8150
+ const response = await fetch(texturesPaths[0]);
8151
+ const imageBitmap = await createImageBitmap(await response.blob());
8152
+ this.texture0 = device.createTexture({
8153
+ size: [imageBitmap.width, imageBitmap.height, 1],
8154
+ format: 'rgba8unorm',
8155
+ usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT
8156
+ });
8157
+ device.queue.copyExternalImageToTexture({
8158
+ source: imageBitmap
8159
+ }, {
8160
+ texture: this.texture0
8161
+ }, [imageBitmap.width, imageBitmap.height]);
8162
+ resolve();
8163
+ });
8164
+ }
8165
+ draw = commandEncoder => {
8166
+ if (this.done == false) return;
8167
+ const transformationMatrix = this.getTransformationMatrix(this.position);
8168
+ this.device.queue.writeBuffer(this.sceneUniformBuffer, 64, transformationMatrix.buffer, transformationMatrix.byteOffset, transformationMatrix.byteLength);
8169
+ this.renderPassDescriptor.colorAttachments[0].view = this.context.getCurrentTexture().createView();
8170
+ {
8171
+ const shadowPass = commandEncoder.beginRenderPass(this.shadowPassDescriptor);
8172
+ shadowPass.setPipeline(this.shadowPipeline);
8173
+ shadowPass.setBindGroup(0, this.sceneBindGroupForShadow);
8174
+ shadowPass.setBindGroup(1, this.modelBindGroup);
8175
+ shadowPass.setVertexBuffer(0, this.vertexBuffer);
8176
+ shadowPass.setIndexBuffer(this.indexBuffer, 'uint16');
8177
+ shadowPass.drawIndexed(this.indexCount);
8178
+ shadowPass.end();
8179
+ }
8180
+ {
8181
+ const renderPass = commandEncoder.beginRenderPass(this.renderPassDescriptor);
8182
+ renderPass.setPipeline(this.pipeline);
8183
+ renderPass.setBindGroup(0, this.sceneBindGroupForRender);
8184
+ renderPass.setBindGroup(1, this.modelBindGroup);
8185
+ renderPass.setVertexBuffer(0, this.vertexBuffer);
8186
+ renderPass.setIndexBuffer(this.indexBuffer, 'uint16');
8187
+ renderPass.drawIndexed(this.indexCount);
8188
+ renderPass.end();
8189
+ }
8190
+ };
8191
+ }
8192
+ exports.default = MEMesh;
8193
+
8194
+ },{"../shaders/fragment.wgsl":11,"../shaders/vertex.wgsl":13,"../shaders/vertexShadow.wgsl":14,"./engine":5,"./loader-obj":6,"./matrix-class":7,"wgpu-matrix":2}],10:[function(require,module,exports){
8195
+ "use strict";
8196
+
8197
+ Object.defineProperty(exports, "__esModule", {
8198
+ value: true
8199
+ });
8200
+ exports.degToRad = degToRad;
8201
+ exports.vec3 = exports.mat4 = void 0;
8202
+ const vec3 = exports.vec3 = {
8203
+ cross(a, b, dst) {
8204
+ dst = dst || new Float32Array(3);
8205
+ const t0 = a[1] * b[2] - a[2] * b[1];
8206
+ const t1 = a[2] * b[0] - a[0] * b[2];
8207
+ const t2 = a[0] * b[1] - a[1] * b[0];
8208
+ dst[0] = t0;
8209
+ dst[1] = t1;
8210
+ dst[2] = t2;
8211
+ return dst;
8212
+ },
8213
+ subtract(a, b, dst) {
8214
+ dst = dst || new Float32Array(3);
8215
+ dst[0] = a[0] - b[0];
8216
+ dst[1] = a[1] - b[1];
8217
+ dst[2] = a[2] - b[2];
8218
+ return dst;
8219
+ },
8220
+ normalize(v, dst) {
8221
+ dst = dst || new Float32Array(3);
8222
+ const length = Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
8223
+ // make sure we don't divide by 0.
8224
+ if (length > 0.00001) {
8225
+ dst[0] = v[0] / length;
8226
+ dst[1] = v[1] / length;
8227
+ dst[2] = v[2] / length;
8228
+ } else {
8229
+ dst[0] = 0;
8230
+ dst[1] = 0;
8231
+ dst[2] = 0;
8232
+ }
8233
+ return dst;
8234
+ }
8235
+ };
8236
+ const mat4 = exports.mat4 = {
8237
+ projection(width, height, depth, dst) {
8238
+ // Note: This matrix flips the Y axis so that 0 is at the top.
8239
+ return mat4.ortho(0, width, height, 0, depth, -depth, dst);
8240
+ },
8241
+ perspective(fieldOfViewYInRadians, aspect, zNear, zFar, dst) {
8242
+ dst = dst || new Float32Array(16);
8243
+ const f = Math.tan(Math.PI * 0.5 - 0.5 * fieldOfViewYInRadians);
8244
+ const rangeInv = 1 / (zNear - zFar);
8245
+ dst[0] = f / aspect;
8246
+ dst[1] = 0;
8247
+ dst[2] = 0;
8248
+ dst[3] = 0;
8249
+ dst[4] = 0;
8250
+ dst[5] = f;
8251
+ dst[6] = 0;
8252
+ dst[7] = 0;
8253
+ dst[8] = 0;
8254
+ dst[9] = 0;
8255
+ dst[10] = zFar * rangeInv;
8256
+ dst[11] = -1;
8257
+ dst[12] = 0;
8258
+ dst[13] = 0;
8259
+ dst[14] = zNear * zFar * rangeInv;
8260
+ dst[15] = 0;
8261
+ return dst;
8262
+ },
8263
+ ortho(left, right, bottom, top, near, far, dst) {
8264
+ dst = dst || new Float32Array(16);
8265
+ dst[0] = 2 / (right - left);
8266
+ dst[1] = 0;
8267
+ dst[2] = 0;
8268
+ dst[3] = 0;
8269
+ dst[4] = 0;
8270
+ dst[5] = 2 / (top - bottom);
8271
+ dst[6] = 0;
8272
+ dst[7] = 0;
8273
+ dst[8] = 0;
8274
+ dst[9] = 0;
8275
+ dst[10] = 1 / (near - far);
8276
+ dst[11] = 0;
8277
+ dst[12] = (right + left) / (left - right);
8278
+ dst[13] = (top + bottom) / (bottom - top);
8279
+ dst[14] = near / (near - far);
8280
+ dst[15] = 1;
8281
+ return dst;
8282
+ },
8283
+ identity(dst) {
8284
+ dst = dst || new Float32Array(16);
8285
+ dst[0] = 1;
8286
+ dst[1] = 0;
8287
+ dst[2] = 0;
8288
+ dst[3] = 0;
8289
+ dst[4] = 0;
8290
+ dst[5] = 1;
8291
+ dst[6] = 0;
8292
+ dst[7] = 0;
8293
+ dst[8] = 0;
8294
+ dst[9] = 0;
8295
+ dst[10] = 1;
8296
+ dst[11] = 0;
8297
+ dst[12] = 0;
8298
+ dst[13] = 0;
8299
+ dst[14] = 0;
8300
+ dst[15] = 1;
8301
+ return dst;
8302
+ },
8303
+ multiply(a, b, dst) {
8304
+ dst = dst || new Float32Array(16);
8305
+ const b00 = b[0 * 4 + 0];
8306
+ const b01 = b[0 * 4 + 1];
8307
+ const b02 = b[0 * 4 + 2];
8308
+ const b03 = b[0 * 4 + 3];
8309
+ const b10 = b[1 * 4 + 0];
8310
+ const b11 = b[1 * 4 + 1];
8311
+ const b12 = b[1 * 4 + 2];
8312
+ const b13 = b[1 * 4 + 3];
8313
+ const b20 = b[2 * 4 + 0];
8314
+ const b21 = b[2 * 4 + 1];
8315
+ const b22 = b[2 * 4 + 2];
8316
+ const b23 = b[2 * 4 + 3];
8317
+ const b30 = b[3 * 4 + 0];
8318
+ const b31 = b[3 * 4 + 1];
8319
+ const b32 = b[3 * 4 + 2];
8320
+ const b33 = b[3 * 4 + 3];
8321
+ const a00 = a[0 * 4 + 0];
8322
+ const a01 = a[0 * 4 + 1];
8323
+ const a02 = a[0 * 4 + 2];
8324
+ const a03 = a[0 * 4 + 3];
8325
+ const a10 = a[1 * 4 + 0];
8326
+ const a11 = a[1 * 4 + 1];
8327
+ const a12 = a[1 * 4 + 2];
8328
+ const a13 = a[1 * 4 + 3];
8329
+ const a20 = a[2 * 4 + 0];
8330
+ const a21 = a[2 * 4 + 1];
8331
+ const a22 = a[2 * 4 + 2];
8332
+ const a23 = a[2 * 4 + 3];
8333
+ const a30 = a[3 * 4 + 0];
8334
+ const a31 = a[3 * 4 + 1];
8335
+ const a32 = a[3 * 4 + 2];
8336
+ const a33 = a[3 * 4 + 3];
8337
+ dst[0] = b00 * a00 + b01 * a10 + b02 * a20 + b03 * a30;
8338
+ dst[1] = b00 * a01 + b01 * a11 + b02 * a21 + b03 * a31;
8339
+ dst[2] = b00 * a02 + b01 * a12 + b02 * a22 + b03 * a32;
8340
+ dst[3] = b00 * a03 + b01 * a13 + b02 * a23 + b03 * a33;
8341
+ dst[4] = b10 * a00 + b11 * a10 + b12 * a20 + b13 * a30;
8342
+ dst[5] = b10 * a01 + b11 * a11 + b12 * a21 + b13 * a31;
8343
+ dst[6] = b10 * a02 + b11 * a12 + b12 * a22 + b13 * a32;
8344
+ dst[7] = b10 * a03 + b11 * a13 + b12 * a23 + b13 * a33;
8345
+ dst[8] = b20 * a00 + b21 * a10 + b22 * a20 + b23 * a30;
8346
+ dst[9] = b20 * a01 + b21 * a11 + b22 * a21 + b23 * a31;
8347
+ dst[10] = b20 * a02 + b21 * a12 + b22 * a22 + b23 * a32;
8348
+ dst[11] = b20 * a03 + b21 * a13 + b22 * a23 + b23 * a33;
8349
+ dst[12] = b30 * a00 + b31 * a10 + b32 * a20 + b33 * a30;
8350
+ dst[13] = b30 * a01 + b31 * a11 + b32 * a21 + b33 * a31;
8351
+ dst[14] = b30 * a02 + b31 * a12 + b32 * a22 + b33 * a32;
8352
+ dst[15] = b30 * a03 + b31 * a13 + b32 * a23 + b33 * a33;
8353
+ return dst;
8354
+ },
8355
+ cameraAim(eye, target, up, dst) {
8356
+ dst = dst || new Float32Array(16);
8357
+ const zAxis = vec3.normalize(vec3.subtract(eye, target));
8358
+ const xAxis = vec3.normalize(vec3.cross(up, zAxis));
8359
+ const yAxis = vec3.normalize(vec3.cross(zAxis, xAxis));
8360
+ dst[0] = xAxis[0];
8361
+ dst[1] = xAxis[1];
8362
+ dst[2] = xAxis[2];
8363
+ dst[3] = 0;
8364
+ dst[4] = yAxis[0];
8365
+ dst[5] = yAxis[1];
8366
+ dst[6] = yAxis[2];
8367
+ dst[7] = 0;
8368
+ dst[8] = zAxis[0];
8369
+ dst[9] = zAxis[1];
8370
+ dst[10] = zAxis[2];
8371
+ dst[11] = 0;
8372
+ dst[12] = eye[0];
8373
+ dst[13] = eye[1];
8374
+ dst[14] = eye[2];
8375
+ dst[15] = 1;
8376
+ return dst;
8377
+ },
8378
+ inverse(m, dst) {
8379
+ dst = dst || new Float32Array(16);
8380
+ const m00 = m[0 * 4 + 0];
8381
+ const m01 = m[0 * 4 + 1];
8382
+ const m02 = m[0 * 4 + 2];
8383
+ const m03 = m[0 * 4 + 3];
8384
+ const m10 = m[1 * 4 + 0];
8385
+ const m11 = m[1 * 4 + 1];
8386
+ const m12 = m[1 * 4 + 2];
8387
+ const m13 = m[1 * 4 + 3];
8388
+ const m20 = m[2 * 4 + 0];
8389
+ const m21 = m[2 * 4 + 1];
8390
+ const m22 = m[2 * 4 + 2];
8391
+ const m23 = m[2 * 4 + 3];
8392
+ const m30 = m[3 * 4 + 0];
8393
+ const m31 = m[3 * 4 + 1];
8394
+ const m32 = m[3 * 4 + 2];
8395
+ const m33 = m[3 * 4 + 3];
8396
+ const tmp0 = m22 * m33;
8397
+ const tmp1 = m32 * m23;
8398
+ const tmp2 = m12 * m33;
8399
+ const tmp3 = m32 * m13;
8400
+ const tmp4 = m12 * m23;
8401
+ const tmp5 = m22 * m13;
8402
+ const tmp6 = m02 * m33;
8403
+ const tmp7 = m32 * m03;
8404
+ const tmp8 = m02 * m23;
8405
+ const tmp9 = m22 * m03;
8406
+ const tmp10 = m02 * m13;
8407
+ const tmp11 = m12 * m03;
8408
+ const tmp12 = m20 * m31;
8409
+ const tmp13 = m30 * m21;
8410
+ const tmp14 = m10 * m31;
8411
+ const tmp15 = m30 * m11;
8412
+ const tmp16 = m10 * m21;
8413
+ const tmp17 = m20 * m11;
8414
+ const tmp18 = m00 * m31;
8415
+ const tmp19 = m30 * m01;
8416
+ const tmp20 = m00 * m21;
8417
+ const tmp21 = m20 * m01;
8418
+ const tmp22 = m00 * m11;
8419
+ const tmp23 = m10 * m01;
8420
+ const t0 = tmp0 * m11 + tmp3 * m21 + tmp4 * m31 - (tmp1 * m11 + tmp2 * m21 + tmp5 * m31);
8421
+ const t1 = tmp1 * m01 + tmp6 * m21 + tmp9 * m31 - (tmp0 * m01 + tmp7 * m21 + tmp8 * m31);
8422
+ const t2 = tmp2 * m01 + tmp7 * m11 + tmp10 * m31 - (tmp3 * m01 + tmp6 * m11 + tmp11 * m31);
8423
+ const t3 = tmp5 * m01 + tmp8 * m11 + tmp11 * m21 - (tmp4 * m01 + tmp9 * m11 + tmp10 * m21);
8424
+ const d = 1 / (m00 * t0 + m10 * t1 + m20 * t2 + m30 * t3);
8425
+ dst[0] = d * t0;
8426
+ dst[1] = d * t1;
8427
+ dst[2] = d * t2;
8428
+ dst[3] = d * t3;
8429
+ dst[4] = d * (tmp1 * m10 + tmp2 * m20 + tmp5 * m30 - (tmp0 * m10 + tmp3 * m20 + tmp4 * m30));
8430
+ dst[5] = d * (tmp0 * m00 + tmp7 * m20 + tmp8 * m30 - (tmp1 * m00 + tmp6 * m20 + tmp9 * m30));
8431
+ dst[6] = d * (tmp3 * m00 + tmp6 * m10 + tmp11 * m30 - (tmp2 * m00 + tmp7 * m10 + tmp10 * m30));
8432
+ dst[7] = d * (tmp4 * m00 + tmp9 * m10 + tmp10 * m20 - (tmp5 * m00 + tmp8 * m10 + tmp11 * m20));
8433
+ dst[8] = d * (tmp12 * m13 + tmp15 * m23 + tmp16 * m33 - (tmp13 * m13 + tmp14 * m23 + tmp17 * m33));
8434
+ dst[9] = d * (tmp13 * m03 + tmp18 * m23 + tmp21 * m33 - (tmp12 * m03 + tmp19 * m23 + tmp20 * m33));
8435
+ dst[10] = d * (tmp14 * m03 + tmp19 * m13 + tmp22 * m33 - (tmp15 * m03 + tmp18 * m13 + tmp23 * m33));
8436
+ dst[11] = d * (tmp17 * m03 + tmp20 * m13 + tmp23 * m23 - (tmp16 * m03 + tmp21 * m13 + tmp22 * m23));
8437
+ dst[12] = d * (tmp14 * m22 + tmp17 * m32 + tmp13 * m12 - (tmp16 * m32 + tmp12 * m12 + tmp15 * m22));
8438
+ dst[13] = d * (tmp20 * m32 + tmp12 * m02 + tmp19 * m22 - (tmp18 * m22 + tmp21 * m32 + tmp13 * m02));
8439
+ dst[14] = d * (tmp18 * m12 + tmp23 * m32 + tmp15 * m02 - (tmp22 * m32 + tmp14 * m02 + tmp19 * m12));
8440
+ dst[15] = d * (tmp22 * m22 + tmp16 * m02 + tmp21 * m12 - (tmp20 * m12 + tmp23 * m22 + tmp17 * m02));
8441
+ return dst;
8442
+ },
8443
+ lookAt(eye, target, up, dst) {
8444
+ return mat4.inverse(mat4.cameraAim(eye, target, up, dst), dst);
8445
+ },
8446
+ translation([tx, ty, tz], dst) {
8447
+ dst = dst || new Float32Array(16);
8448
+ dst[0] = 1;
8449
+ dst[1] = 0;
8450
+ dst[2] = 0;
8451
+ dst[3] = 0;
8452
+ dst[4] = 0;
8453
+ dst[5] = 1;
8454
+ dst[6] = 0;
8455
+ dst[7] = 0;
8456
+ dst[8] = 0;
8457
+ dst[9] = 0;
8458
+ dst[10] = 1;
8459
+ dst[11] = 0;
8460
+ dst[12] = tx;
8461
+ dst[13] = ty;
8462
+ dst[14] = tz;
8463
+ dst[15] = 1;
8464
+ return dst;
8465
+ },
8466
+ rotationX(angleInRadians, dst) {
8467
+ const c = Math.cos(angleInRadians);
8468
+ const s = Math.sin(angleInRadians);
8469
+ dst = dst || new Float32Array(16);
8470
+ dst[0] = 1;
8471
+ dst[1] = 0;
8472
+ dst[2] = 0;
8473
+ dst[3] = 0;
8474
+ dst[4] = 0;
8475
+ dst[5] = c;
8476
+ dst[6] = s;
8477
+ dst[7] = 0;
8478
+ dst[8] = 0;
8479
+ dst[9] = -s;
8480
+ dst[10] = c;
8481
+ dst[11] = 0;
8482
+ dst[12] = 0;
8483
+ dst[13] = 0;
8484
+ dst[14] = 0;
8485
+ dst[15] = 1;
8486
+ return dst;
8487
+ },
8488
+ rotationY(angleInRadians, dst) {
8489
+ const c = Math.cos(angleInRadians);
8490
+ const s = Math.sin(angleInRadians);
8491
+ dst = dst || new Float32Array(16);
8492
+ dst[0] = c;
8493
+ dst[1] = 0;
8494
+ dst[2] = -s;
8495
+ dst[3] = 0;
8496
+ dst[4] = 0;
8497
+ dst[5] = 1;
8498
+ dst[6] = 0;
8499
+ dst[7] = 0;
8500
+ dst[8] = s;
8501
+ dst[9] = 0;
8502
+ dst[10] = c;
8503
+ dst[11] = 0;
8504
+ dst[12] = 0;
8505
+ dst[13] = 0;
8506
+ dst[14] = 0;
8507
+ dst[15] = 1;
8508
+ return dst;
8509
+ },
8510
+ rotationZ(angleInRadians, dst) {
8511
+ const c = Math.cos(angleInRadians);
8512
+ const s = Math.sin(angleInRadians);
8513
+ dst = dst || new Float32Array(16);
8514
+ dst[0] = c;
8515
+ dst[1] = s;
8516
+ dst[2] = 0;
8517
+ dst[3] = 0;
8518
+ dst[4] = -s;
8519
+ dst[5] = c;
8520
+ dst[6] = 0;
8521
+ dst[7] = 0;
8522
+ dst[8] = 0;
8523
+ dst[9] = 0;
8524
+ dst[10] = 1;
8525
+ dst[11] = 0;
8526
+ dst[12] = 0;
8527
+ dst[13] = 0;
8528
+ dst[14] = 0;
8529
+ dst[15] = 1;
8530
+ return dst;
8531
+ },
8532
+ scaling([sx, sy, sz], dst) {
8533
+ dst = dst || new Float32Array(16);
8534
+ dst[0] = sx;
8535
+ dst[1] = 0;
8536
+ dst[2] = 0;
8537
+ dst[3] = 0;
8538
+ dst[4] = 0;
8539
+ dst[5] = sy;
8540
+ dst[6] = 0;
8541
+ dst[7] = 0;
8542
+ dst[8] = 0;
8543
+ dst[9] = 0;
8544
+ dst[10] = sz;
8545
+ dst[11] = 0;
8546
+ dst[12] = 0;
8547
+ dst[13] = 0;
8548
+ dst[14] = 0;
8549
+ dst[15] = 1;
8550
+ return dst;
8551
+ },
8552
+ translate(m, translation, dst) {
8553
+ return mat4.multiply(m, mat4.translation(translation), dst);
8554
+ },
8555
+ rotateX(m, angleInRadians, dst) {
8556
+ return mat4.multiply(m, mat4.rotationX(angleInRadians), dst);
8557
+ },
8558
+ rotateY(m, angleInRadians, dst) {
8559
+ return mat4.multiply(m, mat4.rotationY(angleInRadians), dst);
8560
+ },
8561
+ rotateZ(m, angleInRadians, dst) {
8562
+ return mat4.multiply(m, mat4.rotationZ(angleInRadians), dst);
8563
+ },
8564
+ scale(m, scale, dst) {
8565
+ return mat4.multiply(m, mat4.scaling(scale), dst);
8566
+ }
8567
+ };
8568
+ function degToRad(degrees) {
8569
+ return degrees * Math.PI / 180;
8570
+ }
8571
+ ;
8572
+
8573
+ },{}],11:[function(require,module,exports){
8574
+ "use strict";
8575
+
8576
+ Object.defineProperty(exports, "__esModule", {
8577
+ value: true
8578
+ });
8579
+ exports.fragmentWGSL = void 0;
8580
+ let fragmentWGSL = exports.fragmentWGSL = `override shadowDepthTextureSize: f32 = 1024.0;
8581
+
8582
+ struct Scene {
8583
+ lightViewProjMatrix : mat4x4f,
8584
+ cameraViewProjMatrix : mat4x4f,
8585
+ lightPos : vec3f,
8586
+ }
8587
+
8588
+ @group(0) @binding(0) var<uniform> scene : Scene;
8589
+ @group(0) @binding(1) var shadowMap: texture_depth_2d;
8590
+ @group(0) @binding(2) var shadowSampler: sampler_comparison;
8591
+ @group(0) @binding(3) var meshTexture: texture_2d<f32>;
8592
+ @group(0) @binding(4) var meshSampler: sampler;
8593
+
8594
+ struct FragmentInput {
8595
+ @location(0) shadowPos : vec3f,
8596
+ @location(1) fragPos : vec3f,
8597
+ @location(2) fragNorm : vec3f,
8598
+ @location(3) uv : vec2f,
8599
+ }
8600
+
8601
+ const albedo = vec3f(0.9);
8602
+ const ambientFactor = 0.2;
8603
+
8604
+ @fragment
8605
+ fn main(input : FragmentInput) -> @location(0) vec4f {
8606
+ // Percentage-closer filtering. Sample texels in the region
8607
+ // to smooth the result.
8608
+ var visibility = 0.0;
8609
+ let oneOverShadowDepthTextureSize = 1.0 / shadowDepthTextureSize;
8610
+ for (var y = -1; y <= 1; y++) {
8611
+ for (var x = -1; x <= 1; x++) {
8612
+ let offset = vec2f(vec2(x, y)) * oneOverShadowDepthTextureSize;
8613
+
8614
+ visibility += textureSampleCompare(
8615
+ shadowMap, shadowSampler,
8616
+ input.shadowPos.xy + offset, input.shadowPos.z - 0.007
8617
+ );
8618
+ }
8619
+ }
8620
+ visibility /= 9.0;
8621
+
8622
+ let lambertFactor = max(dot(normalize(scene.lightPos - input.fragPos), normalize(input.fragNorm)), 0.0);
8623
+ let lightingFactor = min(ambientFactor + visibility * lambertFactor, 1.0);
8624
+ let textureColor = textureSample(meshTexture, meshSampler, input.uv);
8625
+
8626
+ return vec4(textureColor.rgb * lightingFactor * albedo, 1.0);
8627
+ }`;
8628
+
8629
+ },{}],12:[function(require,module,exports){
8630
+ "use strict";
8631
+
8632
+ Object.defineProperty(exports, "__esModule", {
8633
+ value: true
8634
+ });
8635
+ exports.UNLIT_SHADER = void 0;
8636
+ /**
8637
+ * @description
8638
+ * UNIT Texures -
8639
+ * Good for performance
8640
+ */
8641
+ const UNLIT_SHADER = exports.UNLIT_SHADER = `struct Uniforms {
8642
+ viewProjectionMatrix : mat4x4f
8643
+ }
8644
+ @group(0) @binding(0) var<uniform> uniforms : Uniforms;
8645
+
8646
+ @group(1) @binding(0) var<uniform> modelMatrix : mat4x4f;
8647
+
8648
+ struct VertexInput {
8649
+ @location(0) position : vec4f,
8650
+ @location(1) normal : vec3f,
8651
+ @location(2) uv : vec2f
8652
+ }
8653
+
8654
+ struct VertexOutput {
8655
+ @builtin(position) position : vec4f,
8656
+ @location(0) normal: vec3f,
8657
+ @location(1) uv : vec2f,
8658
+ }
8659
+
8660
+ @vertex
8661
+ fn vertexMain(input: VertexInput) -> VertexOutput {
8662
+ var output : VertexOutput;
8663
+ output.position = uniforms.viewProjectionMatrix * modelMatrix * input.position;
8664
+ output.normal = normalize((modelMatrix * vec4(input.normal, 0)).xyz);
8665
+ output.uv = input.uv;
8666
+ return output;
8667
+ }
8668
+
8669
+ @group(1) @binding(1) var meshSampler: sampler;
8670
+ @group(1) @binding(2) var meshTexture: texture_2d<f32>;
8671
+
8672
+ // Static directional lighting
8673
+ const lightDir = vec3f(1, 1, 1);
8674
+ const dirColor = vec3(1);
8675
+ const ambientColor = vec3f(0.05);
8676
+
8677
+ @fragment
8678
+ fn fragmentMain(input: VertexOutput) -> @location(0) vec4f {
8679
+ let textureColor = textureSample(meshTexture, meshSampler, input.uv);
8680
+
8681
+ // Very simplified lighting algorithm.
8682
+ let lightColor = saturate(ambientColor + max(dot(input.normal, lightDir), 0.0) * dirColor);
8683
+
8684
+ return vec4f(textureColor.rgb * lightColor, textureColor.a);
8685
+ }`;
8686
+
8687
+ },{}],13:[function(require,module,exports){
8688
+ "use strict";
8689
+
8690
+ Object.defineProperty(exports, "__esModule", {
8691
+ value: true
8692
+ });
8693
+ exports.vertexWGSL = void 0;
8694
+ let vertexWGSL = exports.vertexWGSL = `struct Scene {
8695
+ lightViewProjMatrix: mat4x4f,
8696
+ cameraViewProjMatrix: mat4x4f,
8697
+ lightPos: vec3f,
8698
+ }
8699
+
8700
+ struct Model {
8701
+ modelMatrix: mat4x4f,
8702
+ }
8703
+
8704
+ @group(0) @binding(0) var<uniform> scene : Scene;
8705
+ @group(1) @binding(0) var<uniform> model : Model;
8706
+
8707
+ struct VertexOutput {
8708
+ @location(0) shadowPos: vec3f,
8709
+ @location(1) fragPos: vec3f,
8710
+ @location(2) fragNorm: vec3f,
8711
+ @location(3) uv : vec2f,
8712
+
8713
+ @builtin(position) Position: vec4f,
8714
+ }
8715
+
8716
+ @vertex
8717
+ fn main(
8718
+ @location(0) position: vec3f,
8719
+ @location(1) normal: vec3f,
8720
+ @location(2) uv : vec2f
8721
+ ) -> VertexOutput {
8722
+ var output : VertexOutput;
8723
+
8724
+ // XY is in (-1, 1) space, Z is in (0, 1) space
8725
+ let posFromLight = scene.lightViewProjMatrix * model.modelMatrix * vec4(position, 1.0);
8726
+
8727
+ // Convert XY to (0, 1)
8728
+ // Y is flipped because texture coords are Y-down.
8729
+ output.shadowPos = vec3(
8730
+ posFromLight.xy * vec2(0.5, -0.5) + vec2(0.5),
8731
+ posFromLight.z
8732
+ );
8733
+
8734
+ output.Position = scene.cameraViewProjMatrix * model.modelMatrix * vec4(position, 1.0);
8735
+ output.fragPos = output.Position.xyz;
8736
+ output.fragNorm = normal;
8737
+ // nidza
8738
+ output.uv = uv;
8739
+
8740
+ return output;
8741
+ }
8742
+ `;
8743
+
8744
+ },{}],14:[function(require,module,exports){
8745
+ "use strict";
8746
+
8747
+ Object.defineProperty(exports, "__esModule", {
8748
+ value: true
8749
+ });
8750
+ exports.vertexShadowWGSL = void 0;
8751
+ let vertexShadowWGSL = exports.vertexShadowWGSL = `struct Scene {
8752
+ lightViewProjMatrix: mat4x4f,
8753
+ cameraViewProjMatrix: mat4x4f,
8754
+ lightPos: vec3f,
8755
+ }
8756
+
8757
+ struct Model {
8758
+ modelMatrix: mat4x4f,
8759
+ }
8760
+
8761
+ @group(0) @binding(0) var<uniform> scene : Scene;
8762
+ @group(1) @binding(0) var<uniform> model : Model;
8763
+
8764
+ @vertex
8765
+ fn main(
8766
+ @location(0) position: vec3f
8767
+ ) -> @builtin(position) vec4f {
8768
+ return scene.lightViewProjMatrix * model.modelMatrix * vec4(position, 1.0);
8769
+ }
8770
+ `;
8771
+
8772
+ },{}],15:[function(require,module,exports){
8773
+ "use strict";
8774
+
8775
+ Object.defineProperty(exports, "__esModule", {
8776
+ value: true
8777
+ });
8778
+ exports.default = void 0;
8779
+ var _wgpuMatrix = require("wgpu-matrix");
8780
+ var _ball = _interopRequireDefault(require("./engine/ball.js"));
8781
+ var _cube = _interopRequireDefault(require("./engine/cube.js"));
8782
+ var _engine = require("./engine/engine.js");
8783
+ var _mesh = _interopRequireDefault(require("./engine/mesh.js"));
8784
+ var _meshObj = _interopRequireDefault(require("./engine/mesh-obj.js"));
8785
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
8786
+ class MatrixEngineWGPU {
8787
+ mainRenderBundle = [];
8788
+ rbContainer = [];
8789
+ frame = () => {};
8790
+ entityHolder = [];
8791
+ entityArgPass = {
8792
+ loadOp: 'clear',
8793
+ storeOp: 'store',
8794
+ depthLoadOp: 'clear',
8795
+ depthStoreOp: 'store'
8796
+ };
8797
+
8798
+ // The input handler
8799
+ constructor(options, callback) {
8800
+ // console.log('typeof options ', typeof options )
8801
+ if (typeof options == 'undefined' || typeof options == "function") {
8802
+ this.options = {
8803
+ useSingleRenderPass: true,
8804
+ canvasSize: 'fullscreen'
8805
+ };
8806
+ callback = options;
8807
+ }
8808
+ this.options = options;
8809
+ var canvas = document.createElement('canvas');
8810
+ if (this.options.canvasSize == 'fullscreen') {
8811
+ canvas.width = window.innerWidth;
8812
+ canvas.height = window.innerHeight;
8813
+ } else {
8814
+ canvas.width = this.options.canvasSize.w;
8815
+ canvas.height = this.options.canvasSize.h;
8816
+ }
8817
+ document.body.append(canvas);
8818
+
8819
+ // The camera types
8820
+ const initialCameraPosition = _wgpuMatrix.vec3.create(0, 0, 0);
8821
+ this.mainCameraParams = {
8822
+ type: 'WASD',
8823
+ responseCoef: 2000
8824
+ };
8825
+ this.cameras = {
8826
+ arcball: new _engine.ArcballCamera({
8827
+ position: initialCameraPosition
8828
+ }),
8829
+ WASD: new _engine.WASDCamera({
8830
+ position: initialCameraPosition
8831
+ })
8832
+ };
8833
+ this.init({
8834
+ canvas,
8835
+ callback
8836
+ });
6325
8837
  }
6326
8838
  init = async ({
6327
8839
  canvas,
@@ -6340,17 +8852,64 @@ class MatrixEngineWGPU {
6340
8852
  format: presentationFormat,
6341
8853
  alphaMode: 'premultiplied'
6342
8854
  });
8855
+ if (this.options.useSingleRenderPass == true) {
8856
+ this.makeDefaultRenderPassDescriptor();
8857
+ this.frame = this.frameSinglePass;
8858
+ } else {
8859
+ // must be
8860
+ this.frame = this.framePassPerObject;
8861
+ }
6343
8862
  this.run(callback);
6344
8863
  };
8864
+ makeDefaultRenderPassDescriptor = () => {
8865
+ this.depthTexture = this.device.createTexture({
8866
+ size: [this.canvas.width, this.canvas.height],
8867
+ format: 'depth24plus',
8868
+ usage: GPUTextureUsage.RENDER_ATTACHMENT
8869
+ });
8870
+ this.renderPassDescriptor = {
8871
+ colorAttachments: [{
8872
+ view: undefined,
8873
+ clearValue: {
8874
+ r: 0.0,
8875
+ g: 0.0,
8876
+ b: 0.0,
8877
+ a: 1.0
8878
+ },
8879
+ loadOp: 'clear',
8880
+ storeOp: 'store'
8881
+ }],
8882
+ depthStencilAttachment: {
8883
+ view: this.depthTexture.createView(),
8884
+ depthClearValue: 1.0,
8885
+ depthLoadOp: 'clear',
8886
+ depthStoreOp: 'store'
8887
+ }
8888
+ };
8889
+ };
6345
8890
  addCube = o => {
6346
8891
  if (typeof o === 'undefined') {
6347
8892
  var o = {
8893
+ scale: 1,
6348
8894
  position: {
6349
8895
  x: 0,
6350
8896
  y: 0,
6351
8897
  z: -4
6352
8898
  },
6353
- texturesPaths: ['./res/textures/default.png']
8899
+ texturesPaths: ['./res/textures/default.png'],
8900
+ rotation: {
8901
+ x: 0,
8902
+ y: 0,
8903
+ z: 0
8904
+ },
8905
+ rotationSpeed: {
8906
+ x: 0,
8907
+ y: 0,
8908
+ z: 0
8909
+ },
8910
+ entityArgPass: this.entityArgPass,
8911
+ cameras: this.cameras,
8912
+ mainCameraParams: this.mainCameraParams
6354
8913
  };
6355
8914
  } else {
6356
8915
  if (typeof o.position === 'undefined') {
@@ -6360,9 +8919,31 @@ class MatrixEngineWGPU {
6360
8919
  z: -4
6361
8920
  };
6362
8921
  }
8922
+ if (typeof o.rotation === 'undefined') {
8923
+ o.rotation = {
8924
+ x: 0,
8925
+ y: 0,
8926
+ z: 0
8927
+ };
8928
+ }
8929
+ if (typeof o.rotationSpeed === 'undefined') {
8930
+ o.rotationSpeed = {
8931
+ x: 0,
8932
+ y: 0,
8933
+ z: 0
8934
+ };
8935
+ }
6363
8936
  if (typeof o.texturesPaths === 'undefined') {
6364
8937
  o.texturesPaths = ['./res/textures/default.png'];
6365
8938
  }
8939
+ if (typeof o.scale === 'undefined') {
8940
+ o.scale = 1;
8941
+ }
8942
+ if (typeof o.mainCameraParams === 'undefined') {
8943
+ o.mainCameraParams = this.mainCameraParams;
8944
+ }
8945
+ o.entityArgPass = this.entityArgPass;
8946
+ o.cameras = this.cameras;
6366
8947
  }
6367
8948
  let myCube1 = new _cube.default(this.canvas, this.device, this.context, o);
6368
8949
  this.mainRenderBundle.push(myCube1);
@@ -6370,12 +8951,26 @@ class MatrixEngineWGPU {
6370
8951
  addBall = o => {
6371
8952
  if (typeof o === 'undefined') {
6372
8953
  var o = {
8954
+ scale: 1,
6373
8955
  position: {
6374
8956
  x: 0,
6375
8957
  y: 0,
6376
8958
  z: -4
6377
8959
  },
6378
- texturesPaths: ['./res/textures/default.png']
8960
+ texturesPaths: ['./res/textures/default.png'],
8961
+ rotation: {
8962
+ x: 0,
8963
+ y: 0,
8964
+ z: 0
8965
+ },
8966
+ rotationSpeed: {
8967
+ x: 0,
8968
+ y: 0,
8969
+ z: 0
8970
+ },
8971
+ entityArgPass: this.entityArgPass,
8972
+ cameras: this.cameras,
8973
+ mainCameraParams: this.mainCameraParams
6379
8974
  };
6380
8975
  } else {
6381
8976
  if (typeof o.position === 'undefined') {
@@ -6385,213 +8980,172 @@ class MatrixEngineWGPU {
6385
8980
  z: -4
6386
8981
  };
6387
8982
  }
8983
+ if (typeof o.rotation === 'undefined') {
8984
+ o.rotation = {
8985
+ x: 0,
8986
+ y: 0,
8987
+ z: 0
8988
+ };
8989
+ }
8990
+ if (typeof o.rotationSpeed === 'undefined') {
8991
+ o.rotationSpeed = {
8992
+ x: 0,
8993
+ y: 0,
8994
+ z: 0
8995
+ };
8996
+ }
6388
8997
  if (typeof o.texturesPaths === 'undefined') {
6389
8998
  o.texturesPaths = ['./res/textures/default.png'];
6390
8999
  }
9000
+ if (typeof o.mainCameraParams === 'undefined') {
9001
+ o.mainCameraParams = this.mainCameraParams;
9002
+ }
9003
+ if (typeof o.scale === 'undefined') {
9004
+ o.scale = 1;
9005
+ }
9006
+ o.entityArgPass = this.entityArgPass;
9007
+ o.cameras = this.cameras;
6391
9008
  }
6392
9009
  let myBall1 = new _ball.default(this.canvas, this.device, this.context, o);
6393
9010
  this.mainRenderBundle.push(myBall1);
6394
9011
  };
9012
+ addMesh = o => {
9013
+ if (typeof o.position === 'undefined') {
9014
+ o.position = {
9015
+ x: 0,
9016
+ y: 0,
9017
+ z: -4
9018
+ };
9019
+ }
9020
+ if (typeof o.rotation === 'undefined') {
9021
+ o.rotation = {
9022
+ x: 0,
9023
+ y: 0,
9024
+ z: 0
9025
+ };
9026
+ }
9027
+ if (typeof o.rotationSpeed === 'undefined') {
9028
+ o.rotationSpeed = {
9029
+ x: 0,
9030
+ y: 0,
9031
+ z: 0
9032
+ };
9033
+ }
9034
+ if (typeof o.texturesPaths === 'undefined') {
9035
+ o.texturesPaths = ['./res/textures/default.png'];
9036
+ }
9037
+ if (typeof o.mainCameraParams === 'undefined') {
9038
+ o.mainCameraParams = this.mainCameraParams;
9039
+ }
9040
+ if (typeof o.scale === 'undefined') {
9041
+ o.scale = 1;
9042
+ }
9043
+ o.entityArgPass = this.entityArgPass;
9044
+ o.cameras = this.cameras;
9045
+ if (typeof o.name === 'undefined') {
9046
+ o.name = 'random' + Math.random();
9047
+ }
9048
+ if (typeof o.mesh === 'undefined') {
9049
+ throw console.error('arg mesh is empty...');
9050
+ return;
9051
+ }
9052
+ console.log('Mesh procedure', o);
9053
+ let myMesh1 = new _mesh.default(this.canvas, this.device, this.context, o);
9054
+ this.mainRenderBundle.push(myMesh1);
9055
+ };
9056
+ addMeshObj = o => {
9057
+ if (typeof o.position === 'undefined') {
9058
+ o.position = {
9059
+ x: 0,
9060
+ y: 0,
9061
+ z: -4
9062
+ };
9063
+ }
9064
+ if (typeof o.rotation === 'undefined') {
9065
+ o.rotation = {
9066
+ x: 0,
9067
+ y: 0,
9068
+ z: 0
9069
+ };
9070
+ }
9071
+ if (typeof o.rotationSpeed === 'undefined') {
9072
+ o.rotationSpeed = {
9073
+ x: 0,
9074
+ y: 0,
9075
+ z: 0
9076
+ };
9077
+ }
9078
+ if (typeof o.texturesPaths === 'undefined') {
9079
+ o.texturesPaths = ['./res/textures/default.png'];
9080
+ }
9081
+ if (typeof o.mainCameraParams === 'undefined') {
9082
+ o.mainCameraParams = this.mainCameraParams;
9083
+ }
9084
+ if (typeof o.scale === 'undefined') {
9085
+ o.scale = 1;
9086
+ }
9087
+ o.entityArgPass = this.entityArgPass;
9088
+ o.cameras = this.cameras;
9089
+ if (typeof o.name === 'undefined') {
9090
+ o.name = 'random' + Math.random();
9091
+ }
9092
+ if (typeof o.mesh === 'undefined') {
9093
+ throw console.error('arg mesh is empty...');
9094
+ return;
9095
+ }
9096
+ console.log('Mesh procedure', o);
9097
+ let myMesh1 = new _meshObj.default(this.canvas, this.device, this.context, o);
9098
+ this.mainRenderBundle.push(myMesh1);
9099
+ };
6395
9100
  run(callback) {
6396
9101
  setTimeout(() => {
6397
9102
  requestAnimationFrame(this.frame);
6398
- }, 1000);
9103
+ }, 500);
6399
9104
  setTimeout(() => {
6400
9105
  callback();
6401
- }, 10);
9106
+ }, 20);
6402
9107
  }
6403
- frame = () => {
9108
+ frameSinglePass = () => {
9109
+ let passEncoder;
9110
+ let commandEncoder = this.device.createCommandEncoder();
9111
+ if (typeof this.mainRenderBundle != 'undefined') this.mainRenderBundle.forEach((meItem, index) => {
9112
+ meItem.position.update();
9113
+ meItem.draw(commandEncoder);
9114
+
9115
+ //
9116
+ if (typeof meItem.done == 'undefined') {
9117
+ this.rbContainer.push(meItem.renderBundle);
9118
+ this.renderPassDescriptor.colorAttachments[0].view = this.context.getCurrentTexture().createView();
9119
+ // console.log('prolazi ')
9120
+ passEncoder = commandEncoder.beginRenderPass(this.renderPassDescriptor);
9121
+ passEncoder.executeBundles(this.rbContainer);
9122
+ passEncoder.end();
9123
+ // this.device.queue.submit([commandEncoder.finish()]);
9124
+ }
9125
+ });
9126
+ this.device.queue.submit([commandEncoder.finish()]);
9127
+ requestAnimationFrame(this.frame);
9128
+ };
9129
+ framePassPerObject = () => {
9130
+ // console.log('framePassPerObject')
6404
9131
  let commandEncoder = this.device.createCommandEncoder();
6405
9132
  this.rbContainer = [];
6406
9133
  let passEncoder;
6407
9134
  this.mainRenderBundle.forEach((meItem, index) => {
6408
- meItem.draw();
6409
- this.rbContainer.push(meItem.renderBundle);
6410
- if (index == 0) passEncoder = commandEncoder.beginRenderPass(meItem.renderPassDescriptor);
9135
+ meItem.draw(commandEncoder);
9136
+ if (meItem.renderBundle) {
9137
+ this.rbContainer.push(meItem.renderBundle);
9138
+ passEncoder = commandEncoder.beginRenderPass(meItem.renderPassDescriptor);
9139
+ passEncoder.executeBundles(this.rbContainer);
9140
+ passEncoder.end();
9141
+ } else {
9142
+ meItem.draw(commandEncoder);
9143
+ }
6411
9144
  });
6412
-
6413
- // passEncoder.executeBundles([NIK.renderBundle, NIK2.renderBundle]);
6414
- passEncoder.executeBundles(this.rbContainer);
6415
- passEncoder.end();
6416
9145
  this.device.queue.submit([commandEncoder.finish()]);
6417
9146
  requestAnimationFrame(this.frame);
6418
9147
  };
6419
9148
  }
6420
9149
  exports.default = MatrixEngineWGPU;
6421
9150
 
6422
- },{"./engine/ball.js":3,"./engine/cube.js":4}],7:[function(require,module,exports){
6423
- "use strict";
6424
-
6425
- Object.defineProperty(exports, "__esModule", {
6426
- value: true
6427
- });
6428
- exports.vertexPositionColorWGSL = exports.shaderSrc = exports.cubeTexShader = exports.basicVertWGSL = exports.basicFragWGSL = exports.BALL_SHADER = void 0;
6429
- /**
6430
- * @description
6431
- * For microdraw pixel cube texture
6432
- */
6433
- const shaderSrc = exports.shaderSrc = `struct VSUniforms {
6434
- worldViewProjection: mat4x4f,
6435
- worldInverseTranspose: mat4x4f,
6436
- };
6437
- @group(0) @binding(0) var<uniform> vsUniforms: VSUniforms;
6438
-
6439
- struct MyVSInput {
6440
- @location(0) position: vec4f,
6441
- @location(1) normal: vec3f,
6442
- @location(2) texcoord: vec2f,
6443
- };
6444
-
6445
- struct MyVSOutput {
6446
- @builtin(position) position: vec4f,
6447
- @location(0) normal: vec3f,
6448
- @location(1) texcoord: vec2f,
6449
- };
6450
-
6451
- @vertex
6452
- fn myVSMain(v: MyVSInput) -> MyVSOutput {
6453
- var vsOut: MyVSOutput;
6454
- vsOut.position = vsUniforms.worldViewProjection * v.position;
6455
- vsOut.normal = (vsUniforms.worldInverseTranspose * vec4f(v.normal, 0.0)).xyz;
6456
- vsOut.texcoord = v.texcoord;
6457
- return vsOut;
6458
- }
6459
-
6460
- struct FSUniforms {
6461
- lightDirection: vec3f,
6462
- };
6463
-
6464
- @group(0) @binding(1) var<uniform> fsUniforms: FSUniforms;
6465
- @group(0) @binding(2) var diffuseSampler: sampler;
6466
- @group(0) @binding(3) var diffuseTexture: texture_2d<f32>;
6467
-
6468
- @fragment
6469
- fn myFSMain(v: MyVSOutput) -> @location(0) vec4f {
6470
- var diffuseColor = textureSample(diffuseTexture, diffuseSampler, v.texcoord);
6471
- var a_normal = normalize(v.normal);
6472
- var l = dot(a_normal, fsUniforms.lightDirection) * 0.5 + 0.5;
6473
- return vec4f(diffuseColor.rgb * l, diffuseColor.a);
6474
- }
6475
- `;
6476
-
6477
- /**
6478
- * @description
6479
- * For Cube with images
6480
- */
6481
- const cubeTexShader = exports.cubeTexShader = `struct Uniforms {
6482
- matrix: mat4x4f,
6483
- };
6484
-
6485
- struct Vertex {
6486
- @location(0) position: vec4f,
6487
- @location(1) texcoord: vec2f,
6488
- };
6489
-
6490
- struct VSOutput {
6491
- @builtin(position) position: vec4f,
6492
- @location(0) texcoord: vec2f,
6493
- };
6494
-
6495
- @group(0) @binding(0) var<uniform> uni: Uniforms;
6496
- @group(0) @binding(1) var ourSampler: sampler;
6497
- @group(0) @binding(2) var ourTexture: texture_2d<f32>;
6498
-
6499
- @vertex fn vs(vert: Vertex) -> VSOutput {
6500
- var vsOut: VSOutput;
6501
- vsOut.position = uni.matrix * vert.position;
6502
- vsOut.texcoord = vert.texcoord;
6503
- return vsOut;
6504
- }
6505
-
6506
- @fragment fn fs(vsOut: VSOutput) -> @location(0) vec4f {
6507
- return textureSample(ourTexture, ourSampler, vsOut.texcoord);
6508
- }
6509
- `;
6510
- const basicVertWGSL = exports.basicVertWGSL = `struct Uniforms {
6511
- modelViewProjectionMatrix : mat4x4<f32>,
6512
- }
6513
- @binding(0) @group(0) var<uniform> uniforms : Uniforms;
6514
-
6515
- struct VertexOutput {
6516
- @builtin(position) Position : vec4<f32>,
6517
- @location(0) fragUV : vec2<f32>,
6518
- @location(1) fragPosition: vec4<f32>,
6519
- }
6520
-
6521
- @vertex
6522
- fn main(
6523
- @location(0) position : vec4<f32>,
6524
- @location(1) uv : vec2<f32>
6525
- ) -> VertexOutput {
6526
- var output : VertexOutput;
6527
- output.Position = uniforms.modelViewProjectionMatrix * position;
6528
- output.fragUV = uv;
6529
- output.fragPosition = 0.5 * (position + vec4(1.0, 1.0, 1.0, 1.0));
6530
- return output;
6531
- }
6532
- `;
6533
- const basicFragWGSL = exports.basicFragWGSL = `@group(0) @binding(1) var mySampler: sampler;
6534
- @group(0) @binding(2) var myTexture: texture_2d<f32>;
6535
-
6536
- @fragment
6537
- fn main(
6538
- @location(0) fragUV: vec2<f32>,
6539
- @location(1) fragPosition: vec4<f32>
6540
- ) -> @location(0) vec4<f32> {
6541
- return textureSample(myTexture, mySampler, fragUV) * fragPosition;
6542
- }
6543
- `;
6544
- const vertexPositionColorWGSL = exports.vertexPositionColorWGSL = `@fragment
6545
- fn main(
6546
- @location(0) fragUV: vec2<f32>,
6547
- @location(1) fragPosition: vec4<f32>
6548
- ) -> @location(0) vec4<f32> {
6549
- return fragPosition;
6550
- }`;
6551
- const BALL_SHADER = exports.BALL_SHADER = `struct Uniforms {
6552
- viewProjectionMatrix : mat4x4f
6553
- }
6554
- @group(0) @binding(0) var<uniform> uniforms : Uniforms;
6555
-
6556
- @group(1) @binding(0) var<uniform> modelMatrix : mat4x4f;
6557
-
6558
- struct VertexInput {
6559
- @location(0) position : vec4f,
6560
- @location(1) normal : vec3f,
6561
- @location(2) uv : vec2f
6562
- }
6563
-
6564
- struct VertexOutput {
6565
- @builtin(position) position : vec4f,
6566
- @location(0) normal: vec3f,
6567
- @location(1) uv : vec2f,
6568
- }
6569
-
6570
- @vertex
6571
- fn vertexMain(input: VertexInput) -> VertexOutput {
6572
- var output : VertexOutput;
6573
- output.position = uniforms.viewProjectionMatrix * modelMatrix * input.position;
6574
- output.normal = normalize((modelMatrix * vec4(input.normal, 0)).xyz);
6575
- output.uv = input.uv;
6576
- return output;
6577
- }
6578
-
6579
- @group(1) @binding(1) var meshSampler: sampler;
6580
- @group(1) @binding(2) var meshTexture: texture_2d<f32>;
6581
-
6582
- // Static directional lighting
6583
- const lightDir = vec3f(1, 1, 1);
6584
- const dirColor = vec3(1);
6585
- const ambientColor = vec3f(0.05);
6586
-
6587
- @fragment
6588
- fn fragmentMain(input: VertexOutput) -> @location(0) vec4f {
6589
- let textureColor = textureSample(meshTexture, meshSampler, input.uv);
6590
-
6591
- // Very simplified lighting algorithm.
6592
- let lightColor = saturate(ambientColor + max(dot(input.normal, lightDir), 0.0) * dirColor);
6593
-
6594
- return vec4f(textureColor.rgb * lightColor, textureColor.a);
6595
- }`;
6596
-
6597
- },{}]},{},[1]);
9151
+ },{"./engine/ball.js":3,"./engine/cube.js":4,"./engine/engine.js":5,"./engine/mesh-obj.js":8,"./engine/mesh.js":9,"wgpu-matrix":2}]},{},[1]);