@carbonenginejs/core-math 0.1.0

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/src/vec4.js ADDED
@@ -0,0 +1,315 @@
1
+ import { vec4 as glVec4 } from "gl-matrix";
2
+ import { num } from "./num.js";
3
+ import { pool } from "./pool.js";
4
+
5
+ const vec4 = { ...glVec4 };
6
+
7
+ /**
8
+ * Vector 4
9
+ * @typedef {Float32Array} vec4
10
+ */
11
+
12
+
13
+ /**
14
+ * Allocates a pooled vec4
15
+ * @returns {Float32Array|vec4}
16
+ */
17
+ vec4.alloc = function()
18
+ {
19
+ return pool.allocF32(4);
20
+ };
21
+
22
+ /**
23
+ * Unallocates a pooled vec4
24
+ * @param {vec4|Float32Array} a
25
+ */
26
+ vec4.unalloc = function(a)
27
+ {
28
+ pool.freeType(a);
29
+ };
30
+
31
+ vec4.ZERO = vec4.fromValues(0, 0, 0, 0);
32
+
33
+ /**
34
+ * Adds a scalar to a vec4
35
+ *
36
+ * @param {vec4} out
37
+ * @param {vec4} a
38
+ * @param {Number} s
39
+ * @returns {vec4} out
40
+ */
41
+ vec4.addScalar = function(out, a, s)
42
+ {
43
+ out[0] = a[0] + s;
44
+ out[1] = a[1] + s;
45
+ out[2] = a[2] + s;
46
+ out[3] = a[3] + s;
47
+ return out;
48
+ };
49
+
50
+ /**
51
+ * Checks if all elements are 0
52
+ * @param {vec4} a
53
+ * @returns {boolean}
54
+ */
55
+ vec4.isEmpty = function(a)
56
+ {
57
+ return a[0] === 0 && a[1] === 0 && a[2] === 0 && a[3] === 0;
58
+ };
59
+
60
+ /**
61
+ * Divides a vec4 by a scalar
62
+ *
63
+ * @param {vec4} out
64
+ * @param {vec4} a
65
+ * @param {Number} s
66
+ * @returns {vec4} out
67
+ */
68
+ vec4.divideScalar = function(out, a, s)
69
+ {
70
+ return vec4.multiplyScalar(out, a, 1 / s);
71
+ };
72
+
73
+
74
+ /**
75
+ * Multiplies a vec4 by a scalar
76
+ *
77
+ * @param {vec4} out
78
+ * @param {vec4} a
79
+ * @param {Number} s
80
+ * @returns {vec4} out
81
+ */
82
+ vec4.multiplyScalar = function(out, a, s)
83
+ {
84
+ out[0] = a[0] * s;
85
+ out[1] = a[1] * s;
86
+ out[2] = a[2] * s;
87
+ out[3] = a[3] * s;
88
+ return out;
89
+ };
90
+
91
+ /**
92
+ * Sets a vec4 from a scalar
93
+ *
94
+ * @param {vec4} out
95
+ * @param {Number} s
96
+ * @returns {vec4} out
97
+ */
98
+ vec4.setScalar = function(out, s)
99
+ {
100
+ out[0] = s;
101
+ out[1] = s;
102
+ out[2] = s;
103
+ out[3] = s;
104
+ return out;
105
+ };
106
+
107
+ /**
108
+ * Subtracts a scalar from a vec4
109
+ *
110
+ * @param {vec4} out
111
+ * @param {vec4} a
112
+ * @param {Number} s
113
+ * @returns {vec4} out
114
+ */
115
+ vec4.subtractScalar = function(out, a, s)
116
+ {
117
+ out[0] = a[0] - s;
118
+ out[1] = a[1] - s;
119
+ out[2] = a[2] - s;
120
+ out[3] = a[3] - s;
121
+ return out;
122
+ };
123
+
124
+ /**
125
+ * Converts from linear color to rgba
126
+ * @param {vec4} out
127
+ * @param {vec4} linear
128
+ * @param {boolean} [denormalizeAlpha]
129
+ * @returns {vec4}
130
+ */
131
+ vec4.toRGBA = function(out, linear, denormalizeAlpha)
132
+ {
133
+ out[0] = num.colorFromLinear(linear[0]);
134
+ out[1] = num.colorFromLinear(linear[1]);
135
+ out[2] = num.colorFromLinear(linear[2]);
136
+ out[3] = denormalizeAlpha ? num.colorFromLinear(linear[3]) : linear[3];
137
+ return out;
138
+ };
139
+
140
+ /**
141
+ * Converts to linear color from rgba
142
+ * @param {vec4} out
143
+ * @param {vec4} rgba
144
+ * @param {boolean} [denormalizedAlpha]
145
+ * @returns {vec4} out
146
+ */
147
+ vec4.fromRGBA = function(out, rgba, denormalizedAlpha)
148
+ {
149
+ out[0] = num.linearFromColor(rgba[0]);
150
+ out[1] = num.linearFromColor(rgba[1]);
151
+ out[2] = num.linearFromColor(rgba[2]);
152
+ out[3] = denormalizedAlpha ? num.linearFromColor(rgba[3]) : rgba[3];
153
+ return out;
154
+ };
155
+
156
+ /**
157
+ * Converts to linear color from rgb
158
+ * @param {vec4} out
159
+ * @param {vec3} rgb
160
+ * @param {Number} [linearAlpha=1]
161
+ * @returns {vec4} out
162
+ */
163
+ vec4.fromRGB = function(out, rgb, linearAlpha = 1)
164
+ {
165
+ out[0] = num.linearFromColor(rgb[0]);
166
+ out[1] = num.linearFromColor(rgb[1]);
167
+ out[2] = num.linearFromColor(rgb[2]);
168
+ out[3] = linearAlpha;
169
+ return out;
170
+ };
171
+
172
+ /**
173
+ * Gets hex value with alpha from linear color
174
+ * @param {vec4} linear
175
+ * @returns {string} hex value
176
+ */
177
+ vec4.toHexA = function(linear)
178
+ {
179
+ return "#" +
180
+ num.hexFromLinear(linear[0]) +
181
+ num.hexFromLinear(linear[1]) +
182
+ num.hexFromLinear(linear[2]) +
183
+ num.hexFromLinear(linear[3]);
184
+ };
185
+
186
+ /**
187
+ * Gets hex value from linear color
188
+ * @param {vec4} linear
189
+ * @returns {string} hex value
190
+ */
191
+ vec4.toHex = function(linear)
192
+ {
193
+ return "#" +
194
+ num.hexFromLinear(linear[0]) +
195
+ num.hexFromLinear(linear[1]) +
196
+ num.hexFromLinear(linear[2]);
197
+ };
198
+
199
+ /**
200
+ * Gets linear color from hex or hex with alpha
201
+ * @param {vec4} out
202
+ * @param {String} hex
203
+ * @param {Number} [defaultAlpha=1]
204
+ * @return {vec4}
205
+ */
206
+ vec4.fromHex = function(out, hex, defaultAlpha = 1)
207
+ {
208
+ // Set empty color in case of error
209
+ out[0] = 0;
210
+ out[1] = 0;
211
+ out[2] = 0;
212
+ out[3] = defaultAlpha;
213
+
214
+ // RGB hex
215
+ if (hex.length === 4 || hex.length === 5)
216
+ {
217
+ out[0] = ("0x" + hex[1] + hex[1]) / 255;
218
+ out[1] = ("0x" + hex[2] + hex[2]) / 255;
219
+ out[2] = ("0x" + hex[3] + hex[3]) / 255;
220
+ if (hex.length === 5) out[3] = ("0x" + hex[4] + hex[4]) / 255;
221
+ }
222
+ // RGB hex
223
+ else if (hex.length === 7 || hex.length === 9)
224
+ {
225
+ out[0] = ("0x" + hex[1] + hex[2]) / 255;
226
+ out[1] = ("0x" + hex[3] + hex[4]) / 255;
227
+ out[2] = ("0x" + hex[5] + hex[6]) / 255;
228
+ if (hex.length === 9) out[3] = ("0x" + hex[7] + hex[8]) / 255;
229
+ }
230
+ else
231
+ {
232
+ throw new TypeError("Invalid hex");
233
+ }
234
+
235
+ return out;
236
+ };
237
+
238
+ /**
239
+ * Sets a vec4 from an array with an optional offset
240
+ * @param {vec3} out
241
+ * @param {TypedArray|Array} array
242
+ * @param {Number} [offset=0]
243
+ * @returns {vec3} out
244
+ */
245
+ vec4.fromArray = function(out, array, offset=0)
246
+ {
247
+ out[0] = array[offset];
248
+ out[1] = array[offset + 1];
249
+ out[2] = array[offset + 2];
250
+ out[3] = array[offset + 3];
251
+ return out;
252
+ };
253
+
254
+
255
+ export { vec4 };
256
+
257
+ export const {
258
+ add,
259
+ ceil,
260
+ clone,
261
+ copy,
262
+ create,
263
+ cross,
264
+ dist,
265
+ distance,
266
+ div,
267
+ divide,
268
+ dot,
269
+ equals,
270
+ exactEquals,
271
+ floor,
272
+ forEach,
273
+ fromValues,
274
+ inverse,
275
+ len,
276
+ length,
277
+ lerp,
278
+ max,
279
+ min,
280
+ mul,
281
+ multiply,
282
+ negate,
283
+ normalize,
284
+ random,
285
+ round,
286
+ scale,
287
+ scaleAndAdd,
288
+ set,
289
+ sqrDist,
290
+ sqrLen,
291
+ squaredDistance,
292
+ squaredLength,
293
+ str,
294
+ sub,
295
+ subtract,
296
+ transformMat4,
297
+ transformQuat,
298
+ zero,
299
+ alloc,
300
+ unalloc,
301
+ ZERO,
302
+ addScalar,
303
+ isEmpty,
304
+ divideScalar,
305
+ multiplyScalar,
306
+ setScalar,
307
+ subtractScalar,
308
+ toRGBA,
309
+ fromRGBA,
310
+ fromRGB,
311
+ toHexA,
312
+ toHex,
313
+ fromHex,
314
+ fromArray
315
+ } = vec4;
package/src/vertex.js ADDED
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Legacy vertex helper container backed by the shared mesh/tangent math.
3
+ *
4
+ * The previous ccpwgl implementation is intentionally not preserved here:
5
+ * normal/tangent generation now delegates to the same helpers used by the GR2,
6
+ * OBJ, glTF, and STL format packages.
7
+ */
8
+
9
+ import {
10
+ generateBiNormals,
11
+ generateNormals,
12
+ generateTangents
13
+ } from "./mesh.js";
14
+ import { packTangentFrames } from "./tangent.js";
15
+
16
+ function facesForAreas(indices, areas)
17
+ {
18
+ if (!areas || areas.length === 0) return Array.from(indices);
19
+
20
+ const faces = [];
21
+ for (const area of areas)
22
+ {
23
+ const
24
+ start = area.start || 0,
25
+ count = area.count === undefined ? indices.length - start : area.count;
26
+
27
+ for (let i = start; i < start + count; i++)
28
+ {
29
+ faces.push(indices[i]);
30
+ }
31
+ }
32
+ return faces;
33
+ }
34
+
35
+ /**
36
+ * Calculate area-weighted vertex normals.
37
+ *
38
+ * @param {ArrayLike<number>} indices Flat triangle indices.
39
+ * @param {ArrayLike<number>} positions Flat xyz positions.
40
+ * @returns {number[]} Flat xyz normals.
41
+ */
42
+ export function calculateNormals(indices, positions)
43
+ {
44
+ return generateNormals(positions, indices);
45
+ }
46
+
47
+ /**
48
+ * Calculate xyz tangents from positions, normals, UVs, and triangle indices.
49
+ *
50
+ * @param {ArrayLike<number>} indices Flat triangle indices.
51
+ * @param {ArrayLike<number>} positions Flat xyz positions.
52
+ * @param {ArrayLike<number>} uvs Flat uv coordinates.
53
+ * @param {Array<object>} [areas] Optional index ranges to use.
54
+ * @param {ArrayLike<number>} [normals] Flat xyz normals; generated when absent.
55
+ * @returns {number[]} Flat xyz tangents.
56
+ */
57
+ export function calculateTangents(indices, positions, uvs, areas, normals)
58
+ {
59
+ const faces = facesForAreas(indices, areas);
60
+ return generateTangents(
61
+ positions,
62
+ normals && normals.length ? normals : generateNormals(positions, faces),
63
+ uvs,
64
+ faces
65
+ );
66
+ }
67
+
68
+ /**
69
+ * Calculate xyz binormals from normals and tangents.
70
+ *
71
+ * @param {ArrayLike<number>} normals Flat xyz normals.
72
+ * @param {ArrayLike<number>} tangents Flat xyz tangents.
73
+ * @param {object} [options] Generation options.
74
+ * @returns {number[]} Flat xyz binormals.
75
+ */
76
+ export function calculateBiNormals(normals, tangents, options)
77
+ {
78
+ return generateBiNormals(normals, tangents, options);
79
+ }
80
+
81
+ /**
82
+ * Calculate GR2-style packed tangent frames.
83
+ *
84
+ * @param {ArrayLike<number>} indices Flat triangle indices.
85
+ * @param {ArrayLike<number>} positions Flat xyz positions.
86
+ * @param {ArrayLike<number>} uvs Flat uv coordinates.
87
+ * @param {Array<object>} [areas] Optional index ranges to use.
88
+ * @param {ArrayLike<number>} [normals] Flat xyz normals; generated when absent.
89
+ * @param {object} [options] Generation options.
90
+ * @returns {number[]} Flat xyzw packed tangent-frame values.
91
+ */
92
+ export function calculatePackedTangents(indices, positions, uvs, areas, normals, options)
93
+ {
94
+ const
95
+ faces = facesForAreas(indices, areas),
96
+ normalValues = normals && normals.length ? normals : generateNormals(positions, faces),
97
+ tangentValues = generateTangents(positions, normalValues, uvs, faces),
98
+ binormalValues = generateBiNormals(normalValues, tangentValues, options);
99
+
100
+ return packTangentFrames(normalValues, tangentValues, binormalValues);
101
+ }
102
+
103
+ export const vertex = Object.freeze({
104
+ calculateNormals,
105
+ calculateTangents,
106
+ calculateBiNormals,
107
+ calculatePackedTangents
108
+ });
109
+