@math.gl/geometry-utils 4.2.0-alpha.5
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/LICENSE +140 -0
- package/README.md +8 -0
- package/dist/attribute-compression.d.ts +50 -0
- package/dist/attribute-compression.d.ts.map +1 -0
- package/dist/attribute-compression.js +184 -0
- package/dist/attribute-compression.js.map +1 -0
- package/dist/attribute-iterator.d.ts +8 -0
- package/dist/attribute-iterator.d.ts.map +1 -0
- package/dist/attribute-iterator.js +25 -0
- package/dist/attribute-iterator.js.map +1 -0
- package/dist/compute-vertex-normals.d.ts +4 -0
- package/dist/compute-vertex-normals.d.ts.map +1 -0
- package/dist/compute-vertex-normals.js +54 -0
- package/dist/compute-vertex-normals.js.map +1 -0
- package/dist/constants.d.ts +52 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +39 -0
- package/dist/constants.js.map +1 -0
- package/dist/coordinates.d.ts +3 -0
- package/dist/coordinates.d.ts.map +1 -0
- package/dist/coordinates.js +8 -0
- package/dist/coordinates.js.map +1 -0
- package/dist/geometry.d.ts +20 -0
- package/dist/geometry.d.ts.map +1 -0
- package/dist/geometry.js +31 -0
- package/dist/geometry.js.map +1 -0
- package/dist/gl-type.d.ts +17 -0
- package/dist/gl-type.d.ts.map +1 -0
- package/dist/gl-type.js +69 -0
- package/dist/gl-type.js.map +1 -0
- package/dist/index.cjs +535 -0
- package/dist/index.cjs.map +6 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/primitive-iterator.d.ts +21 -0
- package/dist/primitive-iterator.d.ts.map +1 -0
- package/dist/primitive-iterator.js +117 -0
- package/dist/primitive-iterator.js.map +1 -0
- package/dist/rgb565.d.ts +5 -0
- package/dist/rgb565.d.ts.map +1 -0
- package/dist/rgb565.js +24 -0
- package/dist/rgb565.js.map +1 -0
- package/dist/typed-array-utils.d.ts +3 -0
- package/dist/typed-array-utils.d.ts.map +1 -0
- package/dist/typed-array-utils.js +16 -0
- package/dist/typed-array-utils.js.map +1 -0
- package/package.json +40 -0
- package/src/attribute-compression.ts +232 -0
- package/src/attribute-iterator.ts +28 -0
- package/src/compute-vertex-normals.ts +63 -0
- package/src/constants.ts +42 -0
- package/src/coordinates.ts +8 -0
- package/src/geometry.ts +49 -0
- package/src/gl-type.ts +87 -0
- package/src/index.ts +38 -0
- package/src/primitive-iterator.ts +145 -0
- package/src/rgb565.ts +26 -0
- package/src/typed-array-utils.ts +16 -0
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
// math.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
import { GL } from "./constants.js";
|
|
5
|
+
import { getAttributeValues, getPositionAttribute, isGeometry } from "./geometry.js";
|
|
6
|
+
/**
|
|
7
|
+
* Iterates through a geometry's primitives and dereferences optional indices.
|
|
8
|
+
*
|
|
9
|
+
* The legacy argument form `(indices, attributes, mode, start, end)` is also supported.
|
|
10
|
+
*/
|
|
11
|
+
export function* makePrimitiveIterator(geometryOrIndices, attributes = {}, mode, start = 0, end) {
|
|
12
|
+
let indices;
|
|
13
|
+
if (isGeometry(geometryOrIndices)) {
|
|
14
|
+
const geometry = geometryOrIndices;
|
|
15
|
+
indices = geometry.indices ? getAttributeValues(geometry.indices) : undefined;
|
|
16
|
+
attributes = geometry.attributes;
|
|
17
|
+
mode = geometry.mode;
|
|
18
|
+
if (end === undefined) {
|
|
19
|
+
const position = getPositionAttribute(geometry);
|
|
20
|
+
end = indices?.length ?? getAttributeValues(position).length / (position.size || 3);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
else if (geometryOrIndices) {
|
|
24
|
+
indices = getAttributeValues(geometryOrIndices);
|
|
25
|
+
}
|
|
26
|
+
if (mode === undefined) {
|
|
27
|
+
throw new Error('Primitive mode is required');
|
|
28
|
+
}
|
|
29
|
+
end ?? (end = indices?.length ?? start);
|
|
30
|
+
const dereference = (index) => Number(indices ? indices[index] : index);
|
|
31
|
+
let primitiveIndex = 0;
|
|
32
|
+
switch (mode) {
|
|
33
|
+
case GL.POINTS:
|
|
34
|
+
for (let index = start; index < end; index++) {
|
|
35
|
+
yield {
|
|
36
|
+
attributes,
|
|
37
|
+
type: GL.POINTS,
|
|
38
|
+
i1: dereference(index),
|
|
39
|
+
primitiveIndex: primitiveIndex++
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
return;
|
|
43
|
+
case GL.LINES:
|
|
44
|
+
for (let index = start; index + 1 < end; index += 2) {
|
|
45
|
+
yield {
|
|
46
|
+
attributes,
|
|
47
|
+
type: GL.LINES,
|
|
48
|
+
i1: dereference(index),
|
|
49
|
+
i2: dereference(index + 1),
|
|
50
|
+
primitiveIndex: primitiveIndex++
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
return;
|
|
54
|
+
case GL.LINE_STRIP:
|
|
55
|
+
for (let index = start; index + 1 < end; index++) {
|
|
56
|
+
yield {
|
|
57
|
+
attributes,
|
|
58
|
+
type: GL.LINES,
|
|
59
|
+
i1: dereference(index),
|
|
60
|
+
i2: dereference(index + 1),
|
|
61
|
+
primitiveIndex: primitiveIndex++
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
return;
|
|
65
|
+
case GL.LINE_LOOP:
|
|
66
|
+
for (let index = start; index < end; index++) {
|
|
67
|
+
yield {
|
|
68
|
+
attributes,
|
|
69
|
+
type: GL.LINES,
|
|
70
|
+
i1: dereference(index),
|
|
71
|
+
i2: dereference(index + 1 < end ? index + 1 : start),
|
|
72
|
+
primitiveIndex: primitiveIndex++
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
return;
|
|
76
|
+
case GL.TRIANGLES:
|
|
77
|
+
for (let index = start; index + 2 < end; index += 3) {
|
|
78
|
+
yield {
|
|
79
|
+
attributes,
|
|
80
|
+
type: GL.TRIANGLES,
|
|
81
|
+
i1: dereference(index),
|
|
82
|
+
i2: dereference(index + 1),
|
|
83
|
+
i3: dereference(index + 2),
|
|
84
|
+
primitiveIndex: primitiveIndex++
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
return;
|
|
88
|
+
case GL.TRIANGLE_STRIP:
|
|
89
|
+
for (let index = start; index + 2 < end; index++) {
|
|
90
|
+
const odd = (index - start) % 2 === 1;
|
|
91
|
+
yield {
|
|
92
|
+
attributes,
|
|
93
|
+
type: GL.TRIANGLES,
|
|
94
|
+
i1: dereference(odd ? index + 1 : index),
|
|
95
|
+
i2: dereference(odd ? index : index + 1),
|
|
96
|
+
i3: dereference(index + 2),
|
|
97
|
+
primitiveIndex: primitiveIndex++
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
return;
|
|
101
|
+
case GL.TRIANGLE_FAN:
|
|
102
|
+
for (let index = start + 1; index + 1 < end; index++) {
|
|
103
|
+
yield {
|
|
104
|
+
attributes,
|
|
105
|
+
type: GL.TRIANGLES,
|
|
106
|
+
i1: dereference(start),
|
|
107
|
+
i2: dereference(index),
|
|
108
|
+
i3: dereference(index + 1),
|
|
109
|
+
primitiveIndex: primitiveIndex++
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
return;
|
|
113
|
+
default:
|
|
114
|
+
throw new Error(`Unknown primitive mode ${mode}`);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=primitive-iterator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"primitive-iterator.js","sourceRoot":"","sources":["../src/primitive-iterator.ts"],"names":[],"mappings":"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"}
|
package/dist/rgb565.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/** Decodes a packed RGB565 value into 8-bit RGB components. */
|
|
2
|
+
export declare function decodeRGB565(rgb565: number, target?: number[]): number[];
|
|
3
|
+
/** Encodes 8-bit RGB components into a packed RGB565 value. */
|
|
4
|
+
export declare function encodeRGB565(rgb: ArrayLike<number>): number;
|
|
5
|
+
//# sourceMappingURL=rgb565.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rgb565.d.ts","sourceRoot":"","sources":["../src/rgb565.ts"],"names":[],"mappings":"AAIA,+DAA+D;AAC/D,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,GAAE,MAAM,EAAc,GAAG,MAAM,EAAE,CAQnF;AAED,+DAA+D;AAC/D,wBAAgB,YAAY,CAAC,GAAG,EAAE,SAAS,CAAC,MAAM,CAAC,GAAG,MAAM,CAK3D"}
|
package/dist/rgb565.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// math.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
/** Decodes a packed RGB565 value into 8-bit RGB components. */
|
|
5
|
+
export function decodeRGB565(rgb565, target = [0, 0, 0]) {
|
|
6
|
+
const red = (rgb565 >> 11) & 31;
|
|
7
|
+
const green = (rgb565 >> 5) & 63;
|
|
8
|
+
const blue = rgb565 & 31;
|
|
9
|
+
target[0] = (red << 3) | (red >> 2);
|
|
10
|
+
target[1] = (green << 2) | (green >> 4);
|
|
11
|
+
target[2] = (blue << 3) | (blue >> 2);
|
|
12
|
+
return target;
|
|
13
|
+
}
|
|
14
|
+
/** Encodes 8-bit RGB components into a packed RGB565 value. */
|
|
15
|
+
export function encodeRGB565(rgb) {
|
|
16
|
+
const red = Math.round(clampByte(rgb[0] ?? 0) * (31 / 255));
|
|
17
|
+
const green = Math.round(clampByte(rgb[1] ?? 0) * (63 / 255));
|
|
18
|
+
const blue = Math.round(clampByte(rgb[2] ?? 0) * (31 / 255));
|
|
19
|
+
return (red << 11) | (green << 5) | blue;
|
|
20
|
+
}
|
|
21
|
+
function clampByte(value) {
|
|
22
|
+
return Math.max(0, Math.min(255, value));
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=rgb565.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rgb565.js","sourceRoot":"","sources":["../src/rgb565.ts"],"names":[],"mappings":"AAAA,UAAU;AACV,+BAA+B;AAC/B,oCAAoC;AAEpC,+DAA+D;AAC/D,MAAM,UAAU,YAAY,CAAC,MAAc,EAAE,SAAmB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IACvE,MAAM,GAAG,GAAG,CAAC,MAAM,IAAI,EAAE,CAAC,GAAG,EAAE,CAAC;IAChC,MAAM,KAAK,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC,GAAG,EAAE,CAAC;IACjC,MAAM,IAAI,GAAG,MAAM,GAAG,EAAE,CAAC;IACzB,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;IACpC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC;IACxC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC;IACtC,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,+DAA+D;AAC/D,MAAM,UAAU,YAAY,CAAC,GAAsB;IACjD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC;IAC5D,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC;IAC9D,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC;IAC7D,OAAO,CAAC,GAAG,IAAI,EAAE,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC;AAC3C,CAAC;AAED,SAAS,SAAS,CAAC,KAAa;IAC9B,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;AAC3C,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"typed-array-utils.d.ts","sourceRoot":"","sources":["../src/typed-array-utils.ts"],"names":[],"mappings":"AAIA,oFAAoF;AACpF,wBAAgB,iBAAiB,CAAC,MAAM,GAAE,SAAS,eAAe,EAAO,GAAG,UAAU,CAUrF"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// math.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
/** Concatenates the visible bytes of multiple typed-array or DataView instances. */
|
|
5
|
+
export function concatTypedArrays(arrays = []) {
|
|
6
|
+
const byteLength = arrays.reduce((length, array) => length + array.byteLength, 0);
|
|
7
|
+
const result = new Uint8Array(byteLength);
|
|
8
|
+
let byteOffset = 0;
|
|
9
|
+
for (const array of arrays) {
|
|
10
|
+
const bytes = new Uint8Array(array.buffer, array.byteOffset, array.byteLength);
|
|
11
|
+
result.set(bytes, byteOffset);
|
|
12
|
+
byteOffset += bytes.byteLength;
|
|
13
|
+
}
|
|
14
|
+
return result;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=typed-array-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"typed-array-utils.js","sourceRoot":"","sources":["../src/typed-array-utils.ts"],"names":[],"mappings":"AAAA,UAAU;AACV,+BAA+B;AAC/B,oCAAoC;AAEpC,oFAAoF;AACpF,MAAM,UAAU,iBAAiB,CAAC,SAAqC,EAAE;IACvE,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,MAAM,GAAG,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;IAClF,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,UAAU,CAAC,CAAC;IAC1C,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;QAC/E,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;QAC9B,UAAU,IAAI,KAAK,CAAC,UAAU,CAAC;IACjC,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@math.gl/geometry-utils",
|
|
3
|
+
"description": "Typed-array geometry processing and attribute compression utilities",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"publishConfig": {
|
|
7
|
+
"access": "public"
|
|
8
|
+
},
|
|
9
|
+
"version": "4.2.0-alpha.5",
|
|
10
|
+
"keywords": [
|
|
11
|
+
"webgl",
|
|
12
|
+
"webgpu",
|
|
13
|
+
"geometry",
|
|
14
|
+
"typed array",
|
|
15
|
+
"attribute compression"
|
|
16
|
+
],
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "https://github.com/visgl/math.gl.git"
|
|
20
|
+
},
|
|
21
|
+
"types": "dist/index.d.ts",
|
|
22
|
+
"main": "dist/index.cjs",
|
|
23
|
+
"module": "dist/index.js",
|
|
24
|
+
"exports": {
|
|
25
|
+
".": {
|
|
26
|
+
"types": "./dist/index.d.ts",
|
|
27
|
+
"import": "./dist/index.js",
|
|
28
|
+
"require": "./dist/index.cjs"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"files": [
|
|
32
|
+
"dist",
|
|
33
|
+
"src"
|
|
34
|
+
],
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"@math.gl/core": "4.2.0-alpha.5",
|
|
37
|
+
"@math.gl/types": "4.2.0-alpha.5"
|
|
38
|
+
},
|
|
39
|
+
"gitHead": "9c13785761867748e2edb167b5f2749dce803039"
|
|
40
|
+
}
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
// math.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
// Derived from Cesium under the Apache 2.0 license.
|
|
6
|
+
// https://github.com/CesiumGS/cesium/blob/main/LICENSE.md
|
|
7
|
+
|
|
8
|
+
import {Vector2, Vector3, assert, clamp, _MathUtils} from '@math.gl/core';
|
|
9
|
+
|
|
10
|
+
type Vector4 = {x: number; y: number; z: number; w: number};
|
|
11
|
+
|
|
12
|
+
const RIGHT_SHIFT = 1 / 256;
|
|
13
|
+
const LEFT_SHIFT = 256;
|
|
14
|
+
const scratchVector2 = new Vector2();
|
|
15
|
+
const scratchVector3 = new Vector3();
|
|
16
|
+
const scratchEncodeVector2 = new Vector2();
|
|
17
|
+
const octEncodeScratch = new Vector2();
|
|
18
|
+
const uint8ForceArray = new Uint8Array(1);
|
|
19
|
+
|
|
20
|
+
function forceUint8(value: number): number {
|
|
21
|
+
uint8ForceArray[0] = value;
|
|
22
|
+
return uint8ForceArray[0];
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function fromSNorm(value: number, rangeMaximum = 255): number {
|
|
26
|
+
return (clamp(value, 0, rangeMaximum) / rangeMaximum) * 2 - 1;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function toSNorm(value: number, rangeMaximum = 255): number {
|
|
30
|
+
return Math.round((clamp(value, -1, 1) * 0.5 + 0.5) * rangeMaximum);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function signNotZero(value: number): number {
|
|
34
|
+
return value < 0 ? -1 : 1;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Encodes a normalized vector into two SNORM values following octahedral encoding.
|
|
39
|
+
*
|
|
40
|
+
* @param vector Normalized vector to encode.
|
|
41
|
+
* @param rangeMaximum Maximum value of the SNORM range.
|
|
42
|
+
* @param result Target for the two encoded components.
|
|
43
|
+
*/
|
|
44
|
+
export function octEncodeInRange(vector: Vector3, rangeMaximum: number, result: Vector2): Vector2 {
|
|
45
|
+
assert(vector);
|
|
46
|
+
assert(result);
|
|
47
|
+
scratchVector3.from(vector);
|
|
48
|
+
assert(Math.abs(scratchVector3.magnitudeSquared() - 1) <= _MathUtils.EPSILON6);
|
|
49
|
+
|
|
50
|
+
const denominator = Math.abs(vector.x) + Math.abs(vector.y) + Math.abs(vector.z);
|
|
51
|
+
result.x = vector.x / denominator;
|
|
52
|
+
result.y = vector.y / denominator;
|
|
53
|
+
|
|
54
|
+
if (vector.z < 0) {
|
|
55
|
+
const x = result.x;
|
|
56
|
+
const y = result.y;
|
|
57
|
+
result.x = (1 - Math.abs(y)) * signNotZero(x);
|
|
58
|
+
result.y = (1 - Math.abs(x)) * signNotZero(y);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
result.x = toSNorm(result.x, rangeMaximum);
|
|
62
|
+
result.y = toSNorm(result.y, rangeMaximum);
|
|
63
|
+
return result;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/** Encodes a normalized vector into two 8-bit octahedral components. */
|
|
67
|
+
export function octEncode(vector: Vector3, result: Vector2): Vector2 {
|
|
68
|
+
return octEncodeInRange(vector, 255, result);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** Encodes a normalized vector into four 8-bit octahedral components. */
|
|
72
|
+
export function octEncodeToVector4(vector: Vector3, result: Vector4): Vector4 {
|
|
73
|
+
octEncodeInRange(vector, 65535, octEncodeScratch);
|
|
74
|
+
result.x = forceUint8(octEncodeScratch.x * RIGHT_SHIFT);
|
|
75
|
+
result.y = forceUint8(octEncodeScratch.x);
|
|
76
|
+
result.z = forceUint8(octEncodeScratch.y * RIGHT_SHIFT);
|
|
77
|
+
result.w = forceUint8(octEncodeScratch.y);
|
|
78
|
+
return result;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Decodes two SNORM octahedral components into a normalized vector.
|
|
83
|
+
*
|
|
84
|
+
* @param x First encoded component.
|
|
85
|
+
* @param y Second encoded component.
|
|
86
|
+
* @param rangeMaximum Maximum value of the SNORM range.
|
|
87
|
+
* @param result Target for the decoded vector.
|
|
88
|
+
*/
|
|
89
|
+
export function octDecodeInRange(
|
|
90
|
+
x: number,
|
|
91
|
+
y: number,
|
|
92
|
+
rangeMaximum: number,
|
|
93
|
+
result: Vector3
|
|
94
|
+
): Vector3 {
|
|
95
|
+
assert(result);
|
|
96
|
+
if (x < 0 || x > rangeMaximum || y < 0 || y > rangeMaximum) {
|
|
97
|
+
throw new Error(`x and y must be unsigned normalized integers between 0 and ${rangeMaximum}`);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
result.x = fromSNorm(x, rangeMaximum);
|
|
101
|
+
result.y = fromSNorm(y, rangeMaximum);
|
|
102
|
+
result.z = 1 - (Math.abs(result.x) + Math.abs(result.y));
|
|
103
|
+
|
|
104
|
+
if (result.z < 0) {
|
|
105
|
+
const oldX = result.x;
|
|
106
|
+
result.x = (1 - Math.abs(result.y)) * signNotZero(oldX);
|
|
107
|
+
result.y = (1 - Math.abs(oldX)) * signNotZero(result.y);
|
|
108
|
+
}
|
|
109
|
+
return result.normalize();
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/** Decodes two 8-bit octahedral components into a normalized vector. */
|
|
113
|
+
export function octDecode(x: number, y: number, result: Vector3): Vector3 {
|
|
114
|
+
return octDecodeInRange(x, y, 255, result);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/** Decodes four 8-bit octahedral components into a normalized vector. */
|
|
118
|
+
export function octDecodeFromVector4(encoded: Vector4, result: Vector3): Vector3 {
|
|
119
|
+
assert(encoded);
|
|
120
|
+
assert(result);
|
|
121
|
+
const {x, y, z, w} = encoded;
|
|
122
|
+
if (x < 0 || x > 255 || y < 0 || y > 255 || z < 0 || z > 255 || w < 0 || w > 255) {
|
|
123
|
+
throw new Error('x, y, z, and w must be unsigned normalized integers between 0 and 255');
|
|
124
|
+
}
|
|
125
|
+
return octDecodeInRange(x * LEFT_SHIFT + y, z * LEFT_SHIFT + w, 65535, result);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/** Packs an octahedrally encoded two-component vector into one number. */
|
|
129
|
+
export function octPackFloat(encoded: Vector2): number {
|
|
130
|
+
scratchVector2.from(encoded);
|
|
131
|
+
return 256 * scratchVector2.x + scratchVector2.y;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/** Encodes a normalized vector into an octahedral representation packed into one number. */
|
|
135
|
+
export function octEncodeFloat(vector: Vector3): number {
|
|
136
|
+
octEncode(vector, scratchEncodeVector2);
|
|
137
|
+
return octPackFloat(scratchEncodeVector2);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/** Decodes an octahedral representation packed into one number. */
|
|
141
|
+
export function octDecodeFloat(value: number, result: Vector3): Vector3 {
|
|
142
|
+
assert(Number.isFinite(value));
|
|
143
|
+
const temporary = value / 256;
|
|
144
|
+
const x = Math.floor(temporary);
|
|
145
|
+
const y = (temporary - x) * 256;
|
|
146
|
+
return octDecode(x, y, result);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/** Packs three normalized vectors into two numeric octahedral values. */
|
|
150
|
+
export function octPack(
|
|
151
|
+
vector1: Vector3,
|
|
152
|
+
vector2: Vector3,
|
|
153
|
+
vector3: Vector3,
|
|
154
|
+
result: Vector2
|
|
155
|
+
): Vector2 {
|
|
156
|
+
assert(vector1);
|
|
157
|
+
assert(vector2);
|
|
158
|
+
assert(vector3);
|
|
159
|
+
assert(result);
|
|
160
|
+
const encoded1 = octEncodeFloat(vector1);
|
|
161
|
+
const encoded2 = octEncodeFloat(vector2);
|
|
162
|
+
const encoded3 = octEncode(vector3, scratchEncodeVector2);
|
|
163
|
+
result.x = 65536 * encoded3.x + encoded1;
|
|
164
|
+
result.y = 65536 * encoded3.y + encoded2;
|
|
165
|
+
return result;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/** Decodes three normalized vectors packed by {@link octPack}. */
|
|
169
|
+
export function octUnpack(
|
|
170
|
+
packed: Vector2,
|
|
171
|
+
vector1: Vector3,
|
|
172
|
+
vector2: Vector3,
|
|
173
|
+
vector3: Vector3
|
|
174
|
+
): void {
|
|
175
|
+
let temporary = packed.x / 65536;
|
|
176
|
+
const x = Math.floor(temporary);
|
|
177
|
+
const encodedFloat1 = (temporary - x) * 65536;
|
|
178
|
+
temporary = packed.y / 65536;
|
|
179
|
+
const y = Math.floor(temporary);
|
|
180
|
+
const encodedFloat2 = (temporary - y) * 65536;
|
|
181
|
+
octDecodeFloat(encodedFloat1, vector1);
|
|
182
|
+
octDecodeFloat(encodedFloat2, vector2);
|
|
183
|
+
octDecode(x, y, vector3);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/** Packs two normalized texture coordinates into one number with 12 bits per component. */
|
|
187
|
+
export function compressTextureCoordinates(textureCoordinates: Vector2): number {
|
|
188
|
+
const x = (textureCoordinates.x * 4095) | 0;
|
|
189
|
+
const y = (textureCoordinates.y * 4095) | 0;
|
|
190
|
+
return 4096 * x + y;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/** Decompresses texture coordinates packed by {@link compressTextureCoordinates}. */
|
|
194
|
+
export function decompressTextureCoordinates(compressed: number, result: Vector2): Vector2 {
|
|
195
|
+
const temporary = compressed / 4096;
|
|
196
|
+
const x = Math.floor(temporary);
|
|
197
|
+
result.x = x / 4095;
|
|
198
|
+
result.y = (compressed - x * 4096) / 4095;
|
|
199
|
+
return result;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/** Decodes delta- and ZigZag-encoded vertex buffers in place. */
|
|
203
|
+
export function zigZagDeltaDecode(
|
|
204
|
+
uBuffer: Uint16Array,
|
|
205
|
+
vBuffer: Uint16Array,
|
|
206
|
+
heightBuffer?: Uint16Array | number[]
|
|
207
|
+
): void {
|
|
208
|
+
assert(uBuffer);
|
|
209
|
+
assert(vBuffer);
|
|
210
|
+
assert(uBuffer.length === vBuffer.length);
|
|
211
|
+
if (heightBuffer) {
|
|
212
|
+
assert(uBuffer.length === heightBuffer.length);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
let u = 0;
|
|
216
|
+
let v = 0;
|
|
217
|
+
let height = 0;
|
|
218
|
+
for (let index = 0; index < uBuffer.length; index++) {
|
|
219
|
+
u += zigZagDecode(uBuffer[index]);
|
|
220
|
+
v += zigZagDecode(vBuffer[index]);
|
|
221
|
+
uBuffer[index] = u;
|
|
222
|
+
vBuffer[index] = v;
|
|
223
|
+
if (heightBuffer) {
|
|
224
|
+
height += zigZagDecode(heightBuffer[index]);
|
|
225
|
+
heightBuffer[index] = height;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
function zigZagDecode(value: number): number {
|
|
231
|
+
return (value >> 1) ^ -(value & 1);
|
|
232
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// math.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
import type {TypedArray, TypedArrayConstructor} from '@math.gl/types';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Iterates over the fixed-size elements of a typed array.
|
|
9
|
+
*
|
|
10
|
+
* For performance, each iteration reuses the same typed-array view-sized value.
|
|
11
|
+
*/
|
|
12
|
+
export function* makeAttributeIterator(values: TypedArray, size: number): Iterable<TypedArray> {
|
|
13
|
+
if (!Number.isInteger(size) || size <= 0) {
|
|
14
|
+
throw new Error('Attribute size must be a positive integer');
|
|
15
|
+
}
|
|
16
|
+
if (values.length % size !== 0) {
|
|
17
|
+
throw new Error('Attribute length must be divisible by its size');
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const ArrayType = values.constructor as TypedArrayConstructor;
|
|
21
|
+
const element = new ArrayType(size);
|
|
22
|
+
for (let index = 0; index < values.length; index += size) {
|
|
23
|
+
for (let componentIndex = 0; componentIndex < size; componentIndex++) {
|
|
24
|
+
element[componentIndex] = values[index + componentIndex]!;
|
|
25
|
+
}
|
|
26
|
+
yield element;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// math.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
import {Vector3} from '@math.gl/core';
|
|
6
|
+
import {GL} from './constants';
|
|
7
|
+
import type {Geometry} from './geometry';
|
|
8
|
+
import {getAttributeValues, getPositionAttribute} from './geometry';
|
|
9
|
+
import {makePrimitiveIterator} from './primitive-iterator';
|
|
10
|
+
|
|
11
|
+
/** Computes smooth, area-weighted vertex normals for a triangle geometry. */
|
|
12
|
+
export function computeVertexNormals(geometry: Geometry): Float32Array {
|
|
13
|
+
if (
|
|
14
|
+
geometry.mode !== GL.TRIANGLES &&
|
|
15
|
+
geometry.mode !== GL.TRIANGLE_STRIP &&
|
|
16
|
+
geometry.mode !== GL.TRIANGLE_FAN
|
|
17
|
+
) {
|
|
18
|
+
throw new Error('Triangle geometry is required');
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const position = getPositionAttribute(geometry);
|
|
22
|
+
const positions = getAttributeValues(position);
|
|
23
|
+
const positionSize = position.size || 3;
|
|
24
|
+
if (positionSize < 3) {
|
|
25
|
+
throw new Error('Position attributes must have at least three components');
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const vertexCount = positions.length / positionSize;
|
|
29
|
+
const normals = new Float32Array(vertexCount * 3);
|
|
30
|
+
const vectorA = new Vector3();
|
|
31
|
+
const vectorB = new Vector3();
|
|
32
|
+
const vectorC = new Vector3();
|
|
33
|
+
const edgeCB = new Vector3();
|
|
34
|
+
const edgeAB = new Vector3();
|
|
35
|
+
|
|
36
|
+
for (const primitive of makePrimitiveIterator(geometry)) {
|
|
37
|
+
const {i1, i2, i3} = primitive;
|
|
38
|
+
if (i2 === undefined || i3 === undefined) {
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
vectorA.fromArray(positions, i1 * positionSize);
|
|
42
|
+
vectorB.fromArray(positions, i2 * positionSize);
|
|
43
|
+
vectorC.fromArray(positions, i3 * positionSize);
|
|
44
|
+
const faceNormal = edgeCB
|
|
45
|
+
.subVectors(vectorC, vectorB)
|
|
46
|
+
.cross(edgeAB.subVectors(vectorA, vectorB));
|
|
47
|
+
|
|
48
|
+
for (const vertexIndex of [i1, i2, i3]) {
|
|
49
|
+
normals[vertexIndex * 3] += faceNormal.x;
|
|
50
|
+
normals[vertexIndex * 3 + 1] += faceNormal.y;
|
|
51
|
+
normals[vertexIndex * 3 + 2] += faceNormal.z;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const normal = new Vector3();
|
|
56
|
+
for (let vertexIndex = 0; vertexIndex < vertexCount; vertexIndex++) {
|
|
57
|
+
normal.fromArray(normals, vertexIndex * 3);
|
|
58
|
+
if (normal.magnitudeSquared() > 0) {
|
|
59
|
+
normal.normalize().toArray(normals, vertexIndex * 3);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return normals;
|
|
63
|
+
}
|
package/src/constants.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// math.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
/** Portable point, line, and triangle primitive types. */
|
|
6
|
+
export const GL_PRIMITIVE = {
|
|
7
|
+
POINTS: 0x0000,
|
|
8
|
+
LINES: 0x0001,
|
|
9
|
+
TRIANGLES: 0x0004
|
|
10
|
+
} as const;
|
|
11
|
+
|
|
12
|
+
/** WebGL-compatible primitive topology constants. */
|
|
13
|
+
export const GL_PRIMITIVE_MODE = {
|
|
14
|
+
POINTS: 0x0000,
|
|
15
|
+
LINES: 0x0001,
|
|
16
|
+
LINE_LOOP: 0x0002,
|
|
17
|
+
LINE_STRIP: 0x0003,
|
|
18
|
+
TRIANGLES: 0x0004,
|
|
19
|
+
TRIANGLE_STRIP: 0x0005,
|
|
20
|
+
TRIANGLE_FAN: 0x0006
|
|
21
|
+
} as const;
|
|
22
|
+
|
|
23
|
+
/** WebGL-compatible vertex component type constants. */
|
|
24
|
+
export const GL_TYPE = {
|
|
25
|
+
BYTE: 5120,
|
|
26
|
+
UNSIGNED_BYTE: 5121,
|
|
27
|
+
SHORT: 5122,
|
|
28
|
+
UNSIGNED_SHORT: 5123,
|
|
29
|
+
INT: 5124,
|
|
30
|
+
UNSIGNED_INT: 5125,
|
|
31
|
+
FLOAT: 5126,
|
|
32
|
+
DOUBLE: 5130,
|
|
33
|
+
UNSIGNED_SHORT_4_4_4_4: 32819,
|
|
34
|
+
UNSIGNED_SHORT_5_5_5_1: 32820,
|
|
35
|
+
UNSIGNED_SHORT_5_6_5: 33635
|
|
36
|
+
} as const;
|
|
37
|
+
|
|
38
|
+
/** WebGL-compatible constants used by geometry utilities. */
|
|
39
|
+
export const GL = {
|
|
40
|
+
...GL_PRIMITIVE_MODE,
|
|
41
|
+
...GL_TYPE
|
|
42
|
+
} as const;
|
package/src/geometry.ts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
// math.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
import type {TypedArray} from '@math.gl/types';
|
|
6
|
+
|
|
7
|
+
/** A typed geometry attribute with either loaders.gl-style `value` or legacy `values` storage. */
|
|
8
|
+
export type GeometryAttribute = {
|
|
9
|
+
value?: TypedArray;
|
|
10
|
+
values?: TypedArray;
|
|
11
|
+
size?: number;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
/** Minimal geometry shape understood by the geometry utilities. */
|
|
15
|
+
export type Geometry = {
|
|
16
|
+
mode: number;
|
|
17
|
+
indices?: GeometryAttribute | TypedArray;
|
|
18
|
+
attributes: Record<string, GeometryAttribute>;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
/** Returns whether a value has the minimal geometry shape. */
|
|
22
|
+
export function isGeometry(value: unknown): value is Geometry {
|
|
23
|
+
if (!value || typeof value !== 'object') {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
const geometry = value as Partial<Geometry>;
|
|
27
|
+
return typeof geometry.mode === 'number' && Boolean(geometry.attributes);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** Returns the typed array stored in a geometry attribute. */
|
|
31
|
+
export function getAttributeValues(attribute: GeometryAttribute | TypedArray): TypedArray {
|
|
32
|
+
if (ArrayBuffer.isView(attribute)) {
|
|
33
|
+
return attribute as TypedArray;
|
|
34
|
+
}
|
|
35
|
+
const values = attribute.value || attribute.values;
|
|
36
|
+
if (!values) {
|
|
37
|
+
throw new Error('Geometry attribute does not contain typed-array values');
|
|
38
|
+
}
|
|
39
|
+
return values;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** Returns a geometry's position attribute. */
|
|
43
|
+
export function getPositionAttribute(geometry: Geometry): GeometryAttribute {
|
|
44
|
+
const position = geometry.attributes['POSITION'] || geometry.attributes['positions'];
|
|
45
|
+
if (!position) {
|
|
46
|
+
throw new Error('Geometry does not contain a position attribute');
|
|
47
|
+
}
|
|
48
|
+
return position;
|
|
49
|
+
}
|