UNPKG

6.64 kBJavaScriptView Raw
1/**
2 * WebGL numeric type constants. Use {@link GL2TYPE} to convert, if needed.
3 *
4 * {@link Type}
5 * {@link GL2TYPE}
6 * {@link TYPE2GL}
7 */
8export var GLType;
9(function (GLType) {
10 GLType[GLType["I8"] = 5120] = "I8";
11 GLType[GLType["U8"] = 5121] = "U8";
12 GLType[GLType["I16"] = 5122] = "I16";
13 GLType[GLType["U16"] = 5123] = "U16";
14 GLType[GLType["I32"] = 5124] = "I32";
15 GLType[GLType["U32"] = 5125] = "U32";
16 GLType[GLType["F32"] = 5126] = "F32";
17})(GLType || (GLType = {}));
18/**
19 * Conversion from {@link GLType} to {@link Type} enums.
20 */
21export const GL2TYPE = {
22 [GLType.I8]: "i8",
23 [GLType.U8]: "u8",
24 [GLType.I16]: "i16",
25 [GLType.U16]: "u16",
26 [GLType.I32]: "i32",
27 [GLType.U32]: "u32",
28 [GLType.F32]: "f32",
29};
30/**
31 * Potentially lossy conversion from {@link Type} to {@link GLType} enums.
32 *
33 * Not all enums are mappable:
34 *
35 * - `F64` maps to `undefined`, since unsupported by WebGL
36 * - `U8C` maps to "u8"
37 */
38export const TYPE2GL = {
39 i8: GLType.I8,
40 u8: GLType.U8,
41 u8c: GLType.U8,
42 i16: GLType.I16,
43 u16: GLType.U16,
44 i32: GLType.I32,
45 u32: GLType.U32,
46 f32: GLType.F32,
47 f64: undefined,
48};
49/**
50 * Size information (in bytes) for {@link Type} and {@link BigType}. Also see
51 * {@link sizeOf}.
52 */
53export const SIZEOF = {
54 u8: 1,
55 u8c: 1,
56 i8: 1,
57 u16: 2,
58 i16: 2,
59 u32: 4,
60 i32: 4,
61 i64: 8,
62 u64: 8,
63 f32: 4,
64 f64: 8,
65};
66/**
67 * Bit shift values to convert byte addresses into array indices for all
68 * {@link Type}s and {@link BigType}s.
69 */
70export const BIT_SHIFTS = {
71 i8: 0,
72 u8: 0,
73 u8c: 0,
74 i16: 1,
75 u16: 1,
76 i32: 2,
77 u32: 2,
78 i64: 3,
79 u64: 3,
80 f32: 2,
81 f64: 3,
82};
83export const FLOAT_ARRAY_CTORS = {
84 f32: Float32Array,
85 f64: Float64Array,
86};
87export const INT_ARRAY_CTORS = {
88 i8: Int8Array,
89 i16: Int16Array,
90 i32: Int32Array,
91};
92export const UINT_ARRAY_CTORS = {
93 u8: Uint8Array,
94 u8c: Uint8ClampedArray,
95 u16: Uint16Array,
96 u32: Uint32Array,
97};
98export const BIGINT_ARRAY_CTORS = {
99 i64: BigInt64Array,
100 u64: BigUint64Array,
101};
102export const TYPEDARRAY_CTORS = {
103 ...FLOAT_ARRAY_CTORS,
104 ...INT_ARRAY_CTORS,
105 ...UINT_ARRAY_CTORS,
106};
107/**
108 * Returns canonical {@link Type} value of `type` by first
109 * attempting to resolve it as {@link GLType} enum.
110 *
111 * @example
112 * ```ts
113 * asNativeType(GLType.F32) => "f32"
114 * asNativeType("f32") => "f32"
115 * ```
116 *
117 * @param type -
118 */
119export const asNativeType = (type) => {
120 const t = GL2TYPE[type];
121 return t !== undefined ? t : type;
122};
123/**
124 * Returns suitable {@link GLType} enum of `type`.
125 *
126 * @example
127 * ```ts
128 * asGLType("f32") => GLType.F32
129 * asGLType(GLType.F32) => GLType.F32
130 * ```
131 *
132 * @param type -
133 */
134export const asGLType = (type) => {
135 const t = TYPE2GL[type];
136 return t !== undefined ? t : type;
137};
138/**
139 * Coerces given numeric args to integer values.
140 */
141export const asInt = (...args) => args.map((x) => x | 0);
142/**
143 * Returns byte size for given {@link Type} ID or {@link GLType} enum.
144 *
145 * @param type -
146 */
147export const sizeOf = (type) => SIZEOF[type] || SIZEOF[asNativeType(type)];
148export function typedArray(type, ...xs) {
149 const ctor = BIGINT_ARRAY_CTORS[type];
150 return new (ctor || TYPEDARRAY_CTORS[asNativeType(type)])(...xs);
151}
152/**
153 * Takes an {@link NumericArray} and returns its corresponding {@link Type} ID.
154 * Standard JS arrays will default to {@link "f64"}.
155 *
156 * @param x -
157 */
158export const typedArrayType = (x) => {
159 if (Array.isArray(x))
160 return "f64";
161 for (let id in TYPEDARRAY_CTORS) {
162 if (x instanceof TYPEDARRAY_CTORS[id])
163 return id;
164 }
165 return "f64";
166};
167/**
168 * Returns the smallest possible *unsigned* int type enum for given `x`.
169 * E.g. if `x <= 256`, the function returns `"u8"`.
170 *
171 * @param x - value to classify
172 */
173export const uintTypeForSize = (x) => x <= 0x100 ? "u8" : x <= 0x10000 ? "u16" : "u32";
174/**
175 * Returns the smallest possible *signed* int type enum for given `x`.
176 * E.g. if `x >= -128 && x < 128`, the function returns `"i8"`.
177 *
178 * @param x - value to classify
179 */
180export const intTypeForSize = (x) => x >= -0x80 && x < 0x80 ? "i8" : x >= -0x8000 && x < 0x8000 ? "i16" : "i32";
181/**
182 * Returns suitable {@link UintType} for given bit size (`[0,32]` range)
183 *
184 * @param x -
185 */
186export const uintTypeForBits = (x) => x > 16 ? "u32" : x > 8 ? "u16" : "u8";
187/**
188 * Returns suitable {@link IntType} for given bit size (`[0,32]` range)
189 *
190 * @param x -
191 */
192export const intTypeForBits = (x) => x > 16 ? "i32" : x > 8 ? "i16" : "i8";
193/**
194 * Returns the next smaller {@link IntType} for given type (or the same type if
195 * already the narrowest).
196 *
197 * @param t
198 */
199export const narrowInt = (t) => t === "i64" ? "i32" : t === "i32" ? "i16" : t === "i16" ? "i8" : "i8";
200/**
201 * Returns the next larger {@link IntType} for given type (or the same type if
202 * already the widest).
203 *
204 * @param t
205 */
206export const widenInt = (t) => t === "i8" ? "i16" : t === "i16" ? "i32" : t === "i32" ? "i64" : "i64";
207/**
208 * Returns the next smaller {@link UintType} for given type (or the same type if
209 * already the narrowest).
210 *
211 * @remarks
212 * If type is `u8c`, returns `u8`.
213 *
214 * @param t
215 */
216export const narrowUint = (t) => t === "u64" ? "u32" : t === "u32" ? "u16" : t === "u16" ? "u8" : "u8";
217/**
218 * Returns the next larger {@link UintType} for given type (or the same type if
219 * already the widest).
220 *
221 * @param t
222 */
223export const widenUint = (t) => t === "u8" || t === "u8c"
224 ? "u16"
225 : t === "u16"
226 ? "u32"
227 : t === "u32"
228 ? "u64"
229 : "u64";
230/**
231 * Returns the next smaller {@link FloatType} for given type (or the same type
232 * if already the narrowest).
233 *
234 * @param t
235 */
236export const narrowFloat = (t) => (t === "f64" ? "f32" : "f32");
237/**
238 * Returns the next larger {@link FloatType} for given type (or the same type if
239 * already the widest).
240 *
241 * @param t
242 */
243export const widenFloat = (t) => (t === "f32" ? "f64" : "f64");
244/**
245 * Returns the next smaller type (i.e. {@link IntType}, {@link UintType} or
246 * {@link FloatType}) for given type (or the same type if already the smallest).
247 *
248 * @param t
249 */
250export const narrowType = (t) => t[0] === "i"
251 ? narrowInt(t)
252 : t[0] === "u"
253 ? narrowUint(t)
254 : narrowFloat(t);
255/**
256 * Returns the next larger type (i.e. {@link IntType}, {@link UintType} or
257 * {@link FloatType}) for given type (or the same type if already the widest).
258 *
259 * @param t
260 */
261export const widenType = (t) => t[0] === "i"
262 ? widenInt(t)
263 : t[0] === "u"
264 ? widenUint(t)
265 : widenFloat(t);