@threepipe/plugin-blend-importer 0.0.5 → 0.0.7
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.map +1 -1
- package/dist/dependencies.txt +32 -1
- package/dist/index.js +1857 -70
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1856 -68
- package/dist/index.mjs.map +1 -1
- package/dist/loader/camera.d.ts +2 -1
- package/dist/loader/camera.d.ts.map +1 -1
- 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 +2 -1
- package/dist/loader/light.d.ts.map +1 -1
- package/dist/loader/material.d.ts +2 -1
- package/dist/loader/material.d.ts.map +1 -1
- package/dist/loader/mesh.d.ts +2 -3
- package/dist/loader/mesh.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/BlendLoadPlugin.ts +8 -3
- package/src/js-blend/parser/parser.js +31 -33
- package/src/loader/camera.ts +17 -8
- package/src/loader/ctx.ts +29 -0
- package/src/loader/geometry.ts +38 -29
- package/src/loader/index.ts +43 -6
- package/src/loader/light.ts +2 -1
- package/src/loader/material.ts +3 -1
- package/src/loader/mesh.ts +2 -14
package/dist/loader/camera.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
import { Object3D } from 'threepipe';
|
|
2
|
-
|
|
2
|
+
import { Ctx } from './ctx';
|
|
3
|
+
export declare function createCamera(object: any, ctx: Ctx): Object3D | undefined;
|
|
3
4
|
//# sourceMappingURL=camera.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"camera.d.ts","sourceRoot":"","sources":["../../src/loader/camera.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,WAAW,CAAA;
|
|
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
|
-
|
|
2
|
-
export declare function
|
|
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":"
|
|
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,kHAoM3D;AASD,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,kHA6E1D"}
|
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":"AAGA,OAAO,
|
|
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
1
|
import { Light } from 'threepipe';
|
|
2
|
-
|
|
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,KAAK,EAAC,MAAM,WAAW,CAAA;
|
|
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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"material.d.ts","sourceRoot":"","sources":["../../src/loader/material.ts"],"names":[],"mappings":"AAEA,wBAAgB,cAAc,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,
|
|
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,4 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export declare function
|
|
3
|
-
export declare function createMesh(object: any, loaded: WeakMap<any, any>, ctx: any): 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;
|
|
4
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
package/src/BlendLoadPlugin.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
+
AmbientLight2,
|
|
2
3
|
AnyOptions,
|
|
3
4
|
BaseImporterPlugin,
|
|
4
5
|
BufferAttribute,
|
|
@@ -6,7 +7,7 @@ import {
|
|
|
6
7
|
DirectionalLight2,
|
|
7
8
|
FileLoader,
|
|
8
9
|
ILoader,
|
|
9
|
-
Importer,
|
|
10
|
+
Importer, Mesh,
|
|
10
11
|
Mesh2,
|
|
11
12
|
Object3D,
|
|
12
13
|
Object3D2,
|
|
@@ -14,7 +15,7 @@ import {
|
|
|
14
15
|
PerspectiveCamera0,
|
|
15
16
|
PhysicalMaterial,
|
|
16
17
|
PointLight2,
|
|
17
|
-
Scene,
|
|
18
|
+
Scene, SpotLight2,
|
|
18
19
|
UnlitMaterial,
|
|
19
20
|
} from 'threepipe'
|
|
20
21
|
import {parseBlend} from './js-blend/main.js'
|
|
@@ -36,19 +37,23 @@ export class BlendLoadPlugin extends BaseImporterPlugin {
|
|
|
36
37
|
// console.log(bakeGetters(blend))
|
|
37
38
|
const ctx = {
|
|
38
39
|
Object3D: Object3D2,
|
|
39
|
-
Mesh: Mesh2,
|
|
40
|
+
Mesh: Mesh2 as typeof Mesh,
|
|
40
41
|
MeshPhysicalMaterial: PhysicalMaterial,
|
|
41
42
|
MeshBasicMaterial: UnlitMaterial,
|
|
42
43
|
PerspectiveCamera: PerspectiveCamera0,
|
|
43
44
|
OrthographicCamera: OrthographicCamera0,
|
|
44
45
|
PointLight: PointLight2,
|
|
45
46
|
DirectionalLight: DirectionalLight2,
|
|
47
|
+
SpotLight: SpotLight2,
|
|
48
|
+
AmbientLight: AmbientLight2,
|
|
46
49
|
BufferGeometry: BufferGeometry2,
|
|
47
50
|
BufferAttribute: BufferAttribute,
|
|
48
51
|
}
|
|
49
52
|
const objects = await createObjects(blend, ctx)
|
|
50
53
|
const root = new Object3D()
|
|
51
54
|
root.add(...objects)
|
|
55
|
+
// root.userData.autoScaled = true
|
|
56
|
+
// root.userData.autoCentered = true
|
|
52
57
|
// console.log(res, blend, root)
|
|
53
58
|
blend.scene = root
|
|
54
59
|
return blend
|
|
@@ -583,6 +583,15 @@ function worker_code () {
|
|
|
583
583
|
function toString (buffer, _in, _out) {
|
|
584
584
|
return String.fromCharCode.apply(String, new Uint8Array(buffer, _in, _out - _in));
|
|
585
585
|
}
|
|
586
|
+
function seekCheck (buffer, _in, str) {
|
|
587
|
+
const length = str.length;
|
|
588
|
+
for (let i = 0; i < length; i++) {
|
|
589
|
+
if (buffer.getUint8(_in + i) !== str.charCodeAt(i)) {
|
|
590
|
+
return false;
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
return true;
|
|
594
|
+
}
|
|
586
595
|
|
|
587
596
|
// Begin parsing blender __blender_file__
|
|
588
597
|
|
|
@@ -674,19 +683,16 @@ function worker_code () {
|
|
|
674
683
|
curr_count++;
|
|
675
684
|
}
|
|
676
685
|
|
|
677
|
-
//
|
|
678
|
-
|
|
679
|
-
|
|
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
|
+
// Adjust for alignment TYPE
|
|
687
|
+
for (let j = 0; j < 8; j++) {
|
|
688
|
+
if(seekCheck(data, offset2, 'TYPE')) break
|
|
689
|
+
offset2++;
|
|
686
690
|
}
|
|
687
|
-
if(
|
|
688
|
-
|
|
691
|
+
if(!seekCheck(data, offset2, 'TYPE')) {
|
|
692
|
+
ERROR = 'Unexpected alignment error in SDNA parsing';
|
|
693
|
+
break
|
|
689
694
|
}
|
|
695
|
+
|
|
690
696
|
offset2 += 4;
|
|
691
697
|
|
|
692
698
|
// Number of struct types
|
|
@@ -706,18 +712,14 @@ function worker_code () {
|
|
|
706
712
|
curr_count++;
|
|
707
713
|
}
|
|
708
714
|
|
|
709
|
-
//
|
|
710
|
-
|
|
711
|
-
|
|
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;
|
|
715
|
+
// Adjust for alignment
|
|
716
|
+
for (let j = 0; j < 8; j++) {
|
|
717
|
+
if(seekCheck(data, offset2, 'TLEN')) break
|
|
718
|
+
offset2++;
|
|
718
719
|
}
|
|
719
|
-
if(
|
|
720
|
-
|
|
720
|
+
if(!seekCheck(data, offset2, 'TLEN')) {
|
|
721
|
+
ERROR = 'Unexpected alignment error in SDNA parsing';
|
|
722
|
+
break
|
|
721
723
|
}
|
|
722
724
|
offset2 += 4;
|
|
723
725
|
curr_count = 0;
|
|
@@ -729,18 +731,14 @@ function worker_code () {
|
|
|
729
731
|
curr_count++;
|
|
730
732
|
}
|
|
731
733
|
|
|
732
|
-
//
|
|
733
|
-
|
|
734
|
-
|
|
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;
|
|
734
|
+
// Adjust for alignment
|
|
735
|
+
for (let j = 0; j < 8; j++) {
|
|
736
|
+
if(seekCheck(data, offset2, 'STRC')) break
|
|
737
|
+
offset2++;
|
|
741
738
|
}
|
|
742
|
-
if(
|
|
743
|
-
|
|
739
|
+
if(!seekCheck(data, offset2, 'STRC')) {
|
|
740
|
+
ERROR = 'Unexpected alignment error in SDNA parsing';
|
|
741
|
+
break
|
|
744
742
|
}
|
|
745
743
|
offset2 += 4;
|
|
746
744
|
|
package/src/loader/camera.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {Object3D} from 'threepipe'
|
|
2
|
+
import {Ctx} from './ctx'
|
|
2
3
|
|
|
3
|
-
export function createCamera(object: any, ctx:
|
|
4
|
+
export function createCamera(object: any, ctx: Ctx): Object3D | undefined {
|
|
4
5
|
const cdata = object.data
|
|
5
6
|
// console.log(bakeGetters(object))
|
|
6
7
|
if (!cdata) return undefined
|
|
@@ -10,14 +11,19 @@ export function createCamera(object: any, ctx: any): Object3D | undefined {
|
|
|
10
11
|
let camera: Object3D
|
|
11
12
|
if (type === 0) {
|
|
12
13
|
// Perspective
|
|
14
|
+
// Convert lens (mm) to field of view (fov) in degrees (vfov)
|
|
15
|
+
const sensorWidth = cdata.sensor_x || 36
|
|
16
|
+
const sensorHeight = cdata.sensor_y || 24
|
|
17
|
+
const lens = cdata.lens || 50
|
|
18
|
+
const fov = 2 * Math.atan(sensorHeight / (2 * lens)) * (180 / Math.PI)
|
|
19
|
+
|
|
13
20
|
camera = new ctx.PerspectiveCamera(
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
cdata.clipsta || 0.1,
|
|
17
|
-
cdata.clipend || 1000
|
|
21
|
+
fov,
|
|
22
|
+
sensorWidth / sensorHeight,
|
|
23
|
+
cdata.clipsta || 0.1,
|
|
24
|
+
cdata.clipend || 1000
|
|
18
25
|
)
|
|
19
|
-
|
|
20
|
-
camera.position.set(0, 0, 0)
|
|
26
|
+
if ('shiftx' in cdata) camera.userData.shiftX = cdata.shiftx // todo?
|
|
21
27
|
if ('shiftx' in cdata) camera.userData.shiftX = cdata.shiftx // todo?
|
|
22
28
|
if ('shifty' in cdata) camera.userData.shiftY = cdata.shifty
|
|
23
29
|
} else if (type === 1) {
|
|
@@ -33,7 +39,6 @@ export function createCamera(object: any, ctx: any): Object3D | undefined {
|
|
|
33
39
|
cdata.clipsta || 0.1,
|
|
34
40
|
cdata.clipend || 1000
|
|
35
41
|
)
|
|
36
|
-
camera.position.set(0, 0, 0)
|
|
37
42
|
if ('shiftx' in cdata) camera.userData.shiftX = cdata.shiftx
|
|
38
43
|
if ('shifty' in cdata) camera.userData.shiftY = cdata.shifty
|
|
39
44
|
} else {
|
|
@@ -42,5 +47,9 @@ export function createCamera(object: any, ctx: any): Object3D | undefined {
|
|
|
42
47
|
console.warn('Unsupported camera type', type)
|
|
43
48
|
}
|
|
44
49
|
|
|
50
|
+
// const obj = new Object3D()
|
|
51
|
+
// camera.rotation.x = -Math.PI / 2
|
|
52
|
+
// obj.add(camera)
|
|
53
|
+
|
|
45
54
|
return camera
|
|
46
55
|
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AmbientLight,
|
|
3
|
+
BufferAttribute,
|
|
4
|
+
BufferGeometry,
|
|
5
|
+
DirectionalLight,
|
|
6
|
+
Mesh,
|
|
7
|
+
MeshBasicMaterial,
|
|
8
|
+
MeshPhysicalMaterial,
|
|
9
|
+
Object3D,
|
|
10
|
+
OrthographicCamera,
|
|
11
|
+
PerspectiveCamera,
|
|
12
|
+
PointLight,
|
|
13
|
+
SpotLight,
|
|
14
|
+
} from 'threepipe'
|
|
15
|
+
|
|
16
|
+
export interface Ctx {
|
|
17
|
+
PointLight: typeof PointLight
|
|
18
|
+
SpotLight: typeof SpotLight
|
|
19
|
+
DirectionalLight: typeof DirectionalLight
|
|
20
|
+
AmbientLight: typeof AmbientLight
|
|
21
|
+
Object3D: typeof Object3D
|
|
22
|
+
PerspectiveCamera: typeof PerspectiveCamera
|
|
23
|
+
OrthographicCamera: typeof OrthographicCamera
|
|
24
|
+
Mesh: typeof Mesh
|
|
25
|
+
BufferGeometry: typeof BufferGeometry
|
|
26
|
+
BufferAttribute: typeof BufferAttribute
|
|
27
|
+
MeshPhysicalMaterial: typeof MeshPhysicalMaterial
|
|
28
|
+
MeshBasicMaterial: typeof MeshBasicMaterial
|
|
29
|
+
}
|
package/src/loader/geometry.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import {Ctx} from './ctx'
|
|
2
|
+
|
|
1
3
|
function getLayer(layers: any, i: number) {
|
|
2
4
|
if (!Array.isArray(layers)) return layers
|
|
3
5
|
return layers[i]
|
|
@@ -11,7 +13,7 @@ function getLayer(layers: any, i: number) {
|
|
|
11
13
|
// https://projects.blender.org/blender/blender/pulls/106638
|
|
12
14
|
|
|
13
15
|
// https://github.com/blender/blender/blob/55e2fd2929b7577e0785c128c8f8069efd990c07/source/blender/blenkernel/intern/mesh.cc#L413
|
|
14
|
-
export function createBufferGeometry(meshData: any, ctx:
|
|
16
|
+
export function createBufferGeometry(meshData: any, ctx: Ctx) {
|
|
15
17
|
|
|
16
18
|
if (meshData.mpoly) return createBufferGeometryOld(meshData, ctx)
|
|
17
19
|
const geometry = new ctx.BufferGeometry()
|
|
@@ -22,7 +24,9 @@ export function createBufferGeometry(meshData: any, ctx: any) {
|
|
|
22
24
|
// https://github.com/blender/blender/blob/05dcc0377b62d8e026e1901dfbecbd4b06fda0b5/scripts/addons_core/io_scene_gltf2/blender/exp/primitive_extract.py#L19
|
|
23
25
|
|
|
24
26
|
let vertices
|
|
27
|
+
let verticesData
|
|
25
28
|
let indices
|
|
29
|
+
let indicesData
|
|
26
30
|
|
|
27
31
|
// Extract vertex positions from vdata layers
|
|
28
32
|
if (meshData.vdata && meshData.vdata.layers && meshData.vdata.totlayer > 0) {
|
|
@@ -38,6 +42,7 @@ export function createBufferGeometry(meshData: any, ctx: any) {
|
|
|
38
42
|
continue
|
|
39
43
|
}
|
|
40
44
|
vertices = layer
|
|
45
|
+
verticesData = data
|
|
41
46
|
} else {
|
|
42
47
|
// console.log('unknown vdata', layer)
|
|
43
48
|
}
|
|
@@ -59,6 +64,7 @@ export function createBufferGeometry(meshData: any, ctx: any) {
|
|
|
59
64
|
continue
|
|
60
65
|
}
|
|
61
66
|
indices = layer
|
|
67
|
+
indicesData = data
|
|
62
68
|
} else {
|
|
63
69
|
// console.log('unknown ldata', layer)
|
|
64
70
|
}
|
|
@@ -104,30 +110,30 @@ export function createBufferGeometry(meshData: any, ctx: any) {
|
|
|
104
110
|
// return geometry
|
|
105
111
|
// }
|
|
106
112
|
|
|
107
|
-
if (
|
|
108
|
-
const positions = new Float32Array(
|
|
109
|
-
for (let j = 0; j <
|
|
110
|
-
const
|
|
111
|
-
if (
|
|
112
|
-
positions[j * 3] =
|
|
113
|
-
positions[j * 3 + 1] =
|
|
114
|
-
positions[j * 3 + 2] = -
|
|
115
|
-
} else if (
|
|
116
|
-
positions[j * 3] =
|
|
117
|
-
positions[j * 3 + 1] =
|
|
118
|
-
positions[j * 3 + 2] = -
|
|
113
|
+
if (verticesData && verticesData.length > 0) {
|
|
114
|
+
const positions = new Float32Array(verticesData.length * 3)
|
|
115
|
+
for (let j = 0; j < verticesData.length; j++) {
|
|
116
|
+
const {x, y, z, co} = verticesData[j] || {}
|
|
117
|
+
if (x !== undefined) {
|
|
118
|
+
positions[j * 3] = x
|
|
119
|
+
positions[j * 3 + 1] = z
|
|
120
|
+
positions[j * 3 + 2] = -y
|
|
121
|
+
} else if (co !== undefined) {
|
|
122
|
+
positions[j * 3] = co[0]
|
|
123
|
+
positions[j * 3 + 1] = co[2]
|
|
124
|
+
positions[j * 3 + 2] = -co[1]
|
|
119
125
|
} else {
|
|
120
126
|
// console.log(bakeGetters(meshData))
|
|
121
127
|
// const t = [...new Int32Array(vertex.__blender_file__.AB, vertex.__data_address__, 8)]
|
|
122
128
|
// debugger
|
|
123
|
-
console.error('BlendLoader - unknown vertex',
|
|
129
|
+
console.error('BlendLoader - unknown vertex', verticesData[j])
|
|
124
130
|
break
|
|
125
131
|
}
|
|
126
132
|
}
|
|
127
133
|
geometry.setAttribute('position', new ctx.BufferAttribute(positions, 3))
|
|
128
134
|
}
|
|
129
135
|
|
|
130
|
-
if (
|
|
136
|
+
if (indicesData && indicesData.length > 0 && verticesData?.length) {
|
|
131
137
|
const faceSize = meshData.totloop / meshData.totpoly
|
|
132
138
|
if (faceIndices.length > 0) {
|
|
133
139
|
// Use face offset indices for variable-sized faces
|
|
@@ -147,11 +153,11 @@ export function createBufferGeometry(meshData: any, ctx: any) {
|
|
|
147
153
|
|
|
148
154
|
if (faceVertCount >= 3) {
|
|
149
155
|
// todo better Triangulate the face using fan triangulation
|
|
150
|
-
const firstVert =
|
|
156
|
+
const firstVert = indicesData[faceStart].i
|
|
151
157
|
for (let k = 1; k < faceVertCount - 1; k++) {
|
|
152
158
|
indexes[t++] = firstVert
|
|
153
|
-
indexes[t++] =
|
|
154
|
-
indexes[t++] =
|
|
159
|
+
indexes[t++] = indicesData[faceStart + k].i
|
|
160
|
+
indexes[t++] = indicesData[faceStart + k + 1].i
|
|
155
161
|
}
|
|
156
162
|
} else {
|
|
157
163
|
// debugger
|
|
@@ -212,7 +218,7 @@ export function createBufferGeometry(meshData: any, ctx: any) {
|
|
|
212
218
|
// // meshData.eData = domain edge - https://github.com/blender/blender/blob/05dcc0377b62d8e026e1901dfbecbd4b06fda0b5/scripts/addons_core/io_scene_gltf2/blender/exp/primitive_extract.py#L189
|
|
213
219
|
// // todo normals, tangents
|
|
214
220
|
|
|
215
|
-
export function createBufferGeometryOld(mesh: any, ctx:
|
|
221
|
+
export function createBufferGeometryOld(mesh: any, ctx: Ctx) {
|
|
216
222
|
const
|
|
217
223
|
faces = Array.isArray(mesh.mpoly) ? mesh.mpoly as any[] : [mesh.mpoly],
|
|
218
224
|
loops = mesh.mloop,
|
|
@@ -249,24 +255,27 @@ export function createBufferGeometryOld(mesh: any, ctx: any) {
|
|
|
249
255
|
index += indexi - 1 + l
|
|
250
256
|
|
|
251
257
|
const loop = loops[index]
|
|
252
|
-
const
|
|
258
|
+
const {co, no} = vertices[loop.v] || {}
|
|
253
259
|
indices[currentIndex] = currentIndex
|
|
254
260
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
261
|
+
if (co) {
|
|
262
|
+
positions[currentIndex * 3 + 0] = co[0]
|
|
263
|
+
positions[currentIndex * 3 + 1] = co[2]
|
|
264
|
+
positions[currentIndex * 3 + 2] = -co[1]
|
|
265
|
+
}
|
|
258
266
|
|
|
259
|
-
if (
|
|
260
|
-
normals[currentIndex * 3 + 0] =
|
|
261
|
-
normals[currentIndex * 3 + 1] =
|
|
262
|
-
normals[currentIndex * 3 + 2] = -
|
|
267
|
+
if (no) {
|
|
268
|
+
normals[currentIndex * 3 + 0] = no[0]
|
|
269
|
+
normals[currentIndex * 3 + 1] = no[2]
|
|
270
|
+
normals[currentIndex * 3 + 2] = -no[1]
|
|
263
271
|
} else {
|
|
264
272
|
computeNormals = true
|
|
265
273
|
}
|
|
266
274
|
|
|
267
275
|
if (uv) {
|
|
268
|
-
|
|
269
|
-
uvs[currentIndex * 2 +
|
|
276
|
+
const uv1 = uv[index].uv
|
|
277
|
+
uvs[currentIndex * 2 + 0] = uv1[0]
|
|
278
|
+
uvs[currentIndex * 2 + 1] = uv1[1]
|
|
270
279
|
}
|
|
271
280
|
|
|
272
281
|
currentIndex++
|
package/src/loader/index.ts
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import {createCamera} from './camera'
|
|
2
2
|
import {createLight} from './light'
|
|
3
|
-
import {createMesh
|
|
4
|
-
import {Object3D} from 'threepipe'
|
|
3
|
+
import {createMesh} from './mesh'
|
|
4
|
+
import {IObject3D, Object3D} from 'threepipe'
|
|
5
|
+
import {Ctx} from './ctx'
|
|
6
|
+
import {Euler, EulerOrder} from 'three/src/math/Euler'
|
|
7
|
+
import {Quaternion, Vector3} from 'three'
|
|
5
8
|
|
|
6
9
|
// https://github.com/blender/blender/blob/99a4c93081cc2310a09a14f20a1493e8974c10d2/source/blender/makesdna/DNA_object_types.h#L445
|
|
7
10
|
const blenderObjectTypes = {
|
|
@@ -11,7 +14,7 @@ const blenderObjectTypes = {
|
|
|
11
14
|
camera: 11,
|
|
12
15
|
}
|
|
13
16
|
|
|
14
|
-
export async function createObjects(file: any, ctx:
|
|
17
|
+
export async function createObjects(file: any, ctx: Ctx) {
|
|
15
18
|
const objects: (Object3D|null)[] = []
|
|
16
19
|
const childMap = new Map<any, Object3D[]>()
|
|
17
20
|
const objMap = new Map<any, Object3D>()
|
|
@@ -42,7 +45,7 @@ export async function createObjects(file: any, ctx: any) {
|
|
|
42
45
|
console.warn('Unsupported object type', object.type, object, obj)
|
|
43
46
|
}
|
|
44
47
|
if (obj) {
|
|
45
|
-
|
|
48
|
+
setTransform(object, obj as any)
|
|
46
49
|
const exChildren = childMap.get(object)
|
|
47
50
|
if (exChildren) {
|
|
48
51
|
for (const exChild of exChildren) {
|
|
@@ -52,7 +55,7 @@ export async function createObjects(file: any, ctx: any) {
|
|
|
52
55
|
}
|
|
53
56
|
objMap.set(object, obj)
|
|
54
57
|
if (object.parent === object) {
|
|
55
|
-
console.error('invalid, parent same as object, adding to root', object)
|
|
58
|
+
console.error('BlendLoader - invalid, parent same as object, adding to root', object)
|
|
56
59
|
objects.push(obj)
|
|
57
60
|
} else if (!object.parent) { // just in case
|
|
58
61
|
objects.push(obj)
|
|
@@ -71,8 +74,42 @@ export async function createObjects(file: any, ctx: any) {
|
|
|
71
74
|
}
|
|
72
75
|
if (childMap.size) {
|
|
73
76
|
const vals = [...childMap.values()].flat()
|
|
74
|
-
console.warn('unknown objects with parents, adding to root', vals, childMap)
|
|
77
|
+
console.warn('BlendLoader - unknown objects with parents, adding to root', vals, childMap)
|
|
75
78
|
objects.push(...vals)
|
|
76
79
|
}
|
|
77
80
|
return objects.filter(o => !!o) as Object3D[]
|
|
78
81
|
}
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
// https://github.com/blender/blender/blob/458e224587e8c45da20841a283cc1b41adc98950/source/blender/makesdna/DNA_action_types.h#L526
|
|
85
|
+
const eulerModes: Record<number, EulerOrder> = {
|
|
86
|
+
[1]: 'XYZ',
|
|
87
|
+
[2]: 'XZY',
|
|
88
|
+
[3]: 'YXZ',
|
|
89
|
+
[4]: 'YZX',
|
|
90
|
+
[5]: 'ZXY',
|
|
91
|
+
[6]: 'ZYX',
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function setTransform(object: any, obj: IObject3D) {
|
|
95
|
+
obj.name = object.aname
|
|
96
|
+
obj.scale.set(object.size[0], object.size[2], object.size[1])
|
|
97
|
+
obj.position.set(object.loc[0], object.loc[2], -object.loc[1])
|
|
98
|
+
|
|
99
|
+
if (!object.rotmode || object.rotmode === 0) {
|
|
100
|
+
// const quat = new Quaternion()
|
|
101
|
+
obj.quaternion.set(object.quat[1], object.quat[3], -object.quat[2], object.quat[0]) // wxyz
|
|
102
|
+
} else {
|
|
103
|
+
// console.log(object.rotmode)
|
|
104
|
+
// const order = eulerModes[4]
|
|
105
|
+
const order = eulerModes[object.rotmode] ?? 'XYZ'
|
|
106
|
+
const quat = new Quaternion().setFromEuler(new Euler(object.rot[0], object.rot[1], object.rot[2], order.split('').reverse().join('') as any))
|
|
107
|
+
obj.quaternion.set(quat.x, quat.z, -quat.y, quat.w) // wxyz
|
|
108
|
+
}
|
|
109
|
+
// because camera is rotated 90d in blender
|
|
110
|
+
if (object.type === blenderObjectTypes.camera)
|
|
111
|
+
obj.quaternion.multiply(new Quaternion().setFromAxisAngle(new Vector3(1, 0, 0), -Math.PI / 2))
|
|
112
|
+
|
|
113
|
+
obj.updateMatrix()
|
|
114
|
+
if (obj.setDirty) obj.setDirty()
|
|
115
|
+
}
|
package/src/loader/light.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {Light} from 'threepipe'
|
|
2
|
+
import {Ctx} from './ctx'
|
|
2
3
|
|
|
3
4
|
const blenderLightTypes = {
|
|
4
5
|
point: 0,
|
|
@@ -8,7 +9,7 @@ const blenderLightTypes = {
|
|
|
8
9
|
area: 0,
|
|
9
10
|
}
|
|
10
11
|
|
|
11
|
-
export function createLight(lamp: any, ctx:
|
|
12
|
+
export function createLight(lamp: any, ctx: Ctx) {
|
|
12
13
|
const ldata = lamp.data
|
|
13
14
|
|
|
14
15
|
const position = [lamp.loc[0], lamp.loc[2], -lamp.loc[1]]
|
package/src/loader/material.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
// todo see blender gltf exporter and convert to js. structure is the same
|
|
2
2
|
// https://github.com/KhronosGroup/glTF-Blender-IO/blob/ed5100ab6c40472b7c3254fddfe0dd0d76d60644/addons/io_scene_gltf2/blender/exp/material/materials.py#L60
|
|
3
|
-
|
|
3
|
+
import {Ctx} from './ctx'
|
|
4
|
+
|
|
5
|
+
export function createMaterial(mat: any, ctx: Ctx) {
|
|
4
6
|
const material = new ctx.MeshPhysicalMaterial()
|
|
5
7
|
material.color.setRGB(mat.r, mat.g, mat.b)
|
|
6
8
|
material.roughness = mat.roughness !== undefined ? mat.roughness : 0.4
|
package/src/loader/mesh.ts
CHANGED
|
@@ -1,20 +1,8 @@
|
|
|
1
|
-
import {Object3D} from 'threepipe'
|
|
2
1
|
import {createBufferGeometry} from './geometry'
|
|
3
2
|
import {createMaterial} from './material'
|
|
3
|
+
import {Ctx} from './ctx'
|
|
4
4
|
|
|
5
|
-
export function
|
|
6
|
-
// obj.rotateZ(object.rot[2])
|
|
7
|
-
// obj.rotateY(object.rot[1])
|
|
8
|
-
// obj.rotateX(object.rot[0])
|
|
9
|
-
|
|
10
|
-
obj.name = object.aname
|
|
11
|
-
obj.quaternion.set(object.quat[1], object.quat[3], -object.quat[2], object.quat[0]) // wxyz
|
|
12
|
-
obj.scale.set(object.size[0], object.size[1], object.size[2])
|
|
13
|
-
obj.position.set(object.loc[0], object.loc[2], -object.loc[1])
|
|
14
|
-
obj.updateMatrix()
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export function createMesh(object: any, loaded: WeakMap<any, any>, ctx: any) {
|
|
5
|
+
export function createMesh(object: any, loaded: WeakMap<any, any>, ctx: Ctx) {
|
|
18
6
|
if (!object.data) {
|
|
19
7
|
return undefined
|
|
20
8
|
}
|