@threepipe/plugin-blend-importer 0.0.4 → 0.0.6
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/dist/BlendLoadPlugin.d.ts +1 -1
- package/dist/BlendLoadPlugin.d.ts.map +1 -1
- package/dist/dependencies.txt +32 -1
- package/dist/index.js +2179 -82
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2179 -81
- package/dist/index.mjs.map +1 -1
- package/dist/loader/bakeGetters.d.ts +2 -0
- package/dist/loader/bakeGetters.d.ts.map +1 -0
- package/dist/loader/camera.d.ts +4 -0
- package/dist/loader/camera.d.ts.map +1 -0
- package/dist/loader/ctx.d.ts +16 -0
- package/dist/loader/ctx.d.ts.map +1 -0
- package/dist/loader/geometry.d.ts +3 -2
- package/dist/loader/geometry.d.ts.map +1 -1
- package/dist/loader/index.d.ts +2 -1
- package/dist/loader/index.d.ts.map +1 -1
- package/dist/loader/light.d.ts +3 -2
- package/dist/loader/light.d.ts.map +1 -1
- package/dist/loader/material.d.ts +2 -2
- package/dist/loader/material.d.ts.map +1 -1
- package/dist/loader/mesh.d.ts +2 -2
- package/dist/loader/mesh.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/BlendLoadPlugin.ts +42 -3
- package/src/js-blend/main.js +3 -2
- package/src/js-blend/parser/parser.js +152 -24
- package/src/js-blend/threejs/blend_three.js +1 -1
- package/src/js-blend/threejs/light.js +1 -1
- package/src/js-blend/threejs/material.js +1 -1
- package/src/loader/bakeGetters.ts +63 -0
- package/src/loader/camera.ts +55 -0
- package/src/loader/ctx.ts +29 -0
- package/src/loader/geometry.ts +236 -13
- package/src/loader/index.ts +95 -6
- package/src/loader/light.ts +18 -13
- package/src/loader/material.ts +7 -5
- package/src/loader/mesh.ts +14 -13
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bakeGetters.d.ts","sourceRoot":"","sources":["../../src/loader/bakeGetters.ts"],"names":[],"mappings":"AAAA,wBAAgB,WAAW,CACvB,GAAG,EAAE,GAAG,GACT,MAAM,CAiDR"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"camera.d.ts","sourceRoot":"","sources":["../../src/loader/camera.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,WAAW,CAAA;AAClC,OAAO,EAAC,GAAG,EAAC,MAAM,OAAO,CAAA;AAEzB,wBAAgB,YAAY,CAAC,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,GAAG,QAAQ,GAAG,SAAS,CAmDxE"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { AmbientLight, BufferAttribute, BufferGeometry, DirectionalLight, Mesh, MeshBasicMaterial, MeshPhysicalMaterial, Object3D, OrthographicCamera, PerspectiveCamera, PointLight, SpotLight } from 'threepipe';
|
|
2
|
+
export interface Ctx {
|
|
3
|
+
PointLight: typeof PointLight;
|
|
4
|
+
SpotLight: typeof SpotLight;
|
|
5
|
+
DirectionalLight: typeof DirectionalLight;
|
|
6
|
+
AmbientLight: typeof AmbientLight;
|
|
7
|
+
Object3D: typeof Object3D;
|
|
8
|
+
PerspectiveCamera: typeof PerspectiveCamera;
|
|
9
|
+
OrthographicCamera: typeof OrthographicCamera;
|
|
10
|
+
Mesh: typeof Mesh;
|
|
11
|
+
BufferGeometry: typeof BufferGeometry;
|
|
12
|
+
BufferAttribute: typeof BufferAttribute;
|
|
13
|
+
MeshPhysicalMaterial: typeof MeshPhysicalMaterial;
|
|
14
|
+
MeshBasicMaterial: typeof MeshBasicMaterial;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=ctx.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ctx.d.ts","sourceRoot":"","sources":["../../src/loader/ctx.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,YAAY,EACZ,eAAe,EACf,cAAc,EACd,gBAAgB,EAChB,IAAI,EACJ,iBAAiB,EACjB,oBAAoB,EACpB,QAAQ,EACR,kBAAkB,EAClB,iBAAiB,EACjB,UAAU,EACV,SAAS,EACZ,MAAM,WAAW,CAAA;AAElB,MAAM,WAAW,GAAG;IAChB,UAAU,EAAE,OAAO,UAAU,CAAA;IAC7B,SAAS,EAAE,OAAO,SAAS,CAAA;IAC3B,gBAAgB,EAAE,OAAO,gBAAgB,CAAA;IACzC,YAAY,EAAE,OAAO,YAAY,CAAA;IACjC,QAAQ,EAAE,OAAO,QAAQ,CAAA;IACzB,iBAAiB,EAAE,OAAO,iBAAiB,CAAA;IAC3C,kBAAkB,EAAE,OAAO,kBAAkB,CAAA;IAC7C,IAAI,EAAE,OAAO,IAAI,CAAA;IACjB,cAAc,EAAE,OAAO,cAAc,CAAA;IACrC,eAAe,EAAE,OAAO,eAAe,CAAA;IACvC,oBAAoB,EAAE,OAAO,oBAAoB,CAAA;IACjD,iBAAiB,EAAE,OAAO,iBAAiB,CAAA;CAC9C"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export declare function createBufferGeometry(
|
|
1
|
+
import { Ctx } from './ctx';
|
|
2
|
+
export declare function createBufferGeometry(meshData: any, ctx: Ctx): import('three').BufferGeometry<import('three').NormalBufferAttributes, import('three').BufferGeometryEventMap>;
|
|
3
|
+
export declare function createBufferGeometryOld(mesh: any, ctx: Ctx): import('three').BufferGeometry<import('three').NormalBufferAttributes, import('three').BufferGeometryEventMap>;
|
|
3
4
|
//# sourceMappingURL=geometry.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"geometry.d.ts","sourceRoot":"","sources":["../../src/loader/geometry.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"geometry.d.ts","sourceRoot":"","sources":["../../src/loader/geometry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,GAAG,EAAC,MAAM,OAAO,CAAA;AAezB,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,kHAgM3D;AASD,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,kHA0E1D"}
|
package/dist/loader/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
import { Object3D } from 'threepipe';
|
|
2
|
-
|
|
2
|
+
import { Ctx } from './ctx';
|
|
3
|
+
export declare function createObjects(file: any, ctx: Ctx): Promise<Object3D<import('threepipe').Object3DEventMap>[]>;
|
|
3
4
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/loader/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/loader/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAY,QAAQ,EAAC,MAAM,WAAW,CAAA;AAC7C,OAAO,EAAC,GAAG,EAAC,MAAM,OAAO,CAAA;AAYzB,wBAAsB,aAAa,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,6DAgEtD"}
|
package/dist/loader/light.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { Light } from 'threepipe';
|
|
2
|
+
import { Ctx } from './ctx';
|
|
3
|
+
export declare function createLight(lamp: any, ctx: Ctx): Light<import('three').LightShadow<import('threepipe').Camera<import('threepipe').Object3DEventMap>> | undefined, import('threepipe').Object3DEventMap> | undefined;
|
|
3
4
|
//# sourceMappingURL=light.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"light.d.ts","sourceRoot":"","sources":["../../src/loader/light.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,
|
|
1
|
+
{"version":3,"file":"light.d.ts","sourceRoot":"","sources":["../../src/loader/light.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,KAAK,EAAC,MAAM,WAAW,CAAA;AAC/B,OAAO,EAAC,GAAG,EAAC,MAAM,OAAO,CAAA;AAUzB,wBAAgB,WAAW,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,sKAmC9C"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export declare function createMaterial(mat: any): MeshPhysicalMaterial<import('three').MaterialEventMap>;
|
|
1
|
+
import { Ctx } from './ctx';
|
|
2
|
+
export declare function createMaterial(mat: any, ctx: Ctx): import('three').MeshPhysicalMaterial<import('three').MaterialEventMap>;
|
|
3
3
|
//# sourceMappingURL=material.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"material.d.ts","sourceRoot":"","sources":["../../src/loader/material.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"material.d.ts","sourceRoot":"","sources":["../../src/loader/material.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,GAAG,EAAC,MAAM,OAAO,CAAA;AAEzB,wBAAgB,cAAc,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,0EAShD"}
|
package/dist/loader/mesh.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export declare function createMesh(object: any
|
|
1
|
+
import { Ctx } from './ctx';
|
|
2
|
+
export declare function createMesh(object: any, loaded: WeakMap<any, any>, ctx: Ctx): import('three').Mesh<any, any, import('three').Object3DEventMap> | undefined;
|
|
3
3
|
//# sourceMappingURL=mesh.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mesh.d.ts","sourceRoot":"","sources":["../../src/loader/mesh.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"mesh.d.ts","sourceRoot":"","sources":["../../src/loader/mesh.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,GAAG,EAAC,MAAM,OAAO,CAAA;AAEzB,wBAAgB,UAAU,CAAC,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,GAAG,EAAE,GAAG,gFAsB1E"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@threepipe/plugin-blend-importer",
|
|
3
3
|
"description": "Basic importer for .blend file",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.6",
|
|
5
5
|
"dependencies": {},
|
|
6
6
|
"exports": {
|
|
7
7
|
".": {
|
|
@@ -42,6 +42,6 @@
|
|
|
42
42
|
"directory": "plugins/blend-importer"
|
|
43
43
|
},
|
|
44
44
|
"peerDependencies": {
|
|
45
|
-
"threepipe": "^0.0.
|
|
45
|
+
"threepipe": "^0.0.54"
|
|
46
46
|
}
|
|
47
47
|
}
|
package/src/BlendLoadPlugin.ts
CHANGED
|
@@ -1,4 +1,23 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
AmbientLight2,
|
|
3
|
+
AnyOptions,
|
|
4
|
+
BaseImporterPlugin,
|
|
5
|
+
BufferAttribute,
|
|
6
|
+
BufferGeometry2,
|
|
7
|
+
DirectionalLight2,
|
|
8
|
+
FileLoader,
|
|
9
|
+
ILoader,
|
|
10
|
+
Importer, Mesh,
|
|
11
|
+
Mesh2,
|
|
12
|
+
Object3D,
|
|
13
|
+
Object3D2,
|
|
14
|
+
OrthographicCamera0,
|
|
15
|
+
PerspectiveCamera0,
|
|
16
|
+
PhysicalMaterial,
|
|
17
|
+
PointLight2,
|
|
18
|
+
Scene, SpotLight2,
|
|
19
|
+
UnlitMaterial,
|
|
20
|
+
} from 'threepipe'
|
|
2
21
|
import {parseBlend} from './js-blend/main.js'
|
|
3
22
|
import {createObjects} from './loader'
|
|
4
23
|
|
|
@@ -15,18 +34,38 @@ export class BlendLoadPlugin extends BaseImporterPlugin {
|
|
|
15
34
|
this.setResponseType('arraybuffer')
|
|
16
35
|
const res = (await super.loadAsync(url, onProgress)) as ArrayBuffer
|
|
17
36
|
const blend = await parseBlend(res)
|
|
18
|
-
|
|
37
|
+
// console.log(bakeGetters(blend))
|
|
38
|
+
const ctx = {
|
|
39
|
+
Object3D: Object3D2,
|
|
40
|
+
Mesh: Mesh2 as typeof Mesh,
|
|
41
|
+
MeshPhysicalMaterial: PhysicalMaterial,
|
|
42
|
+
MeshBasicMaterial: UnlitMaterial,
|
|
43
|
+
PerspectiveCamera: PerspectiveCamera0,
|
|
44
|
+
OrthographicCamera: OrthographicCamera0,
|
|
45
|
+
PointLight: PointLight2,
|
|
46
|
+
DirectionalLight: DirectionalLight2,
|
|
47
|
+
SpotLight: SpotLight2,
|
|
48
|
+
AmbientLight: AmbientLight2,
|
|
49
|
+
BufferGeometry: BufferGeometry2,
|
|
50
|
+
BufferAttribute: BufferAttribute,
|
|
51
|
+
}
|
|
52
|
+
const objects = await createObjects(blend, ctx)
|
|
19
53
|
const root = new Object3D()
|
|
20
54
|
root.add(...objects)
|
|
55
|
+
root.userData.autoScaled = true
|
|
56
|
+
root.userData.autoCentered = true
|
|
21
57
|
// console.log(res, blend, root)
|
|
22
58
|
blend.scene = root
|
|
23
59
|
return blend
|
|
24
60
|
}
|
|
25
61
|
|
|
26
|
-
transform(res: any,
|
|
62
|
+
transform(res: any, options: AnyOptions): Scene {
|
|
27
63
|
// console.log(res)
|
|
28
64
|
// res.scene.userData.kinematics = res.kinematics
|
|
29
65
|
// res.scene.userData.library = res.library
|
|
66
|
+
if (typeof options.onBlendLoad === 'function') {
|
|
67
|
+
options.onBlendLoad(res)
|
|
68
|
+
}
|
|
30
69
|
return res.scene
|
|
31
70
|
}
|
|
32
71
|
}, ['blend'], ['application/x-blender'], true)
|
package/src/js-blend/main.js
CHANGED
|
@@ -13,8 +13,9 @@ import parser from './parser/parser.js';
|
|
|
13
13
|
export async function parseBlend (buffer, name = '') {
|
|
14
14
|
return new Promise((res, rej) => {
|
|
15
15
|
parser.onParseReady = (file, error) => {
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
// todo throw error if no objects?
|
|
17
|
+
if (error) console.error(error)
|
|
18
|
+
res(file)
|
|
18
19
|
}
|
|
19
20
|
parser.loadBlendFromArrayBuffer(buffer, name)
|
|
20
21
|
})
|
|
@@ -88,7 +88,7 @@ function worker_code () {
|
|
|
88
88
|
Export object for a parsed __blender_file__.
|
|
89
89
|
*/
|
|
90
90
|
|
|
91
|
-
|
|
91
|
+
const BLENDER_FILE = function (AB) {
|
|
92
92
|
this.AB = AB;
|
|
93
93
|
// this.double = new Float64Array(AB);
|
|
94
94
|
this.byte = new Uint8Array(AB);
|
|
@@ -144,6 +144,8 @@ function worker_code () {
|
|
|
144
144
|
this.__blender_file__.dv.setFloat64(this.__data_address__ + offset, float, this.__blender_file__.template.endianess);
|
|
145
145
|
}
|
|
146
146
|
},
|
|
147
|
+
enumerable: true,
|
|
148
|
+
configurable: true,
|
|
147
149
|
};
|
|
148
150
|
}
|
|
149
151
|
|
|
@@ -159,6 +161,8 @@ function worker_code () {
|
|
|
159
161
|
this.__blender_file__.dv.setFloat32(this.__data_address__ + offset, float, this.__blender_file__.template.endianess);
|
|
160
162
|
}
|
|
161
163
|
},
|
|
164
|
+
enumerable: true,
|
|
165
|
+
configurable: true,
|
|
162
166
|
};
|
|
163
167
|
}
|
|
164
168
|
|
|
@@ -174,6 +178,8 @@ function worker_code () {
|
|
|
174
178
|
this.__blender_file__.dv.setInt32(this.__data_address__ + offset, float, this.__blender_file__.template.endianess);
|
|
175
179
|
}
|
|
176
180
|
},
|
|
181
|
+
enumerable: true,
|
|
182
|
+
configurable: true,
|
|
177
183
|
};
|
|
178
184
|
}
|
|
179
185
|
|
|
@@ -189,6 +195,8 @@ function worker_code () {
|
|
|
189
195
|
this.__blender_file__.dv.setUint32(this.__data_address__ + offset, float, this.__blender_file__.template.endianess);
|
|
190
196
|
}
|
|
191
197
|
},
|
|
198
|
+
enumerable: true,
|
|
199
|
+
configurable: true,
|
|
192
200
|
};
|
|
193
201
|
}
|
|
194
202
|
|
|
@@ -204,6 +212,8 @@ function worker_code () {
|
|
|
204
212
|
this.__blender_file__.dv.setInt16(this.__data_address__ + offset, float, this.__blender_file__.template.endianess);
|
|
205
213
|
}
|
|
206
214
|
},
|
|
215
|
+
enumerable: true,
|
|
216
|
+
configurable: true,
|
|
207
217
|
};
|
|
208
218
|
}
|
|
209
219
|
|
|
@@ -220,6 +230,8 @@ function worker_code () {
|
|
|
220
230
|
this.__blender_file__.dv.setUint16(this.__data_address__ + offset, float, this.__blender_file__.template.endianess);
|
|
221
231
|
}
|
|
222
232
|
},
|
|
233
|
+
enumerable: true,
|
|
234
|
+
configurable: true,
|
|
223
235
|
};
|
|
224
236
|
};
|
|
225
237
|
|
|
@@ -254,6 +266,8 @@ function worker_code () {
|
|
|
254
266
|
this.__blender_file__.byte[(this.__data_address__ + offset)] = byte | 0;
|
|
255
267
|
}
|
|
256
268
|
},
|
|
269
|
+
enumerable: true,
|
|
270
|
+
configurable: true,
|
|
257
271
|
};
|
|
258
272
|
}
|
|
259
273
|
|
|
@@ -281,6 +295,8 @@ function worker_code () {
|
|
|
281
295
|
return results;
|
|
282
296
|
},
|
|
283
297
|
set: function () {},
|
|
298
|
+
enumerable: true,
|
|
299
|
+
configurable: true,
|
|
284
300
|
};
|
|
285
301
|
}
|
|
286
302
|
|
|
@@ -306,6 +322,8 @@ function worker_code () {
|
|
|
306
322
|
}
|
|
307
323
|
},
|
|
308
324
|
set: function () {},
|
|
325
|
+
enumerable: true,
|
|
326
|
+
configurable: true,
|
|
309
327
|
};
|
|
310
328
|
}
|
|
311
329
|
|
|
@@ -323,9 +341,11 @@ function worker_code () {
|
|
|
323
341
|
Object.defineProperty(obj, name, intProp(offset, array_size, length >> 2));
|
|
324
342
|
break;
|
|
325
343
|
case 'short':
|
|
326
|
-
case 'ushort':
|
|
327
344
|
Object.defineProperty(obj, name, shortProp(offset, array_size, length >> 1));
|
|
328
345
|
break;
|
|
346
|
+
case 'ushort':
|
|
347
|
+
Object.defineProperty(obj, name, uShortProp(offset, array_size, length >> 1));
|
|
348
|
+
break;
|
|
329
349
|
case 'char':
|
|
330
350
|
case 'uchar':
|
|
331
351
|
Object.defineProperty(obj, name, charProp(offset, array_size, length));
|
|
@@ -339,6 +359,7 @@ function worker_code () {
|
|
|
339
359
|
offset += length;
|
|
340
360
|
} else {
|
|
341
361
|
Object.defineProperty(obj, name, pointerProp(offset, array_size, pointer_size));
|
|
362
|
+
obj._length += pointer_size * array_size;
|
|
342
363
|
offset += pointer_size * array_size;
|
|
343
364
|
}
|
|
344
365
|
|
|
@@ -359,13 +380,19 @@ function worker_code () {
|
|
|
359
380
|
MASTER_SDNA_SCHEMA.prototype = {
|
|
360
381
|
getSDNAStructureConstructor: function (name, struct) {
|
|
361
382
|
if (struct) {
|
|
362
|
-
const
|
|
383
|
+
const jsName = name === 'void' ? 'void_' : name
|
|
384
|
+
const blen_struct = Function('function ' + jsName + '(){}; return ' + jsName)();
|
|
385
|
+
|
|
386
|
+
// if(name === 'CustomDataLayer') debugger
|
|
363
387
|
|
|
364
388
|
blen_struct.prototype = new BLENDER_STRUCTURE();
|
|
365
389
|
blen_struct.prototype.blender_name = name;
|
|
366
390
|
blen_struct.prototype.__pointers = [];
|
|
367
391
|
blen_struct.prototype.__list__ = [];
|
|
368
392
|
|
|
393
|
+
const DNA = this.SDNA[name] = {
|
|
394
|
+
constructor: blen_struct,
|
|
395
|
+
};
|
|
369
396
|
let offset = 0;
|
|
370
397
|
// Create properties of struct
|
|
371
398
|
for (let i = 0; i < struct.length; i += 3) {
|
|
@@ -379,9 +406,6 @@ function worker_code () {
|
|
|
379
406
|
Suparray_match = 1,
|
|
380
407
|
PointerToArray = false,
|
|
381
408
|
Pointer_Match = 0;
|
|
382
|
-
const DNA = this.SDNA[name] = {
|
|
383
|
-
constructor: blen_struct,
|
|
384
|
-
};
|
|
385
409
|
|
|
386
410
|
|
|
387
411
|
let original_name = _name;
|
|
@@ -445,6 +469,8 @@ function worker_code () {
|
|
|
445
469
|
return array;
|
|
446
470
|
};
|
|
447
471
|
})(array_names),
|
|
472
|
+
enumerable: true,
|
|
473
|
+
configurable: true,
|
|
448
474
|
});
|
|
449
475
|
} else {
|
|
450
476
|
offset = compileProp(blen_struct.prototype, _name, type, offset, Blender_Array_Length, Pointer_Match, pointer_size, length);
|
|
@@ -462,7 +488,7 @@ function worker_code () {
|
|
|
462
488
|
},
|
|
463
489
|
};
|
|
464
490
|
|
|
465
|
-
|
|
491
|
+
const BLENDER_STRUCTURE = function () {
|
|
466
492
|
this.__blender_file__ = null;
|
|
467
493
|
this.__list__ = null;
|
|
468
494
|
this.__super_array_list__ = null;
|
|
@@ -513,6 +539,8 @@ function worker_code () {
|
|
|
513
539
|
|
|
514
540
|
this.__data_address__ = _data_offset;
|
|
515
541
|
|
|
542
|
+
// if(this.blender_name === 'CustomDataLayer') debugger
|
|
543
|
+
|
|
516
544
|
if (struct === null) return this;
|
|
517
545
|
|
|
518
546
|
for (i = 0; i < struct.length; i += 6) {
|
|
@@ -574,9 +602,11 @@ function worker_code () {
|
|
|
574
602
|
struct_names = [];
|
|
575
603
|
offset = 0;
|
|
576
604
|
|
|
605
|
+
// todo gzip, zstd(28 b5 2f fd, https://projects.blender.org/archive/blender-file/issues/93858)
|
|
577
606
|
// Make sure we have a .blend __blender_file__. All blend files have the first 12bytes
|
|
578
607
|
// set with BLENDER-v### in Utf-8
|
|
579
|
-
|
|
608
|
+
const magic = toString(_data, offset, 7)
|
|
609
|
+
if (magic !== 'BLENDER') return ERROR = 'File supplied is not a .blend compatible Blender file.';
|
|
580
610
|
|
|
581
611
|
// otherwise get templete from save version.
|
|
582
612
|
|
|
@@ -644,13 +674,23 @@ function worker_code () {
|
|
|
644
674
|
curr_count++;
|
|
645
675
|
}
|
|
646
676
|
|
|
647
|
-
|
|
648
|
-
// Adjust for 4byte alignment
|
|
649
|
-
if ((
|
|
677
|
+
// todo fix seek logic
|
|
678
|
+
// Adjust for 4byte alignment TYPE
|
|
679
|
+
if (toString(_data, offset2, offset2 + 4) !== 'TYPE'
|
|
680
|
+
) {
|
|
681
|
+
for (let j = 0; j < 8; j++) {
|
|
682
|
+
if(toString(_data, offset2, offset2 + 4) === 'TYPE') break
|
|
683
|
+
offset2++;
|
|
684
|
+
}
|
|
685
|
+
// offset2 = (4 - (offset2 % 4)) + offset2;
|
|
686
|
+
}
|
|
687
|
+
if(toString(_data, offset2, offset2 + 4) !== 'TYPE') {
|
|
688
|
+
debugger
|
|
689
|
+
}
|
|
650
690
|
offset2 += 4;
|
|
651
691
|
|
|
652
692
|
// Number of struct types
|
|
653
|
-
count = data.
|
|
693
|
+
count = data.getUint32(offset2, true);
|
|
654
694
|
offset2 += 4;
|
|
655
695
|
curr_count = 0;
|
|
656
696
|
|
|
@@ -666,8 +706,19 @@ function worker_code () {
|
|
|
666
706
|
curr_count++;
|
|
667
707
|
}
|
|
668
708
|
|
|
709
|
+
// todo fix seek logic
|
|
669
710
|
// Adjust for 4byte alignment
|
|
670
|
-
if ((
|
|
711
|
+
if (toString(_data, offset2, offset2 + 4) !== 'TLEN'
|
|
712
|
+
) {
|
|
713
|
+
for (let j = 0; j < 8; j++) {
|
|
714
|
+
if(toString(_data, offset2, offset2 + 4) === 'TLEN') break
|
|
715
|
+
offset2++;
|
|
716
|
+
}
|
|
717
|
+
// offset2 = (4 - (offset2 % 4)) + offset2;
|
|
718
|
+
}
|
|
719
|
+
if(toString(_data, offset2, offset2 + 4) !== 'TLEN') {
|
|
720
|
+
debugger
|
|
721
|
+
}
|
|
671
722
|
offset2 += 4;
|
|
672
723
|
curr_count = 0;
|
|
673
724
|
|
|
@@ -678,8 +729,19 @@ function worker_code () {
|
|
|
678
729
|
curr_count++;
|
|
679
730
|
}
|
|
680
731
|
|
|
681
|
-
//
|
|
682
|
-
|
|
732
|
+
// todo fix seek logic
|
|
733
|
+
// Adjust for 4byte alignment STRC
|
|
734
|
+
if (toString(_data, offset2, offset2 + 4) !== 'STRC'
|
|
735
|
+
) {
|
|
736
|
+
for (let j = 0; j < 8; j++) {
|
|
737
|
+
if(toString(_data, offset2, offset2 + 4) === 'STRC') break
|
|
738
|
+
offset2++;
|
|
739
|
+
}
|
|
740
|
+
// offset2 = (4 - (offset2 % 4)) + offset2;
|
|
741
|
+
}
|
|
742
|
+
if(toString(_data, offset2, offset2 + 4) !== 'STRC') {
|
|
743
|
+
debugger
|
|
744
|
+
}
|
|
683
745
|
offset2 += 4;
|
|
684
746
|
|
|
685
747
|
// Number of structures
|
|
@@ -699,6 +761,11 @@ function worker_code () {
|
|
|
699
761
|
|
|
700
762
|
// Fill an array with name, type, and length for each SDNA struct property
|
|
701
763
|
while (curr_count2 < count) {
|
|
764
|
+
|
|
765
|
+
// const n = names[data.getInt16(offset2 + 2, BIG_ENDIAN)]
|
|
766
|
+
// if(obj.find((o, i)=>i%3===0 && o===n)){
|
|
767
|
+
// debugger
|
|
768
|
+
// }
|
|
702
769
|
obj.push(names[data.getInt16(offset2 + 2, BIG_ENDIAN)], types[data.getInt16(offset2, BIG_ENDIAN)], lengths[data.getInt16(offset2, BIG_ENDIAN)]);
|
|
703
770
|
offset2 += 4;
|
|
704
771
|
curr_count2++;
|
|
@@ -720,19 +787,74 @@ function worker_code () {
|
|
|
720
787
|
|
|
721
788
|
// TODO: turn into "on-demand" parsing.
|
|
722
789
|
|
|
790
|
+
// https://github.com/fschutt/mystery-of-the-blend-backup
|
|
723
791
|
while (true) {
|
|
724
|
-
|
|
725
|
-
|
|
792
|
+
// todo fix cleanup
|
|
793
|
+
// this is not the case, see blend-load-test.blend and Ruins_Assets.blend
|
|
794
|
+
// if ((offset % 4) > 0) {
|
|
795
|
+
// console.log('fix', offset, offset % 4)
|
|
796
|
+
// debugger
|
|
797
|
+
// offset = (4 - (offset % 4)) + offset;
|
|
798
|
+
// }
|
|
799
|
+
for (let j = 0; j < 8; j++) {
|
|
800
|
+
if(data.getInt8(offset) === 0) {
|
|
801
|
+
offset++
|
|
802
|
+
continue
|
|
803
|
+
}
|
|
804
|
+
break
|
|
805
|
+
}
|
|
806
|
+
if(data.getInt8(offset) === 0) {
|
|
807
|
+
debugger
|
|
726
808
|
}
|
|
727
809
|
|
|
728
810
|
data_offset = offset;
|
|
811
|
+
|
|
812
|
+
if (offset + pointer_size + 12 >= data.byteLength) {
|
|
813
|
+
ERROR = 'Unexpected end of file while parsing';
|
|
814
|
+
break
|
|
815
|
+
}
|
|
816
|
+
|
|
729
817
|
sdna_index = data.getInt32(offset + pointer_size + 8, BIG_ENDIAN);
|
|
730
|
-
let code_uint = data.getUint32(offset, BIG_ENDIAN);
|
|
818
|
+
// let code_uint = data.getUint32(offset, BIG_ENDIAN);
|
|
819
|
+
const code_str = toString(_data, offset, offset + 4) // data.getUint32(offset, BIG_ENDIAN);
|
|
820
|
+
|
|
731
821
|
offset2 = offset + 16 + (pointer_size);
|
|
732
|
-
|
|
822
|
+
// console.log(code_str, code_str.length, data.getInt8(offset))
|
|
733
823
|
|
|
734
|
-
|
|
735
|
-
|
|
824
|
+
const blockLength = data.getInt32(offset + 4, true);
|
|
825
|
+
if (blockLength < 0 || offset + blockLength + 16 + pointer_size > data.byteLength) {
|
|
826
|
+
ERROR = 'Invalid block length detected';
|
|
827
|
+
break
|
|
828
|
+
}
|
|
829
|
+
// if(blockLength === 1) {
|
|
830
|
+
// debugger
|
|
831
|
+
// }
|
|
832
|
+
|
|
833
|
+
// last_offset = offset
|
|
834
|
+
|
|
835
|
+
offset += blockLength + 16 + (pointer_size);
|
|
836
|
+
|
|
837
|
+
if (code_str === 'DNA1') {} // skip - already processed at this point
|
|
838
|
+
else if (code_str === 'ENDB') break; // end of __blender_file__ found
|
|
839
|
+
else if (code_str === 'TEST') { // snapshot
|
|
840
|
+
const data_start = data_offset + pointer_size + 16;
|
|
841
|
+
const width = data.getInt32(data_start, BIG_ENDIAN);
|
|
842
|
+
const height = data.getInt32(data_start + 4, BIG_ENDIAN);
|
|
843
|
+
if ((width * height > 0)) {
|
|
844
|
+
const data_len = width * height * 4; // RGBA
|
|
845
|
+
if(blockLength < data_len + 8) {
|
|
846
|
+
ERROR = 'Invalid TEST block length detected';
|
|
847
|
+
break;
|
|
848
|
+
}
|
|
849
|
+
const image_data = new Uint32Array(_data, data_start + 8, data_len >> 2);
|
|
850
|
+
const image = {
|
|
851
|
+
width: width,
|
|
852
|
+
height: height,
|
|
853
|
+
data: image_data,
|
|
854
|
+
};
|
|
855
|
+
FILE.thumbnail = image
|
|
856
|
+
}
|
|
857
|
+
}
|
|
736
858
|
else {
|
|
737
859
|
// Create a Blender object using a constructor template from current_SDNA_template
|
|
738
860
|
const data_start = data_offset + pointer_size + 16;
|
|
@@ -744,7 +866,7 @@ function worker_code () {
|
|
|
744
866
|
|
|
745
867
|
count = data.getInt32(data_offset + 12 + pointer_size, BIG_ENDIAN);
|
|
746
868
|
|
|
747
|
-
if (count > 0) {
|
|
869
|
+
if (count > 0 && constructor) {
|
|
748
870
|
let obj = new constructor();
|
|
749
871
|
|
|
750
872
|
const length = constructor.prototype._length;
|
|
@@ -776,8 +898,14 @@ function worker_code () {
|
|
|
776
898
|
|
|
777
899
|
worker = new worker_code();
|
|
778
900
|
|
|
779
|
-
worker.postMessage = function (message) {
|
|
780
|
-
return_object.onParseReady(message);
|
|
901
|
+
worker.postMessage = function (message, err) {
|
|
902
|
+
return_object.onParseReady(message, err);
|
|
781
903
|
};
|
|
782
904
|
|
|
783
905
|
export default return_object;
|
|
906
|
+
|
|
907
|
+
// window.prettyPrintHex = function (view, offset = 0, length = view.byteLength - offset) {
|
|
908
|
+
// const bytes = Array.from({ length }, (_, i) => view.getUint8(offset + i));
|
|
909
|
+
// console.log(bytes.map((b, i) => (i % 16 === 0 ? '\n' : '') + b.toString(16).padStart(2, '0')).join(' '));
|
|
910
|
+
// console.log(bytes.map((b, i) => (i % 16 === 0 ? '\n' : '') + String.fromCharCode(b)).join(''));
|
|
911
|
+
// }
|
|
@@ -15,7 +15,7 @@ function createObject (blender_file, object) {
|
|
|
15
15
|
// get the mesh
|
|
16
16
|
const buffered_geometry = createThreeJSBufferGeometry(object.data, [0, 0, 0]);
|
|
17
17
|
|
|
18
|
-
console.log(object)
|
|
18
|
+
// console.log(object)
|
|
19
19
|
const blend_material = object.data.mat[0];
|
|
20
20
|
|
|
21
21
|
const material = blend_material ? createThreeJSMaterial(blend_material) : null;
|
|
@@ -118,7 +118,7 @@ function applyTexture (blender_texture, material) {
|
|
|
118
118
|
|
|
119
119
|
export function createThreeJSMaterial (blend_mat) {
|
|
120
120
|
|
|
121
|
-
console.log(blend_mat)
|
|
121
|
+
// console.log(blend_mat)
|
|
122
122
|
|
|
123
123
|
let material = new MeshPhysicalMaterial();
|
|
124
124
|
material.color.setRGB(blend_mat.r, blend_mat.g, blend_mat.b);
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
export function bakeGetters(
|
|
2
|
+
obj: any,
|
|
3
|
+
): string {
|
|
4
|
+
const ss = new Set<any>()
|
|
5
|
+
|
|
6
|
+
// Create a plain object that includes getter values
|
|
7
|
+
function toPlainObject(source: any, level = 0): any {
|
|
8
|
+
if (!source || typeof source !== 'object') {
|
|
9
|
+
return source
|
|
10
|
+
}
|
|
11
|
+
if (ss.has(source)) {
|
|
12
|
+
// console.warn('duplicate', source, level)
|
|
13
|
+
// debugger
|
|
14
|
+
return 'duplicate'
|
|
15
|
+
}
|
|
16
|
+
ss.add(source)
|
|
17
|
+
|
|
18
|
+
if (Array.isArray(source)) {
|
|
19
|
+
return source.map(toPlainObject)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const result: Record<string, any> = {}
|
|
23
|
+
|
|
24
|
+
const keys = getAllKeys(source) as string[]
|
|
25
|
+
// Get all enumerable properties (including getters)
|
|
26
|
+
for (const key of keys) {
|
|
27
|
+
// if (key.startsWith('__')) continue
|
|
28
|
+
if (key === '__blender_file__') continue
|
|
29
|
+
try {
|
|
30
|
+
const v = source[key]
|
|
31
|
+
if (v === source || v === undefined || v === null) continue
|
|
32
|
+
// result[key] = 'a'
|
|
33
|
+
|
|
34
|
+
// if (key === 'typemap') console.log(v)
|
|
35
|
+
// const v = source[key]
|
|
36
|
+
// if (v === source) continue
|
|
37
|
+
// console.log(key, v)
|
|
38
|
+
if (typeof v === 'object' && v?.buffer instanceof ArrayBuffer) {
|
|
39
|
+
result[key] = Object.getPrototypeOf(v).constructor.name
|
|
40
|
+
} else
|
|
41
|
+
result[key] = toPlainObject(v, level + 1)
|
|
42
|
+
} catch (e) {
|
|
43
|
+
// Skip properties that throw errors when accessed
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return result
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const plainObj = toPlainObject(obj)
|
|
51
|
+
return plainObj
|
|
52
|
+
}
|
|
53
|
+
function getAllKeys(obj: any) {
|
|
54
|
+
const keys = new Set()
|
|
55
|
+
let current = obj
|
|
56
|
+
|
|
57
|
+
while (current !== null) {
|
|
58
|
+
Object.getOwnPropertyNames(current).forEach(key => keys.add(key))
|
|
59
|
+
current = Object.getPrototypeOf(current)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return Array.from(keys)
|
|
63
|
+
}
|