@driftengine/assets 4.6.1 → 4.7.1
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/README.md +1 -1
- package/dist/blend.d.ts +25 -0
- package/dist/blend.js +43 -0
- package/dist/blendAnimation.d.ts +45 -0
- package/dist/blendAnimation.js +294 -0
- package/dist/blendData.d.ts +114 -0
- package/dist/blendData.js +366 -0
- package/dist/blendFile.d.ts +69 -0
- package/dist/blendFile.js +182 -0
- package/dist/blendGeometry.d.ts +45 -0
- package/dist/blendGeometry.js +210 -0
- package/dist/blendGltf.d.ts +65 -0
- package/dist/blendGltf.js +545 -0
- package/dist/blendMaterial.d.ts +68 -0
- package/dist/blendMaterial.js +545 -0
- package/dist/blendMatrix.d.ts +28 -0
- package/dist/blendMatrix.js +245 -0
- package/dist/blendMesh.d.ts +70 -0
- package/dist/blendMesh.js +409 -0
- package/dist/blendModifiers.d.ts +25 -0
- package/dist/blendModifiers.js +83 -0
- package/dist/blendNormals.d.ts +44 -0
- package/dist/blendNormals.js +458 -0
- package/dist/blendPacked.d.ts +35 -0
- package/dist/blendPacked.js +82 -0
- package/dist/blendScene.d.ts +50 -0
- package/dist/blendScene.js +280 -0
- package/dist/gltf.js +8 -2
- package/dist/index.d.ts +21 -0
- package/dist/index.js +17 -0
- package/dist/readModel.d.ts +13 -1
- package/dist/readModel.js +43 -13
- package/package.json +4 -4
- package/src/blend.ts +57 -0
- package/src/blendAnimation.ts +328 -0
- package/src/blendData.ts +375 -0
- package/src/blendFile.ts +233 -0
- package/src/blendGeometry.ts +263 -0
- package/src/blendGltf.ts +621 -0
- package/src/blendMaterial.ts +676 -0
- package/src/blendMatrix.ts +257 -0
- package/src/blendMesh.ts +496 -0
- package/src/blendModifiers.ts +96 -0
- package/src/blendNormals.ts +481 -0
- package/src/blendPacked.ts +93 -0
- package/src/blendScene.ts +307 -0
- package/src/gltf.ts +14 -2
- package/src/index.ts +41 -0
- package/src/readModel.ts +58 -13
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The little matrix arithmetic a `.blend` scene needs, in the conventions Blender stores it in.
|
|
3
|
+
*
|
|
4
|
+
* Column-major 4x4 as plain number arrays, which is both how Blender lays out `float[4][4]` in a
|
|
5
|
+
* file and how glTF writes `matrix`, so a matrix read from one is written to the other without a
|
|
6
|
+
* transpose. Doubles throughout: these run once per object at import, and a parent chain composes
|
|
7
|
+
* enough of them that single precision drifts visibly on a deep rig.
|
|
8
|
+
*
|
|
9
|
+
* **Every rotation here is Blender's definition, not a generic one**, because a rotation mode is a
|
|
10
|
+
* claim about order: Blender's `XYZ` turns about X first, so its matrix is `Rz · Ry · Rx`. The
|
|
11
|
+
* fixtures under `scripts/fixtures/blend` hold an object in each of the eight modes and Blender's
|
|
12
|
+
* own export of where they ended up.
|
|
13
|
+
*/
|
|
14
|
+
export const identity = () => [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
|
|
15
|
+
export function multiply(a, b) {
|
|
16
|
+
const out = new Array(16);
|
|
17
|
+
for (let c = 0; c < 4; c++) {
|
|
18
|
+
for (let r = 0; r < 4; r++) {
|
|
19
|
+
let sum = 0;
|
|
20
|
+
for (let k = 0; k < 4; k++)
|
|
21
|
+
sum += a[k * 4 + r] * b[c * 4 + k];
|
|
22
|
+
out[c * 4 + r] = sum;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return out;
|
|
26
|
+
}
|
|
27
|
+
export function multiply3(a, b) {
|
|
28
|
+
const out = new Array(9);
|
|
29
|
+
for (let c = 0; c < 3; c++) {
|
|
30
|
+
for (let r = 0; r < 3; r++) {
|
|
31
|
+
let sum = 0;
|
|
32
|
+
for (let k = 0; k < 3; k++)
|
|
33
|
+
sum += a[k * 3 + r] * b[c * 3 + k];
|
|
34
|
+
out[c * 3 + r] = sum;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return out;
|
|
38
|
+
}
|
|
39
|
+
export function invert(m) {
|
|
40
|
+
const a = m;
|
|
41
|
+
const inv = new Array(16);
|
|
42
|
+
const g = (i) => a[i];
|
|
43
|
+
inv[0] =
|
|
44
|
+
g(5) * g(10) * g(15) -
|
|
45
|
+
g(5) * g(11) * g(14) -
|
|
46
|
+
g(9) * g(6) * g(15) +
|
|
47
|
+
g(9) * g(7) * g(14) +
|
|
48
|
+
g(13) * g(6) * g(11) -
|
|
49
|
+
g(13) * g(7) * g(10);
|
|
50
|
+
inv[4] =
|
|
51
|
+
-g(4) * g(10) * g(15) +
|
|
52
|
+
g(4) * g(11) * g(14) +
|
|
53
|
+
g(8) * g(6) * g(15) -
|
|
54
|
+
g(8) * g(7) * g(14) -
|
|
55
|
+
g(12) * g(6) * g(11) +
|
|
56
|
+
g(12) * g(7) * g(10);
|
|
57
|
+
inv[8] =
|
|
58
|
+
g(4) * g(9) * g(15) -
|
|
59
|
+
g(4) * g(11) * g(13) -
|
|
60
|
+
g(8) * g(5) * g(15) +
|
|
61
|
+
g(8) * g(7) * g(13) +
|
|
62
|
+
g(12) * g(5) * g(11) -
|
|
63
|
+
g(12) * g(7) * g(9);
|
|
64
|
+
inv[12] =
|
|
65
|
+
-g(4) * g(9) * g(14) +
|
|
66
|
+
g(4) * g(10) * g(13) +
|
|
67
|
+
g(8) * g(5) * g(14) -
|
|
68
|
+
g(8) * g(6) * g(13) -
|
|
69
|
+
g(12) * g(5) * g(10) +
|
|
70
|
+
g(12) * g(6) * g(9);
|
|
71
|
+
inv[1] =
|
|
72
|
+
-g(1) * g(10) * g(15) +
|
|
73
|
+
g(1) * g(11) * g(14) +
|
|
74
|
+
g(9) * g(2) * g(15) -
|
|
75
|
+
g(9) * g(3) * g(14) -
|
|
76
|
+
g(13) * g(2) * g(11) +
|
|
77
|
+
g(13) * g(3) * g(10);
|
|
78
|
+
inv[5] =
|
|
79
|
+
g(0) * g(10) * g(15) -
|
|
80
|
+
g(0) * g(11) * g(14) -
|
|
81
|
+
g(8) * g(2) * g(15) +
|
|
82
|
+
g(8) * g(3) * g(14) +
|
|
83
|
+
g(12) * g(2) * g(11) -
|
|
84
|
+
g(12) * g(3) * g(10);
|
|
85
|
+
inv[9] =
|
|
86
|
+
-g(0) * g(9) * g(15) +
|
|
87
|
+
g(0) * g(11) * g(13) +
|
|
88
|
+
g(8) * g(1) * g(15) -
|
|
89
|
+
g(8) * g(3) * g(13) -
|
|
90
|
+
g(12) * g(1) * g(11) +
|
|
91
|
+
g(12) * g(3) * g(9);
|
|
92
|
+
inv[13] =
|
|
93
|
+
g(0) * g(9) * g(14) -
|
|
94
|
+
g(0) * g(10) * g(13) -
|
|
95
|
+
g(8) * g(1) * g(14) +
|
|
96
|
+
g(8) * g(2) * g(13) +
|
|
97
|
+
g(12) * g(1) * g(10) -
|
|
98
|
+
g(12) * g(2) * g(9);
|
|
99
|
+
inv[2] =
|
|
100
|
+
g(1) * g(6) * g(15) -
|
|
101
|
+
g(1) * g(7) * g(14) -
|
|
102
|
+
g(5) * g(2) * g(15) +
|
|
103
|
+
g(5) * g(3) * g(14) +
|
|
104
|
+
g(13) * g(2) * g(7) -
|
|
105
|
+
g(13) * g(3) * g(6);
|
|
106
|
+
inv[6] =
|
|
107
|
+
-g(0) * g(6) * g(15) +
|
|
108
|
+
g(0) * g(7) * g(14) +
|
|
109
|
+
g(4) * g(2) * g(15) -
|
|
110
|
+
g(4) * g(3) * g(14) -
|
|
111
|
+
g(12) * g(2) * g(7) +
|
|
112
|
+
g(12) * g(3) * g(6);
|
|
113
|
+
inv[10] =
|
|
114
|
+
g(0) * g(5) * g(15) -
|
|
115
|
+
g(0) * g(7) * g(13) -
|
|
116
|
+
g(4) * g(1) * g(15) +
|
|
117
|
+
g(4) * g(3) * g(13) +
|
|
118
|
+
g(12) * g(1) * g(7) -
|
|
119
|
+
g(12) * g(3) * g(5);
|
|
120
|
+
inv[14] =
|
|
121
|
+
-g(0) * g(5) * g(14) +
|
|
122
|
+
g(0) * g(6) * g(13) +
|
|
123
|
+
g(4) * g(1) * g(14) -
|
|
124
|
+
g(4) * g(2) * g(13) -
|
|
125
|
+
g(12) * g(1) * g(6) +
|
|
126
|
+
g(12) * g(2) * g(5);
|
|
127
|
+
inv[3] =
|
|
128
|
+
-g(1) * g(6) * g(11) +
|
|
129
|
+
g(1) * g(7) * g(10) +
|
|
130
|
+
g(5) * g(2) * g(11) -
|
|
131
|
+
g(5) * g(3) * g(10) -
|
|
132
|
+
g(9) * g(2) * g(7) +
|
|
133
|
+
g(9) * g(3) * g(6);
|
|
134
|
+
inv[7] =
|
|
135
|
+
g(0) * g(6) * g(11) -
|
|
136
|
+
g(0) * g(7) * g(10) -
|
|
137
|
+
g(4) * g(2) * g(11) +
|
|
138
|
+
g(4) * g(3) * g(10) +
|
|
139
|
+
g(8) * g(2) * g(7) -
|
|
140
|
+
g(8) * g(3) * g(6);
|
|
141
|
+
inv[11] =
|
|
142
|
+
-g(0) * g(5) * g(11) +
|
|
143
|
+
g(0) * g(7) * g(9) +
|
|
144
|
+
g(4) * g(1) * g(11) -
|
|
145
|
+
g(4) * g(3) * g(9) -
|
|
146
|
+
g(8) * g(1) * g(7) +
|
|
147
|
+
g(8) * g(3) * g(5);
|
|
148
|
+
inv[15] =
|
|
149
|
+
g(0) * g(5) * g(10) -
|
|
150
|
+
g(0) * g(6) * g(9) -
|
|
151
|
+
g(4) * g(1) * g(10) +
|
|
152
|
+
g(4) * g(2) * g(9) +
|
|
153
|
+
g(8) * g(1) * g(6) -
|
|
154
|
+
g(8) * g(2) * g(5);
|
|
155
|
+
const det = g(0) * inv[0] +
|
|
156
|
+
g(1) * inv[4] +
|
|
157
|
+
g(2) * inv[8] +
|
|
158
|
+
g(3) * inv[12];
|
|
159
|
+
/* Blender's `invert_m4` leaves a singular matrix as it found it, and so does this. */
|
|
160
|
+
if (Math.abs(det) < 1e-30)
|
|
161
|
+
return [...m];
|
|
162
|
+
return inv.map((v) => v / det);
|
|
163
|
+
}
|
|
164
|
+
export function translation(x, y, z) {
|
|
165
|
+
return [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, x, y, z, 1];
|
|
166
|
+
}
|
|
167
|
+
/** Rotation and scale in a 3x3, translation beside it: `T · R · S`. */
|
|
168
|
+
export function compose(location, rotation, scale) {
|
|
169
|
+
const out = identity();
|
|
170
|
+
for (let c = 0; c < 3; c++) {
|
|
171
|
+
const s = scale[c];
|
|
172
|
+
for (let r = 0; r < 3; r++)
|
|
173
|
+
out[c * 4 + r] = rotation[c * 3 + r] * s;
|
|
174
|
+
}
|
|
175
|
+
out[12] = location[0];
|
|
176
|
+
out[13] = location[1];
|
|
177
|
+
out[14] = location[2];
|
|
178
|
+
return out;
|
|
179
|
+
}
|
|
180
|
+
function axis(index, angle) {
|
|
181
|
+
const c = Math.cos(angle);
|
|
182
|
+
const s = Math.sin(angle);
|
|
183
|
+
if (index === 0)
|
|
184
|
+
return [1, 0, 0, 0, c, s, 0, -s, c];
|
|
185
|
+
if (index === 1)
|
|
186
|
+
return [c, 0, -s, 0, 1, 0, s, 0, c];
|
|
187
|
+
return [c, s, 0, -s, c, 0, 0, 0, 1];
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Blender's Euler rotation modes, by the value `Object.rotmode` stores: 1 `XYZ` to 6 `ZYX`.
|
|
191
|
+
* Each names the axes in the order they are turned about.
|
|
192
|
+
*/
|
|
193
|
+
const ORDERS = {
|
|
194
|
+
1: [0, 1, 2],
|
|
195
|
+
2: [0, 2, 1],
|
|
196
|
+
3: [1, 0, 2],
|
|
197
|
+
4: [1, 2, 0],
|
|
198
|
+
5: [2, 0, 1],
|
|
199
|
+
6: [2, 1, 0],
|
|
200
|
+
};
|
|
201
|
+
export function eulerMatrix(e, mode) {
|
|
202
|
+
const order = ORDERS[mode] ?? ORDERS[1];
|
|
203
|
+
const [first, second, third] = order;
|
|
204
|
+
const turn = (i) => axis(i, e[i]);
|
|
205
|
+
return multiply3(turn(third), multiply3(turn(second), turn(first)));
|
|
206
|
+
}
|
|
207
|
+
/** A quaternion as Blender stores it, `w` first, normalised before use as Blender does. */
|
|
208
|
+
export function quaternionMatrix(q) {
|
|
209
|
+
let [w, x, y, z] = q;
|
|
210
|
+
const length = Math.hypot(w, x, y, z);
|
|
211
|
+
if (length < 1e-12)
|
|
212
|
+
return [1, 0, 0, 0, 1, 0, 0, 0, 1];
|
|
213
|
+
w /= length;
|
|
214
|
+
x /= length;
|
|
215
|
+
y /= length;
|
|
216
|
+
z /= length;
|
|
217
|
+
return [
|
|
218
|
+
1 - 2 * (y * y + z * z),
|
|
219
|
+
2 * (x * y + w * z),
|
|
220
|
+
2 * (x * z - w * y),
|
|
221
|
+
2 * (x * y - w * z),
|
|
222
|
+
1 - 2 * (x * x + z * z),
|
|
223
|
+
2 * (y * z + w * x),
|
|
224
|
+
2 * (x * z + w * y),
|
|
225
|
+
2 * (y * z - w * x),
|
|
226
|
+
1 - 2 * (x * x + y * y),
|
|
227
|
+
];
|
|
228
|
+
}
|
|
229
|
+
export function axisAngleMatrix(direction, angle) {
|
|
230
|
+
const [x, y, z] = direction;
|
|
231
|
+
const length = Math.hypot(x, y, z);
|
|
232
|
+
if (length < 1e-12)
|
|
233
|
+
return [1, 0, 0, 0, 1, 0, 0, 0, 1];
|
|
234
|
+
const s = Math.sin(angle / 2) / length;
|
|
235
|
+
return quaternionMatrix([Math.cos(angle / 2), x * s, y * s, z * s]);
|
|
236
|
+
}
|
|
237
|
+
/** Transform a point by a column-major 4x4. */
|
|
238
|
+
export function transformPoint(m, x, y, z) {
|
|
239
|
+
const g = (i) => m[i];
|
|
240
|
+
return [
|
|
241
|
+
g(0) * x + g(4) * y + g(8) * z + g(12),
|
|
242
|
+
g(1) * x + g(5) * y + g(9) * z + g(13),
|
|
243
|
+
g(2) * x + g(6) * y + g(10) * z + g(14),
|
|
244
|
+
];
|
|
245
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A `.blend` mesh's stored data, read the same way whichever Blender wrote it.
|
|
3
|
+
*
|
|
4
|
+
* **Three layouts, one result.** Until 3.4 a mesh was arrays of structs — `MVert`, `MEdge`,
|
|
5
|
+
* `MPoly`, `MLoop` — with UVs and colours in `CustomData` layers beside them. From 3.5 to 4.x the
|
|
6
|
+
* same data became named attributes in `CustomData`: `position`, `.edge_verts`, `.corner_vert`,
|
|
7
|
+
* `sharp_face`. From 5.0 the attributes moved again, into `AttributeStorage`, with a type code of
|
|
8
|
+
* their own. Each is read here into `BlendMeshData`, which is plain arrays and knows nothing about
|
|
9
|
+
* where they came from.
|
|
10
|
+
*
|
|
11
|
+
* **What is read is what is stored.** Nothing is evaluated: a mesh with modifiers is the mesh
|
|
12
|
+
* before them, and `blend.ts` refuses such a file rather than drawing the wrong shape.
|
|
13
|
+
*
|
|
14
|
+
* **Old meaning is translated to current meaning**, because the comparison is with Blender as it
|
|
15
|
+
* is now opening the file. Before 4.1 a sharp edge did nothing unless the mesh had auto smooth on,
|
|
16
|
+
* and Blender drops those edges when it opens such a file; with auto smooth on, it adds a modifier
|
|
17
|
+
* that splits by angle, which is exactly the angle this reader applies.
|
|
18
|
+
*/
|
|
19
|
+
import type { BlendData, BlendStruct } from './blendData.ts';
|
|
20
|
+
/** Domains, in the order both of Blender's attribute systems number them. */
|
|
21
|
+
export declare const POINT = 0;
|
|
22
|
+
export declare const EDGE = 1;
|
|
23
|
+
export declare const FACE = 2;
|
|
24
|
+
export declare const CORNER = 3;
|
|
25
|
+
export interface BlendColorLayer {
|
|
26
|
+
readonly name: string;
|
|
27
|
+
readonly domain: typeof POINT | typeof CORNER;
|
|
28
|
+
/** RGBA per element, linear. A byte colour is stored sRGB-encoded and decoded here. */
|
|
29
|
+
readonly rgba: Float32Array;
|
|
30
|
+
}
|
|
31
|
+
export interface BlendMeshData {
|
|
32
|
+
readonly name: string;
|
|
33
|
+
readonly positions: Float32Array;
|
|
34
|
+
/** Face `f` owns corners `faceOffsets[f]` to `faceOffsets[f + 1]`. */
|
|
35
|
+
readonly faceOffsets: Int32Array;
|
|
36
|
+
readonly cornerVerts: Int32Array;
|
|
37
|
+
readonly cornerEdges: Int32Array;
|
|
38
|
+
readonly edgeVerts: Int32Array;
|
|
39
|
+
readonly materialIndex: Int32Array | null;
|
|
40
|
+
readonly sharpFace: Uint8Array | null;
|
|
41
|
+
readonly sharpEdge: Uint8Array | null;
|
|
42
|
+
/** UV maps in the file's order, two floats per corner. */
|
|
43
|
+
readonly uvs: readonly {
|
|
44
|
+
name: string;
|
|
45
|
+
uv: Float32Array;
|
|
46
|
+
}[];
|
|
47
|
+
/** Which UV map renders when a texture names none: Blender's "active render" map. */
|
|
48
|
+
readonly renderUv: number;
|
|
49
|
+
readonly colors: readonly BlendColorLayer[];
|
|
50
|
+
/** The colour attribute a material's unnamed Color Attribute node reads. */
|
|
51
|
+
readonly renderColor: number;
|
|
52
|
+
/** Custom normals in Blender's packed form: two shorts per corner, relative to its fan. */
|
|
53
|
+
readonly packedNormals: Int16Array | null;
|
|
54
|
+
/** Custom normals stored as plain vectors, 4.5 on, in the domain they were written to. */
|
|
55
|
+
readonly freeNormals: {
|
|
56
|
+
domain: number;
|
|
57
|
+
normals: Float32Array;
|
|
58
|
+
} | null;
|
|
59
|
+
/** The split angle a pre-4.1 file's auto smooth asked for, or null where it was off. */
|
|
60
|
+
readonly autoSmooth: number | null;
|
|
61
|
+
/** Per vertex, the groups it belongs to and how much: flattened `(group, weight)` pairs. */
|
|
62
|
+
readonly weights: {
|
|
63
|
+
offsets: Int32Array;
|
|
64
|
+
groups: Int32Array;
|
|
65
|
+
values: Float32Array;
|
|
66
|
+
} | null;
|
|
67
|
+
readonly groupNames: readonly string[];
|
|
68
|
+
}
|
|
69
|
+
/** Read a mesh datablock into plain arrays. */
|
|
70
|
+
export declare function readBlendMesh(blend: BlendData, mesh: BlendStruct): BlendMeshData;
|