@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.
Files changed (38) hide show
  1. package/dist/BlendLoadPlugin.d.ts +1 -1
  2. package/dist/BlendLoadPlugin.d.ts.map +1 -1
  3. package/dist/dependencies.txt +32 -1
  4. package/dist/index.js +2179 -82
  5. package/dist/index.js.map +1 -1
  6. package/dist/index.mjs +2179 -81
  7. package/dist/index.mjs.map +1 -1
  8. package/dist/loader/bakeGetters.d.ts +2 -0
  9. package/dist/loader/bakeGetters.d.ts.map +1 -0
  10. package/dist/loader/camera.d.ts +4 -0
  11. package/dist/loader/camera.d.ts.map +1 -0
  12. package/dist/loader/ctx.d.ts +16 -0
  13. package/dist/loader/ctx.d.ts.map +1 -0
  14. package/dist/loader/geometry.d.ts +3 -2
  15. package/dist/loader/geometry.d.ts.map +1 -1
  16. package/dist/loader/index.d.ts +2 -1
  17. package/dist/loader/index.d.ts.map +1 -1
  18. package/dist/loader/light.d.ts +3 -2
  19. package/dist/loader/light.d.ts.map +1 -1
  20. package/dist/loader/material.d.ts +2 -2
  21. package/dist/loader/material.d.ts.map +1 -1
  22. package/dist/loader/mesh.d.ts +2 -2
  23. package/dist/loader/mesh.d.ts.map +1 -1
  24. package/package.json +2 -2
  25. package/src/BlendLoadPlugin.ts +42 -3
  26. package/src/js-blend/main.js +3 -2
  27. package/src/js-blend/parser/parser.js +152 -24
  28. package/src/js-blend/threejs/blend_three.js +1 -1
  29. package/src/js-blend/threejs/light.js +1 -1
  30. package/src/js-blend/threejs/material.js +1 -1
  31. package/src/loader/bakeGetters.ts +63 -0
  32. package/src/loader/camera.ts +55 -0
  33. package/src/loader/ctx.ts +29 -0
  34. package/src/loader/geometry.ts +236 -13
  35. package/src/loader/index.ts +95 -6
  36. package/src/loader/light.ts +18 -13
  37. package/src/loader/material.ts +7 -5
  38. package/src/loader/mesh.ts +14 -13
@@ -0,0 +1,2 @@
1
+ export declare function bakeGetters(obj: any): string;
2
+ //# sourceMappingURL=bakeGetters.d.ts.map
@@ -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,4 @@
1
+ import { Object3D } from 'threepipe';
2
+ import { Ctx } from './ctx';
3
+ export declare function createCamera(object: any, ctx: Ctx): Object3D | undefined;
4
+ //# sourceMappingURL=camera.d.ts.map
@@ -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 { BufferGeometry, Vector3Tuple } from 'threepipe';
2
- export declare function createBufferGeometry(mesh: any, origin: Vector3Tuple): BufferGeometry<import('three').NormalBufferAttributes, import('three').BufferGeometryEventMap>;
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,EAAkB,cAAc,EAAE,YAAY,EAAC,MAAM,WAAW,CAAA;AAEvE,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,YAAY,kGAiEnE"}
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"}
@@ -1,3 +1,4 @@
1
1
  import { Object3D } from 'threepipe';
2
- export declare function createObjects(file: any): Promise<Object3D<import('three').Object3DEventMap>[]>;
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":"AAEA,OAAO,EAAC,QAAQ,EAAC,MAAM,WAAW,CAAA;AAOlC,wBAAsB,aAAa,CAAC,IAAI,EAAE,GAAG,yDAgB5C"}
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"}
@@ -1,3 +1,4 @@
1
- import { PointLight } from 'threepipe';
2
- export declare function createLight(lamp: any): PointLight | null;
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,UAAU,EAAC,MAAM,WAAW,CAAA;AAUpC,wBAAgB,WAAW,CAAC,IAAI,EAAE,GAAG,qBA+BpC"}
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 { MeshPhysicalMaterial } from 'threepipe';
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":"AAAA,OAAO,EAAC,oBAAoB,EAAC,MAAM,WAAW,CAAA;AAG9C,wBAAgB,cAAc,CAAC,GAAG,EAAE,GAAG,0DAQtC"}
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"}
@@ -1,3 +1,3 @@
1
- import { Mesh } from 'threepipe';
2
- export declare function createMesh(object: any): Mesh<import('threepipe').BufferGeometry<import('three').NormalBufferAttributes, import('three').BufferGeometryEventMap>, import('threepipe').MeshPhysicalMaterial<import('three').MaterialEventMap>, import('three').Object3DEventMap> | null;
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":"AAAA,OAAO,EAAC,IAAI,EAAC,MAAM,WAAW,CAAA;AAI9B,wBAAgB,UAAU,CAAC,MAAM,EAAE,GAAG,iPAqBrC"}
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",
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.13"
45
+ "threepipe": "^0.0.54"
46
46
  }
47
47
  }
@@ -1,4 +1,23 @@
1
- import {AnyOptions, BaseImporterPlugin, FileLoader, ILoader, Importer, Object3D, Scene} from 'threepipe'
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
- const objects = await createObjects(blend)
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, _: AnyOptions): Scene {
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)
@@ -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
- if (error) rej(error)
17
- else res(file)
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
- var BLENDER_FILE = function (AB) {
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 blen_struct = Function('function ' + name + '(){}; return ' + name)();
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
- var BLENDER_STRUCTURE = function () {
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
- if (toString(_data, offset, 7) !== 'BLENDER') return ERROR = 'File supplied is not a .blend compatible Blender file.';
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 ((offset2 % 4) > 0) offset2 = (4 - (offset2 % 4)) + offset2;
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.getInt32(offset2, true);
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 ((offset2 % 4) > 0) offset2 = (4 - (offset2 % 4)) + offset2;
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
- // Adjust for 4byte alignment
682
- if ((offset2 % 4) > 0) offset2 = (4 - (offset2 % 4)) + offset2;
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
- if ((offset % 4) > 0) {
725
- offset = (4 - (offset % 4)) + offset;
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
- offset += data.getInt32(offset + 4, true) + 16 + (pointer_size);
822
+ // console.log(code_str, code_str.length, data.getInt8(offset))
733
823
 
734
- if (code_uint === DNA1); // skip - already processed at this point
735
- else if (code_uint === ENDB) break; // end of __blender_file__ found
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;
@@ -11,7 +11,7 @@ const blender_light_types = {
11
11
 
12
12
  export function createThreeJSLamp (blend_lamp) {
13
13
 
14
- console.log(blend_lamp)
14
+ // console.log(blend_lamp)
15
15
 
16
16
  let ldata = blend_lamp.data;
17
17
 
@@ -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
+ }