@pirireis/webglobeplugins 0.8.26 → 0.9.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Math/arc.ts +74 -245
- package/Math/constants.ts +4 -1
- package/Math/frustum/camera.ts +32 -0
- package/Math/frustum/from-globeinfo.ts +63 -0
- package/Math/frustum/types.ts +11 -0
- package/Math/globe-util/horizon-plane.ts +137 -0
- package/Math/juction/arc-plane.ts +90 -0
- package/Math/juction/line-sphere.ts +30 -0
- package/Math/juction/plane-plane.ts +66 -0
- package/Math/line.ts +70 -0
- package/Math/methods.js +29 -1
- package/Math/plane.ts +57 -138
- package/Math/quaternion.ts +108 -144
- package/Math/types.ts +39 -30
- package/Math/vec3.ts +155 -0
- package/altitude-locator/plugin.js +1 -1
- package/bearing-line/plugin.js +1 -1
- package/circle-line-chain/plugin.js +1 -1
- package/globe-types.ts +13 -0
- package/heatwave/plugins/heatwaveglobeshell.js +5 -9
- package/index.js +3 -0
- package/package.json +1 -1
- package/programs/interface.ts +7 -0
- package/programs/line-on-globe/circle-accurate-3d.js +1 -1
- package/programs/line-on-globe/degree-padding-around-circle-3d.js +1 -1
- package/programs/line-on-globe/lines-color-instanced-flat.js +1 -1
- package/programs/line-on-globe/linestrip.ts +228 -0
- package/programs/line-on-globe/naive-accurate-flexible.js +1 -1
- package/programs/line-on-globe/to-the-surface.js +1 -1
- package/programs/picking/pickable-renderer.js +1 -1
- package/programs/point-on-globe/element-globe-surface-glow.js +1 -1
- package/programs/point-on-globe/element-point-glow.js +1 -1
- package/programs/totems/camerauniformblock.js +24 -1
- package/shape-on-terrain/arc/naive/plugin.ts +304 -0
- package/tests/Math/junction/arc-plane.test.ts +129 -0
- package/tests/Math/junction/plane-plane.test.ts +82 -0
- package/tests/Math/plane.test.ts +30 -32
- package/tests/Math/vec3.test.ts +14 -0
- package/timetracks/plugin-line-strip.js +3 -1
- package/{types.js → types.ts} +2 -1
- package/util/account/{index.js → index.ts} +1 -2
- package/util/account/single-attribute-buffer-management/buffer-orchestrator.js +0 -31
- package/util/account/single-attribute-buffer-management/index.ts +13 -0
- package/util/gl-util/buffer/{integrate-buffer.js → attribute-loader.ts} +17 -6
- package/util/gl-util/buffer/index.ts +6 -0
- package/util/gl-util/buffer/types.ts +13 -0
- package/util/gl-util/draw-options/methods.js +4 -4
- package/util/gl-util/draw-options/{types.js → types.ts} +10 -0
- package/util/gl-util/uniform-block/{manager.js → manager.ts} +24 -13
- package/util/gl-util/uniform-block/types.ts +27 -0
- package/util/heatwavedatamanager/pointcoordinatesdatacalculator.js +17 -17
- package/waveparticles/plugin.js +3 -0
- package/wind/plugin.js +39 -52
- package/Math/methodology/arc-part-on-screen.ts +0 -47
- package/Math/ray.ts +0 -101
- package/Math/vector3d.ts +0 -241
- package/shape-on-terrain/tree-search.js +0 -0
- package/surface-cover-shapes/arc/naive/data-manager.ts +0 -0
- package/surface-cover-shapes/arc/naive/plugin.ts +0 -0
- package/tests/Math/arc.test.ts +0 -112
- package/tests/Math/quaternion.test.ts +0 -98
- package/tests/Math/ray-plane.test.ts +0 -176
- package/tests/Math/vector3d.test.ts +0 -104
- package/util/account/single-attribute-buffer-management/index.js +0 -4
- package/util/gl-util/uniform-block/types.js +0 -7
- /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
|
+
});
|
package/tests/Math/plane.test.ts
CHANGED
|
@@ -1,45 +1,43 @@
|
|
|
1
|
-
import { Plane } from
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
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
|
|
7
|
-
const
|
|
8
|
-
const
|
|
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
|
-
|
|
16
|
-
|
|
17
|
-
|
|
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
|
-
|
|
40
|
-
expect(_0plane.normal.equals(normal)).toBe(true);
|
|
25
|
+
test("Plane: getUnitSphereRadiusAngle 1", () => {
|
|
41
26
|
|
|
42
|
-
|
|
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
|
-
*
|
|
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
|
|
package/{types.js → types.ts}
RENAMED
|
@@ -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
|
-
|
|
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);
|
|
@@ -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,
|
|
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,
|
|
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,
|
|
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,
|
|
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);
|
|
@@ -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
|
-
|
|
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
|
|
101
|
-
bind: this.bind
|
|
102
|
-
unbind: this.unbind
|
|
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
|
-
|
|
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
|
+
};
|