@pirireis/webglobeplugins 0.9.1 → 0.9.3

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 (67) hide show
  1. package/Math/arc.ts +74 -245
  2. package/Math/constants.ts +4 -1
  3. package/Math/frustum/camera.ts +32 -0
  4. package/Math/frustum/from-globeinfo.ts +63 -0
  5. package/Math/frustum/types.ts +11 -0
  6. package/Math/globe-util/horizon-plane.ts +137 -0
  7. package/Math/juction/arc-plane.ts +90 -0
  8. package/Math/juction/line-sphere.ts +30 -0
  9. package/Math/juction/plane-plane.ts +66 -0
  10. package/Math/line.ts +70 -0
  11. package/Math/methods.js +29 -1
  12. package/Math/plane.ts +57 -138
  13. package/Math/quaternion.ts +108 -144
  14. package/Math/types.ts +39 -30
  15. package/Math/vec3.ts +155 -0
  16. package/altitude-locator/plugin.js +1 -1
  17. package/bearing-line/plugin.js +1 -1
  18. package/circle-line-chain/plugin.js +1 -1
  19. package/globe-types.ts +13 -0
  20. package/heatwave/plugins/heatwaveglobeshell.js +5 -9
  21. package/index.js +3 -0
  22. package/package.json +1 -1
  23. package/programs/interface.ts +7 -0
  24. package/programs/line-on-globe/circle-accurate-3d.js +1 -1
  25. package/programs/line-on-globe/degree-padding-around-circle-3d.js +1 -1
  26. package/programs/line-on-globe/lines-color-instanced-flat.js +1 -1
  27. package/programs/line-on-globe/linestrip.ts +228 -0
  28. package/programs/line-on-globe/naive-accurate-flexible.js +1 -1
  29. package/programs/line-on-globe/to-the-surface.js +1 -1
  30. package/programs/picking/pickable-renderer.js +1 -1
  31. package/programs/point-on-globe/element-globe-surface-glow.js +1 -1
  32. package/programs/point-on-globe/element-point-glow.js +1 -1
  33. package/programs/totems/camerauniformblock.js +24 -1
  34. package/programs/vectorfields/logics/drawrectangleparticles.js +1 -1
  35. package/shape-on-terrain/arc/naive/plugin.ts +304 -0
  36. package/tests/Math/junction/arc-plane.test.ts +129 -0
  37. package/tests/Math/junction/plane-plane.test.ts +82 -0
  38. package/tests/Math/plane.test.ts +30 -32
  39. package/tests/Math/vec3.test.ts +14 -0
  40. package/timetracks/plugin-line-strip.js +3 -1
  41. package/{types.js → types.ts} +2 -1
  42. package/util/account/{index.js → index.ts} +1 -2
  43. package/util/account/single-attribute-buffer-management/buffer-orchestrator.js +0 -31
  44. package/util/account/single-attribute-buffer-management/index.ts +13 -0
  45. package/util/gl-util/buffer/{integrate-buffer.js → attribute-loader.ts} +17 -6
  46. package/util/gl-util/buffer/index.ts +6 -0
  47. package/util/gl-util/buffer/types.ts +13 -0
  48. package/util/gl-util/draw-options/methods.js +4 -4
  49. package/util/gl-util/draw-options/{types.js → types.ts} +10 -0
  50. package/util/gl-util/uniform-block/{manager.js → manager.ts} +24 -13
  51. package/util/gl-util/uniform-block/types.ts +27 -0
  52. package/util/heatwavedatamanager/pointcoordinatesdatacalculator.js +17 -17
  53. package/waveparticles/plugin.js +3 -0
  54. package/wind/plugin.js +6 -19
  55. package/Math/methodology/arc-part-on-screen.ts +0 -47
  56. package/Math/ray.ts +0 -101
  57. package/Math/vector3d.ts +0 -241
  58. package/shape-on-terrain/tree-search.js +0 -0
  59. package/surface-cover-shapes/arc/naive/data-manager.ts +0 -0
  60. package/surface-cover-shapes/arc/naive/plugin.ts +0 -0
  61. package/tests/Math/arc.test.ts +0 -112
  62. package/tests/Math/quaternion.test.ts +0 -98
  63. package/tests/Math/ray-plane.test.ts +0 -176
  64. package/tests/Math/vector3d.test.ts +0 -104
  65. package/util/account/single-attribute-buffer-management/index.js +0 -4
  66. package/util/gl-util/uniform-block/types.js +0 -7
  67. /package/{shape-on-terrain/intersection.js → Math/matrix4.ts} +0 -0
@@ -0,0 +1,129 @@
1
+ import { Plane, Line, Vec3, Quaternion } from '../../../Math/types';
2
+ import { plane } from '../../../Math/plane';
3
+ import { line } from '../../../Math/line';
4
+ import { arc } from '../../../Math/arc';
5
+ import { vec3 } from '../../../Math/vec3';
6
+ import { quaternion } from '../../../Math/quaternion';
7
+ import { planePlaneJuction } from '../../../Math/juction/plane-plane';
8
+ import { arcSlice } from '../../../Math/juction/arc-plane';
9
+ import { EPSILON } from '../../../Math/constants';
10
+
11
+
12
+ const arcIn = arc.create(vec3.create(0, 0, 1), vec3.create(1, 0, 0));
13
+ const arcOut = arc.create(vec3.create(0, 0, 1), vec3.create(1, 0, 0));
14
+ const arcExpected = arc.create(vec3.create(0, 0, 1), vec3.create(1, 0, 0));
15
+ const junctionPlane = plane.create(vec3.create(0, 0, 1), 0);
16
+
17
+ const r2 = Math.sqrt(2) / 2;
18
+ const r3 = Math.sqrt(3) / 3;
19
+
20
+ beforeAll(() => {
21
+ // Initialize any necessary data or state before running the tests
22
+ arc.set(arcIn, vec3.create(0, 0, 1), vec3.create(1, 0, 0));
23
+ arc.set(arcOut, vec3.create(0, 0, 1), vec3.create(1, 0, 0));
24
+
25
+ plane.set(junctionPlane, vec3.create(0, 0, 1), 0);
26
+
27
+ });
28
+
29
+
30
+
31
+
32
+
33
+ test('arcSlice - No intersection 1', () => {
34
+ junctionPlane.distance = 2; // Set distance to ensure no intersection
35
+ const result = arcSlice(arcOut, arcIn, junctionPlane);
36
+ expect(result).toBe(false);
37
+ });
38
+
39
+
40
+
41
+ test('arcSlice - Full intersection 1', () => {
42
+ junctionPlane.distance = 0; // Set distance to ensure full intersection
43
+ const result = arcSlice(arcOut, arcIn, junctionPlane);
44
+ expect(result).toBe(true);
45
+ const isEqual = arc.equals(arcOut, arcExpected);
46
+ expect(isEqual).toBe(true);
47
+ });
48
+
49
+
50
+ test('arcSlice-1', () => {
51
+ // Set up a case where the arc intersects with the plane
52
+
53
+
54
+ const r3 = Math.sqrt(3);
55
+ const juctionNormal = vec3.create(r3, r3, r3);
56
+
57
+ plane.set(junctionPlane, juctionNormal, 0);
58
+
59
+ const result = arcSlice(arcOut, arcIn, junctionPlane);
60
+ expect(result).toBe(true);
61
+ });
62
+
63
+
64
+ test('arcSlice - Plane intersection line is out of sphere', () => {
65
+ // Set up a case where the arc intersects with the plane
66
+
67
+ const point1 = vec3.create(0, 1, 0);
68
+ const point2 = vec3.create(0, 0, 1);
69
+ arc.set(arcIn, point1, point2);
70
+
71
+ const juctionNormal = vec3.create(r3, r3, r3);
72
+
73
+ const closestPoint = vec3.create(r2, r2, 0);
74
+ const distance = vec3.dot(juctionNormal, closestPoint) + EPSILON;
75
+ plane.set(junctionPlane, juctionNormal, distance);
76
+
77
+ const result = arcSlice(arcOut, arcIn, junctionPlane);
78
+ expect(result).toBe(false);
79
+ });
80
+
81
+
82
+ test("arcSlice - Planes are parallel", () => {
83
+
84
+ const point1 = vec3.create(0, 1, 0);
85
+ const point2 = vec3.create(0, 0, 1);
86
+ arc.set(arcIn, point1, point2);
87
+
88
+ plane.fromValues(junctionPlane, 1, 0, 0, 0.3); // Set a plane parallel to the arc's normal
89
+ const result = arcSlice(arcOut, arcIn, junctionPlane);
90
+ expect(result).toBe(false); // Expect no intersection
91
+
92
+ junctionPlane.distance = -0.3;
93
+
94
+ const result2 = arcSlice(arcOut, arcIn, junctionPlane);
95
+ expect(result2).toBe(true); // Expect no intersection
96
+ const isEqual = arc.equals(arcOut, arcIn);
97
+ expect(isEqual).toBe(true); // Expect the output arc to be equal to the input arc
98
+ });
99
+
100
+
101
+ test("arcSlice - Arc sliced in half", () => {
102
+
103
+ const point1 = vec3.create(0, 1, 0);
104
+ const point2 = vec3.create(0, 0, 1);
105
+ arc.set(arcIn, point1, point2);
106
+
107
+ expect(vec3.equals(arcIn.normal, vec3.create(1, 0, 0))).toBe(true); // Arc normal should be (1, 0, 0)
108
+
109
+ plane.fromValues(junctionPlane, 0, -r2, r2, 0); // Set a plane parallel to the arc's normal
110
+
111
+ const result = arcSlice(arcOut, arcIn, junctionPlane);
112
+ expect(result).toBe(true); // Expect an intersection
113
+ const expectedPoint1 = vec3.create(0, r2, r2);
114
+ const expectedPoint2 = vec3.create(0, 0, 1);
115
+ arc.set(arcExpected, expectedPoint1, expectedPoint2);
116
+ const isEqual = arc.equals(arcOut, arcExpected);
117
+ expect(isEqual).toBe(true); // Expect the output arc to be equal to the expected arc
118
+ });
119
+
120
+
121
+ // test("arcSlice - Arc sliced in middle", () => {
122
+ // const point1 = vec3.create(0, 1, 0);
123
+ // const point2 = vec3.create(0, 0, 1);
124
+ // arc.set(arcIn, point1, point2);
125
+
126
+
127
+ // plane.fromValues(junctionPlane, 0, r2, r2, )
128
+
129
+ // });
@@ -0,0 +1,82 @@
1
+ import { Plane, Line, Vec3, Quaternion } from '../../../Math/types';
2
+ import { plane } from '../../../Math/plane';
3
+ import { line } from '../../../Math/line';
4
+ import { vec3 } from '../../../Math/vec3';
5
+ import { quaternion } from '../../../Math/quaternion';
6
+ import { planePlaneJuction } from '../../../Math/juction/plane-plane';
7
+
8
+
9
+ let plane1: Plane;
10
+ let plane2: Plane;
11
+ let intersectionLine: Line;
12
+ let quaternion1: Quaternion;
13
+
14
+ beforeAll(() => {
15
+ plane1 = plane.create();
16
+ plane2 = plane.create();
17
+ intersectionLine = line.create();
18
+ quaternion1 = quaternion.create();
19
+ });
20
+
21
+
22
+ test('plane-plane intersection - parallel planes', () => {
23
+ plane.fromValues(plane1, 0, 0, 1, 5); // Plane: z = 5
24
+ plane.fromValues(plane2, 0, 0, 1, 10); // Plane: z = 10
25
+ const result = planePlaneJuction(intersectionLine, plane1, plane2);
26
+ expect(result).toBe(false);
27
+ });
28
+
29
+ test('plane-plane intersection - intersecting planes', () => {
30
+ plane.fromValues(plane1, 0, 0, 1, 5); // Plane: z = 5
31
+ plane.fromValues(plane2, 1, 0, 0, 3); // Plane: x = 3
32
+
33
+ const result = planePlaneJuction(intersectionLine, plane1, plane2);
34
+ expect(result).toBe(true);
35
+ expect(vec3.equals(intersectionLine.direction, vec3.create(0, 1, 0))).toBe(true);
36
+ expect(vec3.equals(intersectionLine.origin, vec3.create(3, 0, 5))).toBe(true);
37
+ });
38
+
39
+
40
+ test('plane-plane intersection - rotating a plane', () => {
41
+ // plane1 z = 5
42
+ plane.fromValues(plane1, 0, 0, 1, 5);
43
+
44
+ // plane2 x = 3, for the start
45
+ vec3.randomUnit(plane2.normal);
46
+ plane2.distance = 3;
47
+
48
+ const result = planePlaneJuction(intersectionLine, plane1, plane2);
49
+ expect(result).toBe(true);
50
+ const quaRotateLine = line.clone(intersectionLine);
51
+
52
+ const step = 90;
53
+ quaternion.fromAxisAngle(quaternion1, plane1.normal, Math.PI / step); // Rotate 90 degrees around Y-axis
54
+
55
+
56
+ for (let i = 0; i < step; i++) {
57
+
58
+ vec3.applyQuaternion(plane2.normal, plane2.normal, quaternion1);
59
+
60
+ const result = planePlaneJuction(intersectionLine, plane1, plane2);
61
+
62
+
63
+ line.applyQuaternion(quaRotateLine, quaRotateLine, quaternion1);
64
+
65
+ expect(result).toBe(true);
66
+ expect(vec3.equals(intersectionLine.direction, quaRotateLine.direction)).toBe(true);
67
+ expect(line.contains(intersectionLine, quaRotateLine.origin)).toBe(true);
68
+ }
69
+ });
70
+
71
+ test("plane-plane intersection 1", () => {
72
+ const r2 = Math.sqrt(2) / 2;
73
+ plane.fromValues(plane1, 1, 0, 0, 0);
74
+ plane.fromValues(plane2, 0, -r2, r2, 0);
75
+ const result = planePlaneJuction(intersectionLine, plane1, plane2);
76
+
77
+ expect(result).toBe(true);
78
+ console.log(intersectionLine);
79
+ expect(vec3.equals(intersectionLine.direction, vec3.create(0, r2, r2)) || vec3.equals(intersectionLine.direction, vec3.create(0, -r2, -r2))
80
+ ).toBe(true);
81
+ expect(line.contains(intersectionLine, vec3.create(0, 0, 0))).toBe(true);
82
+ });
@@ -1,45 +1,43 @@
1
- import { Plane } from '../../Math/plane';
2
- import { Vector3D } from '../../Math/vector3d';
3
- import { Ray } from '../../Math/ray';
1
+ import { Plane, Vec3 } from "../../Math/types";
2
+ import { vec3 } from "../../Math/vec3";
3
+ import { plane } from "../../Math/plane";
4
4
 
5
5
 
6
- const _0vector: Vector3D = new Vector3D(0, 0, 1);
7
- const _1vector: Vector3D = new Vector3D(0, 0, 1);
8
- const _3vector: Vector3D = new Vector3D(0, 0, 1);
9
- const _0ray: Ray = new Ray(new Vector3D(0, 0, 0), new Vector3D(1, 0, 0));;
10
- const _0plane: Plane = new Plane(new Vector3D(1, 0, 0), 0);;
11
- const _1plane: Plane = new Plane(new Vector3D(1, 0, 0), 0);;
12
-
6
+ const _planeA = /*@__PURE__*/ plane.create(vec3.create(1, 0, 0), 0);
7
+ const _planeB = /*@__PURE__*/ plane.create(vec3.create(0, 1, 0), 0);
8
+ const _vecA = /*@__PURE__*/ vec3.create(1, 0, 0);
13
9
 
14
10
  beforeAll(() => {
15
- _0vector.randomUnit();
16
- _1vector.randomUnit();
17
- _3vector.randomUnit();
18
- _0plane.setFromPoints(_0vector, _1vector, _3vector);
19
- _3vector.randomUnit();
20
- _1plane.setFromPoints(_0vector, _1vector, _3vector);
11
+ vec3.set(_vecA, 1, 0, 0);
12
+ plane.set(_planeA, vec3.create(1, 0, 0), 0);
13
+ plane.set(_planeB, vec3.create(0, 1, 0), 0);
21
14
  });
22
15
 
16
+ test("Plane: getUnitSphereRadiusAngle", () => {
17
+ const angleA = plane.getUnitSphereRadiusAngle(_planeA);
18
+ const angleB = plane.getUnitSphereRadiusAngle(_planeB);
23
19
 
24
-
25
-
26
- test("Plane Intersection => Ray", () => {
27
- let result = Ray.fromTwoPlanes(_0plane, _1plane, _0ray);
28
- expect(result).toBeInstanceOf(Ray);
29
- if (result) {
30
- expect(_0ray.contains(_0vector)).toBe(true);
31
- expect(_0ray.contains(_1vector)).toBe(true);
32
- }
20
+ expect(angleA).toBeCloseTo(Math.PI / 2, 5); // 90 degrees
21
+ expect(angleB).toBeCloseTo(Math.PI / 2, 5); // 90 degrees
33
22
  });
34
23
 
35
- test("set from a normal and a point", () => {
36
- const normal = new Vector3D(1, 0, 0);
37
- const point = new Vector3D(1, 2, 3);
38
24
 
39
- _0plane.setFromNormalAndPoint(normal, point);
40
- expect(_0plane.normal.equals(normal)).toBe(true);
25
+ test("Plane: getUnitSphereRadiusAngle 1", () => {
41
26
 
42
- expect(_0plane.constant).toBe(point.dot(normal));
43
- });
27
+ vec3.set(_vecA, 1, 1, 0);
28
+ vec3.normalize(_vecA, _vecA);
29
+ const distance = Math.sqrt(2) / 2; // Distance from origin to the plane
30
+ plane.set(_planeA, _vecA, distance);
31
+ const angleA = plane.getUnitSphereRadiusAngle(_planeA);
32
+ expect(angleA).toBeCloseTo(Math.PI / 4, 5); // 45 degrees
44
33
 
34
+ for (let i = 0; i < 100; i++) {
35
+ const distance = Math.random();
45
36
 
37
+ const angle = Math.acos(distance);
38
+ vec3.randomUnit(_vecA)
39
+ plane.set(_planeA, _vecA, distance);
40
+ const angleA = plane.getUnitSphereRadiusAngle(_planeA);
41
+ expect(angleA).toBeCloseTo(angle, 5); // Check if the angle is close to the expected value
42
+ }
43
+ });
@@ -0,0 +1,14 @@
1
+ import { Vec3 } from "../../Math/types";
2
+ import { vec3 } from "../../Math/vec3";
3
+
4
+ test("vec3.create", () => {
5
+ const v = vec3.create(1, 2, 3);
6
+ expect(v).toEqual([1, 2, 3]);
7
+ });
8
+
9
+
10
+ test("vec3.length", () => {
11
+ const v = vec3.create(3, 4, 0);
12
+ const length = vec3.length(v);
13
+ expect(length).toBe(5);
14
+ });
@@ -13,12 +13,14 @@ import PointProgram from './programpoint-line-strip';
13
13
  * a1x, a1y, a1z, a1time, a1r, a1g, a1b, a1time, a3time,
14
14
  * a2x, a2y, a2z, a2time, a2r, a2g, a2b, a1time, a3time,
15
15
  * a3x, a3y, a3z, a3time, a3r, a3g, a3b, a1time, a3time,
16
- * 0, 0, 0, 0, -1, -1, -1, 0, 0,
16
+ * NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN,
17
17
  * b1x, b1y, b1z, b1time, b1r, b1g, b1b, b1time, b2time,
18
18
  * b2x, b2y, b2z, b2time, b2r, b2g, b2b, BstartTime, BendTime
19
19
  * ]
20
20
  * there is a cutting point between A and B
21
21
  *
22
+ * x, y is xy coordinates are in between 0, +1 for -180 to +180 longitude and -90 to +90 latitude
23
+ * z is height in meters
22
24
  */
23
25
 
24
26
 
@@ -13,4 +13,5 @@
13
13
 
14
14
  /**
15
15
  * * @typedef {Array<number>} Color rgba color 0-1 values
16
- */
16
+ */
17
+
@@ -2,6 +2,5 @@ import BufferOffsetManager from './bufferoffsetmanager.js';
2
2
 
3
3
  export { BufferOffsetManager };
4
4
 
5
+ export * from './single-attribute-buffer-management/index';
5
6
 
6
-
7
- export * from './single-attribute-buffer-management';
@@ -1,34 +1,3 @@
1
-
2
-
3
- /**
4
- * OffsetManager
5
- * 1) Capacity
6
- * 2) Offset account
7
- * 3) Command Buffers in its regisration list.
8
- *
9
- * How insertBulk works:
10
- * 0) autoExtendBuffers..
11
- * 1) assign offset to all keys if not already assigned.
12
- * 2) send item list to each buffer manager and let them do their job.
13
- * This cannot work. BufferManager does not know the which data to insert.
14
- * Solutions:
15
- * 1) selectMethod: insertBulk(items, offsets, selectMethod)
16
- * selectMethod(item) => itemToBlock(item)
17
- * 2) att1manager.insertBulk(items.map(item => this.att1ItemToBlock(item)), offsets)
18
- * Idea about future:
19
- * insert first tombstone.length items one by one.
20
- * insert the rest in a big float32array. IT CAN BE DONE
21
- * 3) DrawRender
22
- *
23
- * How autoExtendBuffers works:
24
- * 1) if incoming items length is greater then space left in buffer, calculate new capacity and extend all buffers.
25
- *
26
- *
27
-
28
- */
29
-
30
-
31
-
32
1
  const EXTRA_SIZE = 10;
33
2
 
34
3
  export class BufferOrchestrator {
@@ -0,0 +1,13 @@
1
+ import { BufferOrchestrator } from "./buffer-orchestrator";
2
+ import { BufferManager } from "./buffer-manager";
3
+ import { ObjectStore } from "./object-store";
4
+
5
+ type BufferManagement = Map<string, {
6
+ bufferManager: BufferManager,
7
+ adaptor: (item: any) => Float32Array,
8
+ }>;
9
+
10
+
11
+ export { BufferOrchestrator, BufferManager, ObjectStore, BufferManagement };
12
+
13
+
@@ -1,3 +1,5 @@
1
+ import './types';
2
+
1
3
 
2
4
  /**
3
5
  * @typedef BufferAndReadInfo Buffers can be intertwined or interleaved.
@@ -21,7 +23,19 @@
21
23
  * @returns
22
24
  */
23
25
 
24
- const attributeLoader = (gl, bufferAndReadInfo, index, size, { divisor = null, type = null, escapeValues = null, normalized = false } = {}) => {
26
+
27
+
28
+ const attributeLoader = (
29
+ gl: WebGL2RenderingContext,
30
+ bufferAndReadInfo: BufferAndReadInfo | null,
31
+ index: number,
32
+ size: number,
33
+ {
34
+ divisor = null,
35
+ type = null,
36
+ escapeValues = null,
37
+ normalized = false
38
+ }: AttributeLoaderOptions = {}) => {
25
39
  if (size < 1 || size > 4) throw new Error("Size must be between 1 and 4");
26
40
  if (bufferAndReadInfo == null) {
27
41
  if (escapeValues !== null) constantFunction(gl, index, size, escapeValues);
@@ -38,7 +52,6 @@ const attributeLoader = (gl, bufferAndReadInfo, index, size, { divisor = null, t
38
52
  if (stride < 0 || offset < 0) {
39
53
  throw new Error("Stride and offset must be non-negative");
40
54
  }
41
- console.log("stride", stride, "offset", offset);
42
55
  const attribType = type === null ? gl.FLOAT : type;
43
56
  gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
44
57
  gl.enableVertexAttribArray(index);
@@ -46,7 +59,6 @@ const attributeLoader = (gl, bufferAndReadInfo, index, size, { divisor = null, t
46
59
  if (divisor !== null) {
47
60
  gl.vertexAttribDivisor(index, divisor);
48
61
  }
49
-
50
62
  }
51
63
 
52
64
  /**
@@ -56,15 +68,14 @@ const attributeLoader = (gl, bufferAndReadInfo, index, size, { divisor = null, t
56
68
  * @param {number} offset
57
69
  * @returns {BufferAndReadInfo}
58
70
  */
59
- const createBufferAndReadInfo = (buffer, stride = 0, offset = 0) => {
71
+ const createBufferAndReadInfo = (buffer: WebGLBuffer, stride: number = 0, offset: number = 0): BufferAndReadInfo => {
60
72
  if (buffer == null) return null;
61
- console.log("createBufferAndReadInfo", buffer, stride, offset);
62
73
  return { buffer, stride, offset };
63
74
  }
64
75
 
65
76
 
66
77
 
67
- const constantFunction = (gl, index, size, escapeValues) => {
78
+ const constantFunction = (gl: WebGL2RenderingContext, index: number, size: number, escapeValues: Array<number>) => {
68
79
  const func = `vertexAttrib${size}f`;
69
80
  console.log(`Using constant function ${func}`, gl[func], escapeValues);
70
81
  gl[func](index, ...escapeValues);
@@ -0,0 +1,6 @@
1
+ // import './types';
2
+
3
+ import { attributeLoader } from './attribute-loader';
4
+
5
+
6
+ export { attributeLoader };
@@ -0,0 +1,13 @@
1
+
2
+ type BufferAndReadInfo = {
3
+ buffer: WebGLBuffer;
4
+ stride: number;
5
+ offset: number;
6
+ }
7
+
8
+ type AttributeLoaderOptions = {
9
+ divisor?: number | null;
10
+ type?: number | null;
11
+ escapeValues?: Array<number> | null;
12
+ normalized?: boolean;
13
+ }
@@ -10,11 +10,11 @@ import './types'
10
10
 
11
11
  // first and element effects the vertexID, which is unfortunately not effected
12
12
  const drawInstanced = (gl, mode, drawOptions, vertexCount) => {
13
- const { drawRange, indexType = gl.UNSIGNED_INT } = drawOptions;
13
+ const { drawRange, elementBufferIndexType = gl.UNSIGNED_INT } = drawOptions;
14
14
  const { first = 0, count: instanceCount = 1 } = drawRange;
15
15
  if (first > 0 || drawOptions.elementBuffer) {
16
16
  gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, drawOptions.elementBuffer);
17
- gl.drawElementsInstanced(mode, vertexCount, indexType, first, instanceCount);
17
+ gl.drawElementsInstanced(mode, vertexCount, elementBufferIndexType, first, instanceCount);
18
18
  gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
19
19
  } else {
20
20
 
@@ -31,12 +31,12 @@ const drawInstanced = (gl, mode, drawOptions, vertexCount) => {
31
31
  */
32
32
 
33
33
  const drawArrays = (gl, defaultMode, drawOptions) => {
34
- const { drawRange, elementBuffer, indexType = gl.UNSIGNED_INT, drawMode = null } = drawOptions;
34
+ const { drawRange, elementBuffer, elementBufferIndexType = gl.UNSIGNED_INT, drawMode = null } = drawOptions;
35
35
  const { first, count } = drawRange;
36
36
  const mode = drawMode ?? defaultMode;
37
37
  if (elementBuffer) {
38
38
  gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, elementBuffer);
39
- gl.drawElements(mode, count, indexType, first);
39
+ gl.drawElements(mode, count, elementBufferIndexType, first);
40
40
  gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
41
41
  } else {
42
42
  gl.drawArrays(mode, first, count);
@@ -14,5 +14,15 @@
14
14
  */
15
15
 
16
16
 
17
+ type DrawRange = {
18
+ first: number;
19
+ count: number;
20
+ };
17
21
 
22
+ type DrawRangeIndexParams = {
23
+ drawRange: DrawRange;
24
+ elementBuffer?: WebGLBuffer;
25
+ elementBufferIndexType?: number;
26
+ drawMode?: number;
27
+ };
18
28
 
@@ -55,7 +55,15 @@ class UniformBlockManager {
55
55
  * @param {Array<UniformBlockMember} blockMembers
56
56
  * @param {string} prefix usage name of block in the shader
57
57
  */
58
- constructor(blockName, blockMembers, bindingPoint, prefix = "") {
58
+
59
+ blockName: string;
60
+ blockMembers: Array<UniformBlockMember>;
61
+ bindingPoint: number;
62
+ prefix: string;
63
+ offsetMap: Map<string, number>;
64
+ size: number;
65
+
66
+ constructor(blockName: string, blockMembers: Array<UniformBlockMember>, bindingPoint: number, prefix: string = "") {
59
67
  this.blockName = blockName;
60
68
  this.blockMembers = blockMembers;
61
69
  this.bindingPoint = bindingPoint;
@@ -81,7 +89,7 @@ class UniformBlockManager {
81
89
  }
82
90
 
83
91
 
84
- createUBO(gl, bufferWriteType = "STATIC_DRAW") {
92
+ createUBO(gl: WebGL2RenderingContext, bufferWriteType = "STATIC_DRAW"): UBOHandler {
85
93
  const ubo = gl.createBuffer();
86
94
  gl.bindBuffer(gl.UNIFORM_BUFFER, ubo);
87
95
  gl.bufferData(gl.UNIFORM_BUFFER, this.size, gl[bufferWriteType]);
@@ -97,23 +105,25 @@ class UniformBlockManager {
97
105
 
98
106
  return { // TODO typedef this, encapsulate this in a class or something, ask ai
99
107
  ubo,
100
- update: this.updateUBO.bind(this, gl, ubo),
101
- bind: this.bind.bind(this, gl, ubo),
102
- unbind: this.unbind.bind(this, gl),
103
- free: () => gl.deleteBuffer(ubo)
108
+ update: (nameValueMap: NameValueMap) => this.updateUBO(gl, ubo, nameValueMap),
109
+ bind: () => this.bind(gl, ubo),
110
+ unbind: () => this.unbind(gl),
111
+ free: () => gl.deleteBuffer(ubo),
104
112
  };
105
113
  }
106
114
 
107
115
 
108
- updateUBO(gl, ubo, nameValueMap) {
116
+ updateUBO(gl: WebGL2RenderingContext, ubo: WebGLBuffer, nameValueMap: NameValueMap) {
109
117
  gl.bindBuffer(gl.UNIFORM_BUFFER, ubo);
110
118
  for (const [name, value] of nameValueMap.entries()) {
111
119
  const offset = this.offsetMap.get(name);
112
- const type = this.blockMembers.find(member => member.name === name).type;
113
120
  if (offset === undefined) {
114
121
  throw new Error(`Uniform block member ${name} not found in offset map.`);
115
122
  }
116
- let data;
123
+ console.log("Updating UBO member:", name, "with value:", value, "at offset:", offset);
124
+ const type = this.blockMembers.find(member => member.name === name).type;
125
+ console.log("Type of member:", name, "is", type);
126
+ let data: Float32Array | Int32Array | ArrayBuffer | DataView;
117
127
  if (Array.isArray(value)) {
118
128
  data = new typeArrayConstructors[type](value);
119
129
  } else if (typeof value === 'number') {
@@ -125,30 +135,31 @@ class UniformBlockManager {
125
135
  else {
126
136
  throw new Error(`Unsupported value type for ${name}: ${typeof value}`);
127
137
  }
138
+ console.log("Data to be uploaded:", data);
128
139
  gl.bufferSubData(gl.UNIFORM_BUFFER, offset, data);
129
140
  }
130
141
  gl.bindBuffer(gl.UNIFORM_BUFFER, null);
131
142
  }
132
143
 
133
144
  // call this after linking the program
134
- assignBindingPoint(gl, program) {
145
+ assignBindingPoint(gl: WebGL2RenderingContext, program: WebGLProgram) {
135
146
  const blockIndex = gl.getUniformBlockIndex(program, this.blockName);
136
147
  gl.uniformBlockBinding(program, blockIndex, this.bindingPoint);
137
148
  }
138
149
 
139
150
  // call this before drawing
140
- bind(gl, ubo) {
151
+ bind(gl: WebGL2RenderingContext, ubo: WebGLBuffer) {
141
152
  gl.bindBufferBase(gl.UNIFORM_BUFFER, this.bindingPoint, ubo);
142
153
  }
143
154
 
144
155
  // call this right after drawing
145
- unbind(gl) {
156
+ unbind(gl: WebGL2RenderingContext) {
146
157
  gl.bindBufferBase(gl.UNIFORM_BUFFER, this.bindingPoint, null);
147
158
  }
148
159
 
149
160
 
150
161
  // implicit methods
151
- __create_LayoutSTD140_OffsetMap() {
162
+ __create_LayoutSTD140_OffsetMap(): Map<string, number> {
152
163
  let offset = 0;
153
164
  const offsetMap = new Map();
154
165
  for (const member of this.blockMembers) {
@@ -0,0 +1,27 @@
1
+ /**
2
+ * @typedef {string} UniformBlockName
3
+ *
4
+ * @typedef {string} GLSLType | mat4, mat3, vec4, vec3, vec2, float, int, bool
5
+ * @typedef {{name: string, type: GLSLType, value: null|Float32Array}} UniformBlockMember
6
+ *
7
+ */
8
+
9
+
10
+ type UniformBlockName = string;
11
+ type GLSLType = "mat4" | "mat3" | "vec4" | "vec3" | "vec2" | "float" | "int" | "bool";
12
+ type UniformBlockMember = {
13
+ name: string;
14
+ type: GLSLType;
15
+ value: Float32Array | null;
16
+ };
17
+
18
+
19
+ type NameValueMap = Map<string, Array<number> | DataView | ArrayBuffer>;
20
+
21
+ type UBOHandler = {
22
+ ubo: WebGLBuffer;
23
+ update: (nameValueMap: Map<string, any>) => void;
24
+ bind: () => void;
25
+ unbind: () => void;
26
+ free: () => void;
27
+ };