@threepipe/plugin-blend-importer 0.0.2 → 0.0.5

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/index.mjs CHANGED
@@ -1,11 +1,618 @@
1
1
  /**
2
2
  * @license
3
- * @threepipe/plugin-blend-importer v0.0.2
4
- * Copyright 2022-2024 repalash <palash@shaders.app>
3
+ * @threepipe/plugin-blend-importer v0.0.5
4
+ * Copyright 2022-2025 repalash <palash@shaders.app>
5
5
  * Apache-2.0 License
6
- * See ./dependencies.txt for bundled third-party dependencies and licenses.
6
+ * See ./dependencies.txt for any bundled third-party dependencies and licenses.
7
7
  */
8
- import{PointLight as t,BufferGeometry as e,BufferAttribute as n,MeshPhysicalMaterial as r,Mesh as s,BaseImporterPlugin as _,Importer as i,FileLoader as o,Object3D as a}from"threepipe";const l=826363460,d=1111772741;let u=null;const c={loadBlendFromArrayBuffer:function(t){c.ready=!1,u.onmessage({data:t})},ready:!0,onParseReady:function(){}};u=new function(){let t=null,e=null,n=!1,r=0,s=[],_=0,i=null,o={},a=null,u=null,c=null;const h=this;var f=function(t){this.AB=t,this.byte=new Uint8Array(t),this.dv=new DataView(t),this.objects={},this.memory_lookup={},this.object_array=[],this.template=null};function p(t){return{get:function(){let e=this.__blender_file__.getPointer(this.__data_address__+t,this.__blender_file__);const n=this.__blender_file__.memory_lookup[e],r=[];if(n){const t=n.__data_address__;let s=0;for(;;){e=this.__blender_file__.getPointer(t+8*s,this.__blender_file__);let n=this.__blender_file__.memory_lookup[e];if(!n)break;r.push(n),s++}}return r},set:function(){}}}function b(t,e,n,r,s,_,i,o){if(_)Object.defineProperty(t,e,function(t,e,n){return{get:function(){if(e>1){let r=[],s=0,_=t;for(;s<e;){let t=this.__blender_file__.getPointer(this.__data_address__+_,this.__blender_file__);r.push(this.__blender_file__.memory_lookup[t]),_+=n,s++}return r}{let e=this.__blender_file__.getPointer(this.__data_address__+t,this.__blender_file__);return this.__blender_file__.memory_lookup[e]}},set:function(){}}}(r,s,i)),r+=i*s;else{switch(n){case"double":Object.defineProperty(t,e,function(t,e,n){return{get:function(){return e>1?new Float64Array(this.__blender_file__.AB,this.__data_address__+t,n):this.__blender_file__.dv.getFloat64(this.__data_address__+t,this.__blender_file__.template.endianess)},set:function(n){e>1||this.__blender_file__.dv.setFloat64(this.__data_address__+t,n,this.__blender_file__.template.endianess)}}}(r,s,o>>3));break;case"float":Object.defineProperty(t,e,function(t,e,n){return{get:function(){return e>1?new Float32Array(this.__blender_file__.AB,this.__data_address__+t,n):this.__blender_file__.dv.getFloat32(this.__data_address__+t,this.__blender_file__.template.endianess)},set:function(n){e>1||this.__blender_file__.dv.setFloat32(this.__data_address__+t,n,this.__blender_file__.template.endianess)}}}(r,s,o>>2));break;case"int":Object.defineProperty(t,e,function(t,e,n){return{get:function(){return e>1?new Int32Array(this.__blender_file__.AB,this.__data_address__+t,n):this.__blender_file__.dv.getInt32(this.__data_address__+t,this.__blender_file__.template.endianess)},set:function(n){e>1||this.__blender_file__.dv.setInt32(this.__data_address__+t,n,this.__blender_file__.template.endianess)}}}(r,s,o>>2));break;case"short":case"ushort":Object.defineProperty(t,e,function(t,e,n){return{get:function(){return e>1?new Int16Array(this.__blender_file__.AB,this.__data_address__+t,n):this.__blender_file__.dv.getInt16(this.__data_address__+t,this.__blender_file__.template.endianess)},set:function(n){e>1||this.__blender_file__.dv.setInt16(this.__data_address__+t,n,this.__blender_file__.template.endianess)}}}(r,s,o>>1));break;case"char":case"uchar":Object.defineProperty(t,e,function(t,e,n){return{get:function(){if(e>1){let e=this.__data_address__+t,r=e,s=0;for(;0!=this.__blender_file__.byte[r]&&s++<n;)r++;return m(this.__blender_file__.AB,e,r)}return this.__blender_file__.byte[this.__data_address__+t]},set:function(r){if(e>1){const e=r+"";let s=0;const _=e.length;for(;s<n;)this.__blender_file__.byte[this.__data_address__+t+s]=s<_?0|e.charCodeAt(s):0,s++}else this.__blender_file__.byte[this.__data_address__+t]=0|r}}}(r,s,o));break;default:t[e]={},t.__list__.push(e,n,o,r,s,_)}t._length+=o,r+=o}return r}f.prototype={addObject:function(t){this.object_array.push(t),this.objects[t.blender_name]||(this.objects[t.blender_name]=[]),this.objects[t.blender_name].push(t)},getPointer:function(t){const e=this.dv.getUint32(t,this.template.endianess);if(this.template.pointer_size>4){const n=this.dv.getUint32(t+4,this.template.endianess);return this.template.endianess?e+"l|h"+n:n+"h|l"+e}return e}},h.onmessage=function(p){"object"==typeof p.data&&(c=null,t=null,n=!1,r=0,s=[],_=0,i=null,e=p.data,c=e.slice(),t=new DataView(e),a=new f(c),function(){let c=0,h=0,f=0,p=0,b="",g=0,w=0,A=0;if(a.memory_lookup={},s=[],_=0,"BLENDER"!==m(e,_,7))return u="File supplied is not a .blend compatible Blender file.";_+=7,r="_"==m(e,_++,_)?4:8,n="V"!==m(e,_++,_);const S=m(e,_,_+3);o[S]||(o[S]=new y(S));if(i=o[S],a.template=i,_+=3,!i.SDNA_SET)for(i.endianess=n,i.pointer_size=r,h=_;;){if(p=t.getInt32(h+r+8,n),b=m(e,h,h+4).replace(/\u0000/g,""),g=t.getInt32(h+4,!0),h+=16+r,"DNA1"===b){c=0;let r=[],_=[],o=[],a="";for(h+=8,c=t.getInt32(h,!0),h+=4,w=0;w<c;){for(a="";0!==t.getInt8(h);)a+=m(e,h,h+1),h++;_.push(a),h++,w++}for(h%4>0&&(h=4-h%4+h),h+=4,c=t.getInt32(h,!0),h+=4,w=0;w<c;){for(a="";0!==t.getInt8(h);)a+=m(e,h,h+1),h++;r.push(a),h++,w++}for(h%4>0&&(h=4-h%4+h),h+=4,w=0;w<c;)o.push(t.getInt16(h,n)),h+=2,w++;h%4>0&&(h=4-h%4+h),h+=4;const l=t.getInt32(h,n);for(h+=4,w=0;w<l;){const e=r[t.getInt16(h,n)];h+=2;const a=[];for(c=t.getInt16(h,n),h+=2,A=0,s.push(e);A<c;)a.push(_[t.getInt16(h+2,n)],r[t.getInt16(h,n)],o[t.getInt16(h,n)]),h+=4,A++;i.getSDNAStructureConstructor(e,a),w++}i.SDNA_SET=!0,i.SDNA_NAMES=s;break}h+=g}for(;;){_%4>0&&(_=4-_%4+_),f=_,p=t.getInt32(_+r+8,n);let e=t.getUint32(_,n);if(h=_+16+r,_+=t.getInt32(_+4,!0)+16+r,e===l);else{if(e===d)break;{const e=f+r+16,s=i.getSDNAStructureConstructor(i.SDNA_NAMES[p]),_=t.getInt32(f+4,n);if(c=t.getInt32(f+12+r,n),c>0){let t=new s;const n=s.prototype._length,r=a.getPointer(f+8);if(t.address=r+"",t.setData(r,e,e+_,a),c>1){let _=[];_.push(t);for(let i=1;i<c;i++)t=new s,t.setData(r,e+n*i,e+n*i+n,a),_.push(t);a.memory_lookup[r]=_}else a.memory_lookup[r]=t}}}}}(),h.postMessage(a,u))};const y=function(t){this.version=t,this.SDNA_SET=!1,this.byte_size=0,this.struct_index=0,this.structs={},this.SDNA={},this.endianess=!1};y.prototype={getSDNAStructureConstructor:function(t,e){if(e){const n=Function("function "+t+"(){}; return "+t)();n.prototype=new g,n.prototype.blender_name=t,n.prototype.__pointers=[],n.prototype.__list__=[];let s=0;for(let _=0;_<e.length;_+=3){let i=e[_];const o=i,a=e[_+1];let l=e[_+2],d=0,u=null,c=1,h=1,f=!1,y=0;const g=this.SDNA[t]={constructor:n};if((u=i.match(/(\*?)(\*?)(\w+)(\[(\w*)\])?(\[(\w*)\])?/))&&(i=u[3],u[1]&&(y=10,n.prototype.__pointers.push(i)),u[2]&&(f=!0),u[4]&&(u[6]?(h=parseInt(u[5]),c=parseInt(u[7])):c=parseInt(u[5])),d=c*l,l=d*h),g[o]={type:a,length:l,isArray:c>0},f)Object.defineProperty(n.prototype,i,p(s)),s+=r;else if(h>1){const t=new Array(h);for(let e=0;e<h;e++){let _=`__${i}[${e}]__`;t[e]=_,s=b(n.prototype,_,a,s,c,y,r,d)}Object.defineProperty(n.prototype,i,{get:function(t){return function(){const e=[];for(let n=0;n<t.length;n++)e.push(this[t[n]]);return e}}(t)})}else s=b(n.prototype,i,a,s,c,y,r,l)}return this.SDNA[t].constructor}return this.SDNA[t]?this.SDNA[t].constructor:null}};var g=function(){this.__blender_file__=null,this.__list__=null,this.__super_array_list__=null,this.blender_name="",this.__pointers=null,this.address=null,this.length=0,this.__data_address__=0,this.blender_name="",this._length=0};function m(t,e,n){return String.fromCharCode.apply(String,new Uint8Array(t,e,n-e))}g.prototype={setData:function(t,e,n,r){if(null===this.__list__)return this;r.addObject(this),this.__blender_file__=r;const s=this.__list__;let _,o,a,l,d,u=0,c=0,h="";if(this.__data_address__=e,null===s)return this;for(c=0;c<s.length;c+=6)if(h=s[c],_=s[c+1],a=s[c+4],s[c+5],l=this.__data_address__+s[c+3],a>1)for(this[h]=[],u=0;u<a;)i.getSDNAStructureConstructor(_)?(d=i.getSDNAStructureConstructor(_),this[h].push((new d).setData(0,l,l+o/a,r))):this[h].push(null),l+=o/a,u++;else i.getSDNAStructureConstructor(_)?(d=i.getSDNAStructureConstructor(_),this[h]=(new d).setData(0,l,o+l,r)):this[h]=null;return this.__list__=null,this},get aname(){return this.id?this.id.name.slice(2):void 0}}},u.postMessage=function(t){c.onParseReady(t)};const h={point:0,sun:1,spot:0,hemi:0,area:0};function f(e){const n=e.data,r=[e.loc[0],e.loc[2],-e.loc[1]],s=255*n.r<<16|255*n.g<<8|255*n.b<<0,_=n.energy;let i=null;switch(n.type){case h.point:i=new t(s,_,0),i.position.fromArray(r,0),i.castShadow=!0;break;case h.sun:i=new t(s,_,0),i.position.fromArray(r,0),i.castShadow=!0,i.shadow.mapSize.width=1024,i.shadow.mapSize.height=1024,i.shadow.camera.near=.01,i.shadow.camera.far=500;break;default:console.warn("Unsupported light type",n.type)}return i}function p(t){if(!t.data)return null;const _=function(t,r){const s=Array.isArray(t.mpoly)?t.mpoly:[t.mpoly],_=t.mloop,i=t.mloopuv,o=t.mvert,a=new e;if(!s)return a;const l=s.reduce(((t,e)=>t+Math.floor(3*e.totloop/2)),0),d=new Uint32Array(l),u=new Float32Array(2*l),c=new Float32Array(3*l),h=new Float32Array(3*l);let f=0;for(const t of s){const e=t.totloop,n=t.loopstart;let s=1;for(;s<e;){let t=0;for(let a=0;a<3;a++){t=n,s-1+a<e&&(t+=s-1+a);const l=o[_[t].v];d[f]=f,h[3*f+0]=l.co[0]+r[0],h[3*f+1]=l.co[2]+r[2],h[3*f+2]=-l.co[1]-r[1],c[3*f+0]=l.no[0],c[3*f+1]=l.no[2],c[3*f+2]=-l.no[1],i&&(u[2*f+0]=i[t].uv[0],u[2*f+1]=i[t].uv[1]),f++}s+=2}}return a.setAttribute("position",new n(h,3)),a.setIndex(new n(d,1)),a.setAttribute("normal",new n(c,3)),a.setAttribute("uv",new n(u,2)),a}(t.data,[0,0,0]),i=t.data.mat[0],o=i?function(t){const e=new r;return e.color.setRGB(t.r,t.g,t.b),e.roughness=void 0!==t.roughness?t.roughness:.4,e.metalness=void 0!==t.metallic?t.metallic:0,e.opacity=void 0!==t.alpha?t.alpha:0,e.transparent=e.opacity<1,e}(i):void 0,a=new s(_,o);return a.castShadow=!0,a.receiveShadow=!0,a.rotateZ(t.rot[2]),a.rotateY(t.rot[1]),a.rotateX(t.rot[0]),a.scale.fromArray(t.size,0),a.position.fromArray([t.loc[0],t.loc[2],-t.loc[1]],0),a}const b=1,y=10;class g extends _{constructor(){super(),this._importer=new i(class extends o{async loadAsync(t,e){this.setResponseType("arraybuffer");const n=await super.loadAsync(t,e),r=
8
+ import { BaseImporterPlugin, Importer, FileLoader, Object3D, Object3D2, PerspectiveCamera0, OrthographicCamera0, PointLight2, PhysicalMaterial, Mesh2, BufferGeometry2, BufferAttribute } from "threepipe";
9
+ let worker = null;
10
+ const return_object = {
11
+ loadBlendFromArrayBuffer: function(array_buffer) {
12
+ return_object.ready = false;
13
+ {
14
+ worker.onmessage({
15
+ data: array_buffer
16
+ });
17
+ }
18
+ },
19
+ // loadBlendFromBlob: function (blob) {
20
+ // FR.onload = function () {
21
+ // return_object.loadBlendFromArrayBuffer(this.result);
22
+ // };
23
+ // FR.readAsArrayBuffer(blob);
24
+ // },
25
+ ready: true,
26
+ onParseReady: function() {
27
+ }
28
+ };
29
+ function worker_code() {
30
+ let data = null, _data = null, BIG_ENDIAN = false, pointer_size = 0, struct_names = [], offset = 0, current_SDNA_template = null, templates = {}, FILE = null, ERROR = null, AB = null;
31
+ const self = this;
32
+ function parseFile(msg) {
33
+ if (typeof msg.data == "object") {
34
+ AB = null;
35
+ data = null;
36
+ BIG_ENDIAN = false;
37
+ pointer_size = 0;
38
+ struct_names = [];
39
+ offset = 0;
40
+ current_SDNA_template = null;
41
+ _data = msg.data;
42
+ AB = _data.slice();
43
+ data = new DataView(_data);
44
+ FILE = new BLENDER_FILE(AB);
45
+ readFile();
46
+ self.postMessage(FILE, ERROR);
47
+ }
48
+ }
49
+ const BLENDER_FILE = function(AB2) {
50
+ this.AB = AB2;
51
+ this.byte = new Uint8Array(AB2);
52
+ this.dv = new DataView(AB2);
53
+ this.objects = {};
54
+ this.memory_lookup = {}, this.object_array = [];
55
+ this.template = null;
56
+ };
57
+ BLENDER_FILE.prototype = {
58
+ addObject: function(obj) {
59
+ this.object_array.push(obj);
60
+ if (!this.objects[obj.blender_name]) this.objects[obj.blender_name] = [];
61
+ this.objects[obj.blender_name].push(obj);
62
+ },
63
+ getPointer: function(offset2) {
64
+ const pointerLow = this.dv.getUint32(offset2, this.template.endianess);
65
+ if (this.template.pointer_size > 4) {
66
+ const pointerHigh = this.dv.getUint32(offset2 + 4, this.template.endianess);
67
+ if (this.template.endianess) {
68
+ return pointerLow + "l|h" + pointerHigh;
69
+ } else {
70
+ return pointerHigh + "h|l" + pointerLow;
71
+ }
72
+ } else {
73
+ return pointerLow;
74
+ }
75
+ }
76
+ };
77
+ self.onmessage = parseFile;
78
+ function float64Prop(offset2, Blender_Array_Length, length) {
79
+ return {
80
+ get: function() {
81
+ return Blender_Array_Length > 1 ? new Float64Array(this.__blender_file__.AB, this.__data_address__ + offset2, length) : this.__blender_file__.dv.getFloat64(this.__data_address__ + offset2, this.__blender_file__.template.endianess);
82
+ },
83
+ set: function(float) {
84
+ if (Blender_Array_Length > 1) ;
85
+ else {
86
+ this.__blender_file__.dv.setFloat64(this.__data_address__ + offset2, float, this.__blender_file__.template.endianess);
87
+ }
88
+ },
89
+ enumerable: true,
90
+ configurable: true
91
+ };
92
+ }
93
+ function floatProp(offset2, Blender_Array_Length, length) {
94
+ return {
95
+ get: function() {
96
+ return Blender_Array_Length > 1 ? new Float32Array(this.__blender_file__.AB, this.__data_address__ + offset2, length) : this.__blender_file__.dv.getFloat32(this.__data_address__ + offset2, this.__blender_file__.template.endianess);
97
+ },
98
+ set: function(float) {
99
+ if (Blender_Array_Length > 1) ;
100
+ else {
101
+ this.__blender_file__.dv.setFloat32(this.__data_address__ + offset2, float, this.__blender_file__.template.endianess);
102
+ }
103
+ },
104
+ enumerable: true,
105
+ configurable: true
106
+ };
107
+ }
108
+ function intProp(offset2, Blender_Array_Length, length) {
109
+ return {
110
+ get: function() {
111
+ return Blender_Array_Length > 1 ? new Int32Array(this.__blender_file__.AB, this.__data_address__ + offset2, length) : this.__blender_file__.dv.getInt32(this.__data_address__ + offset2, this.__blender_file__.template.endianess);
112
+ },
113
+ set: function(float) {
114
+ if (Blender_Array_Length > 1) ;
115
+ else {
116
+ this.__blender_file__.dv.setInt32(this.__data_address__ + offset2, float, this.__blender_file__.template.endianess);
117
+ }
118
+ },
119
+ enumerable: true,
120
+ configurable: true
121
+ };
122
+ }
123
+ function shortProp(offset2, Blender_Array_Length, length) {
124
+ return {
125
+ get: function() {
126
+ return Blender_Array_Length > 1 ? new Int16Array(this.__blender_file__.AB, this.__data_address__ + offset2, length) : this.__blender_file__.dv.getInt16(this.__data_address__ + offset2, this.__blender_file__.template.endianess);
127
+ },
128
+ set: function(float) {
129
+ if (Blender_Array_Length > 1) ;
130
+ else {
131
+ this.__blender_file__.dv.setInt16(this.__data_address__ + offset2, float, this.__blender_file__.template.endianess);
132
+ }
133
+ },
134
+ enumerable: true,
135
+ configurable: true
136
+ };
137
+ }
138
+ const uShortProp = (offset2, Blender_Array_Length, length) => {
139
+ return {
140
+ get: function() {
141
+ return Blender_Array_Length > 1 ? new Uint16Array(this.__blender_file__.AB, this.__data_address__ + offset2, length) : this.__blender_file__.dv.getUint16(this.__data_address__ + offset2, this.__blender_file__.template.endianess);
142
+ },
143
+ set: function(float) {
144
+ if (Blender_Array_Length > 1) ;
145
+ else {
146
+ this.__blender_file__.dv.setUint16(this.__data_address__ + offset2, float, this.__blender_file__.template.endianess);
147
+ }
148
+ },
149
+ enumerable: true,
150
+ configurable: true
151
+ };
152
+ };
153
+ function charProp(offset2, Blender_Array_Length, length) {
154
+ return {
155
+ get: function() {
156
+ if (Blender_Array_Length > 1) {
157
+ let start = this.__data_address__ + offset2;
158
+ let end = start;
159
+ let buffer_guard = 0;
160
+ while (this.__blender_file__.byte[end] != 0 && buffer_guard++ < length) end++;
161
+ return toString(this.__blender_file__.AB, start, end);
162
+ }
163
+ return this.__blender_file__.byte[this.__data_address__ + offset2];
164
+ },
165
+ set: function(byte) {
166
+ if (Blender_Array_Length > 1) {
167
+ const string = byte + "";
168
+ let i = 0;
169
+ const l = string.length;
170
+ while (i < length) {
171
+ if (i < l) {
172
+ this.__blender_file__.byte[this.__data_address__ + offset2 + i] = string.charCodeAt(i) | 0;
173
+ } else {
174
+ this.__blender_file__.byte[this.__data_address__ + offset2 + i] = 0;
175
+ }
176
+ i++;
177
+ }
178
+ } else {
179
+ this.__blender_file__.byte[this.__data_address__ + offset2] = byte | 0;
180
+ }
181
+ },
182
+ enumerable: true,
183
+ configurable: true
184
+ };
185
+ }
186
+ function pointerProp2(offset2) {
187
+ return {
188
+ get: function() {
189
+ let pointer = this.__blender_file__.getPointer(this.__data_address__ + offset2, this.__blender_file__);
190
+ const link = this.__blender_file__.memory_lookup[pointer];
191
+ const results = [];
192
+ if (link) {
193
+ const address = link.__data_address__;
194
+ let j = 0;
195
+ while (true) {
196
+ pointer = this.__blender_file__.getPointer(address + j * 8, this.__blender_file__);
197
+ let obj = this.__blender_file__.memory_lookup[pointer];
198
+ if (!obj) break;
199
+ results.push(obj);
200
+ j++;
201
+ }
202
+ }
203
+ return results;
204
+ },
205
+ set: function() {
206
+ },
207
+ enumerable: true,
208
+ configurable: true
209
+ };
210
+ }
211
+ function pointerProp(offset2, Blender_Array_Length, length) {
212
+ return {
213
+ get: function() {
214
+ if (Blender_Array_Length > 1) {
215
+ let array = [];
216
+ let j = 0;
217
+ let off = offset2;
218
+ while (j < Blender_Array_Length) {
219
+ let pointer = this.__blender_file__.getPointer(this.__data_address__ + off, this.__blender_file__);
220
+ array.push(this.__blender_file__.memory_lookup[pointer]);
221
+ off += length;
222
+ j++;
223
+ }
224
+ return array;
225
+ } else {
226
+ let pointer = this.__blender_file__.getPointer(this.__data_address__ + offset2, this.__blender_file__);
227
+ return this.__blender_file__.memory_lookup[pointer];
228
+ }
229
+ },
230
+ set: function() {
231
+ },
232
+ enumerable: true,
233
+ configurable: true
234
+ };
235
+ }
236
+ function compileProp(obj, name, type, offset2, array_size, IS_POINTER, pointer_size2, length) {
237
+ if (!IS_POINTER) {
238
+ switch (type) {
239
+ case "double":
240
+ Object.defineProperty(obj, name, float64Prop(offset2, array_size, length >> 3));
241
+ break;
242
+ case "float":
243
+ Object.defineProperty(obj, name, floatProp(offset2, array_size, length >> 2));
244
+ break;
245
+ case "int":
246
+ Object.defineProperty(obj, name, intProp(offset2, array_size, length >> 2));
247
+ break;
248
+ case "short":
249
+ Object.defineProperty(obj, name, shortProp(offset2, array_size, length >> 1));
250
+ break;
251
+ case "ushort":
252
+ Object.defineProperty(obj, name, uShortProp(offset2, array_size, length >> 1));
253
+ break;
254
+ case "char":
255
+ case "uchar":
256
+ Object.defineProperty(obj, name, charProp(offset2, array_size, length));
257
+ break;
258
+ default:
259
+ obj[name] = {};
260
+ obj.__list__.push(name, type, length, offset2, array_size, IS_POINTER);
261
+ }
262
+ obj._length += length;
263
+ offset2 += length;
264
+ } else {
265
+ Object.defineProperty(obj, name, pointerProp(offset2, array_size, pointer_size2));
266
+ obj._length += pointer_size2 * array_size;
267
+ offset2 += pointer_size2 * array_size;
268
+ }
269
+ return offset2;
270
+ }
271
+ const MASTER_SDNA_SCHEMA = function(version) {
272
+ this.version = version;
273
+ this.SDNA_SET = false;
274
+ this.byte_size = 0;
275
+ this.struct_index = 0;
276
+ this.structs = {};
277
+ this.SDNA = {};
278
+ this.endianess = false;
279
+ };
280
+ MASTER_SDNA_SCHEMA.prototype = {
281
+ getSDNAStructureConstructor: function(name, struct) {
282
+ if (struct) {
283
+ const jsName = name === "void" ? "void_" : name;
284
+ const blen_struct = Function("function " + jsName + "(){}; return " + jsName)();
285
+ blen_struct.prototype = new BLENDER_STRUCTURE();
286
+ blen_struct.prototype.blender_name = name;
287
+ blen_struct.prototype.__pointers = [];
288
+ blen_struct.prototype.__list__ = [];
289
+ const DNA = this.SDNA[name] = {
290
+ constructor: blen_struct
291
+ };
292
+ let offset2 = 0;
293
+ for (let i = 0; i < struct.length; i += 3) {
294
+ let _name = struct[i];
295
+ const n = _name, type = struct[i + 1];
296
+ let length = struct[i + 2], array_length = 0, match = null, Blender_Array_Length = 1, Suparray_match = 1, PointerToArray = false, Pointer_Match = 0;
297
+ if (match = _name.match(/(\*?)(\*?)(\w+)(\[(\w*)\])?(\[(\w*)\])?/)) {
298
+ _name = match[3];
299
+ if (match[1]) {
300
+ Pointer_Match = 10;
301
+ blen_struct.prototype.__pointers.push(_name);
302
+ }
303
+ if (match[2]) {
304
+ PointerToArray = true;
305
+ }
306
+ if (match[4]) {
307
+ if (match[6]) {
308
+ Suparray_match = parseInt(match[5]);
309
+ Blender_Array_Length = parseInt(match[7]);
310
+ } else {
311
+ Blender_Array_Length = parseInt(match[5]);
312
+ }
313
+ }
314
+ array_length = Blender_Array_Length * length;
315
+ length = array_length * Suparray_match;
316
+ }
317
+ DNA[n] = {
318
+ type,
319
+ length,
320
+ isArray: Blender_Array_Length > 0
321
+ };
322
+ if (PointerToArray) {
323
+ Object.defineProperty(blen_struct.prototype, _name, pointerProp2(offset2));
324
+ offset2 += pointer_size;
325
+ } else if (Suparray_match > 1) {
326
+ const array_names = new Array(Suparray_match);
327
+ for (let j = 0; j < Suparray_match; j++) {
328
+ let array_name_ = `__${_name}[${j}]__`;
329
+ array_names[j] = array_name_;
330
+ offset2 = compileProp(blen_struct.prototype, array_name_, type, offset2, Blender_Array_Length, Pointer_Match, pointer_size, array_length);
331
+ }
332
+ Object.defineProperty(blen_struct.prototype, _name, {
333
+ get: /* @__PURE__ */ function(array_names2) {
334
+ return function() {
335
+ const array = [];
336
+ for (let i2 = 0; i2 < array_names2.length; i2++) {
337
+ array.push(this[array_names2[i2]]);
338
+ }
339
+ return array;
340
+ };
341
+ }(array_names),
342
+ enumerable: true,
343
+ configurable: true
344
+ });
345
+ } else {
346
+ offset2 = compileProp(blen_struct.prototype, _name, type, offset2, Blender_Array_Length, Pointer_Match, pointer_size, length);
347
+ }
348
+ }
349
+ return this.SDNA[name].constructor;
350
+ } else {
351
+ if (!this.SDNA[name]) {
352
+ return null;
353
+ }
354
+ return this.SDNA[name].constructor;
355
+ }
356
+ }
357
+ };
358
+ const BLENDER_STRUCTURE = function() {
359
+ this.__blender_file__ = null;
360
+ this.__list__ = null;
361
+ this.__super_array_list__ = null;
362
+ this.blender_name = "";
363
+ this.__pointers = null;
364
+ this.address = null;
365
+ this.length = 0;
366
+ this.__data_address__ = 0;
367
+ this.blender_name = "";
368
+ this._length = 0;
369
+ };
370
+ BLENDER_STRUCTURE.prototype = {
371
+ setData: function(pointer, _data_offset, data_block_length, BLENDER_FILE2) {
372
+ if (this.__list__ === null) return this;
373
+ BLENDER_FILE2.addObject(this);
374
+ this.__blender_file__ = BLENDER_FILE2;
375
+ const struct = this.__list__;
376
+ let j = 0, i = 0, name = "", type, length, Blender_Array_Length, offset2, constructor;
377
+ this.__data_address__ = _data_offset;
378
+ if (struct === null) return this;
379
+ for (i = 0; i < struct.length; i += 6) {
380
+ name = struct[i];
381
+ type = struct[i + 1];
382
+ Blender_Array_Length = struct[i + 4];
383
+ struct[i + 5];
384
+ offset2 = this.__data_address__ + struct[i + 3];
385
+ if (Blender_Array_Length > 1) {
386
+ this[name] = [];
387
+ j = 0;
388
+ while (j < Blender_Array_Length) {
389
+ if (current_SDNA_template.getSDNAStructureConstructor(type)) {
390
+ constructor = current_SDNA_template.getSDNAStructureConstructor(type);
391
+ this[name].push(new constructor().setData(0, offset2, offset2 + length / Blender_Array_Length, BLENDER_FILE2));
392
+ } else this[name].push(null);
393
+ offset2 += length / Blender_Array_Length;
394
+ j++;
395
+ }
396
+ } else {
397
+ if (current_SDNA_template.getSDNAStructureConstructor(type)) {
398
+ constructor = current_SDNA_template.getSDNAStructureConstructor(type);
399
+ this[name] = new constructor().setData(0, offset2, length + offset2, BLENDER_FILE2);
400
+ } else this[name] = null;
401
+ }
402
+ }
403
+ this.__list__ = null;
404
+ return this;
405
+ },
406
+ get aname() {
407
+ if (this.id) return this.id.name.slice(2);
408
+ else return void 0;
409
+ }
410
+ };
411
+ function toString(buffer, _in, _out) {
412
+ return String.fromCharCode.apply(String, new Uint8Array(buffer, _in, _out - _in));
413
+ }
414
+ function readFile() {
415
+ let count = 0;
416
+ let offset2 = 0;
417
+ let data_offset = 0;
418
+ let sdna_index = 0;
419
+ let code = "";
420
+ let block_length = 0;
421
+ let curr_count = 0;
422
+ let curr_count2 = 0;
423
+ FILE.memory_lookup = {};
424
+ struct_names = [];
425
+ offset = 0;
426
+ const magic = toString(_data, offset, 7);
427
+ if (magic !== "BLENDER") return ERROR = "File supplied is not a .blend compatible Blender file.";
428
+ offset += 7;
429
+ pointer_size = toString(_data, offset++, offset) == "_" ? 4 : 8;
430
+ BIG_ENDIAN = toString(_data, offset++, offset) !== "V";
431
+ const version = toString(_data, offset, offset + 3);
432
+ if (!templates[version]) {
433
+ templates[version] = new MASTER_SDNA_SCHEMA(version);
434
+ }
435
+ current_SDNA_template = templates[version];
436
+ FILE.template = current_SDNA_template;
437
+ offset += 3;
438
+ if (!current_SDNA_template.SDNA_SET) {
439
+ current_SDNA_template.endianess = BIG_ENDIAN;
440
+ current_SDNA_template.pointer_size = pointer_size;
441
+ offset2 = offset;
442
+ while (true) {
443
+ sdna_index = data.getInt32(offset2 + pointer_size + 8, BIG_ENDIAN);
444
+ code = toString(_data, offset2, offset2 + 4).replace(/\u0000/g, "");
445
+ block_length = data.getInt32(offset2 + 4, true);
446
+ offset2 += 16 + pointer_size;
447
+ if (code === "DNA1") {
448
+ count = 0;
449
+ let types = [], names = [], lengths = [], curr_name = "";
450
+ offset2 += 8;
451
+ count = data.getInt32(offset2, true);
452
+ offset2 += 4;
453
+ curr_count = 0;
454
+ while (curr_count < count) {
455
+ curr_name = "";
456
+ while (data.getInt8(offset2) !== 0) {
457
+ curr_name += toString(_data, offset2, offset2 + 1);
458
+ offset2++;
459
+ }
460
+ names.push(curr_name);
461
+ offset2++;
462
+ curr_count++;
463
+ }
464
+ if (toString(_data, offset2, offset2 + 4) !== "TYPE") {
465
+ for (let j = 0; j < 8; j++) {
466
+ if (toString(_data, offset2, offset2 + 4) === "TYPE") break;
467
+ offset2++;
468
+ }
469
+ }
470
+ if (toString(_data, offset2, offset2 + 4) !== "TYPE") {
471
+ debugger;
472
+ }
473
+ offset2 += 4;
474
+ count = data.getUint32(offset2, true);
475
+ offset2 += 4;
476
+ curr_count = 0;
477
+ while (curr_count < count) {
478
+ curr_name = "";
479
+ while (data.getInt8(offset2) !== 0) {
480
+ curr_name += toString(_data, offset2, offset2 + 1);
481
+ offset2++;
482
+ }
483
+ types.push(curr_name);
484
+ offset2++;
485
+ curr_count++;
486
+ }
487
+ if (toString(_data, offset2, offset2 + 4) !== "TLEN") {
488
+ for (let j = 0; j < 8; j++) {
489
+ if (toString(_data, offset2, offset2 + 4) === "TLEN") break;
490
+ offset2++;
491
+ }
492
+ }
493
+ if (toString(_data, offset2, offset2 + 4) !== "TLEN") {
494
+ debugger;
495
+ }
496
+ offset2 += 4;
497
+ curr_count = 0;
498
+ while (curr_count < count) {
499
+ lengths.push(data.getInt16(offset2, BIG_ENDIAN));
500
+ offset2 += 2;
501
+ curr_count++;
502
+ }
503
+ if (toString(_data, offset2, offset2 + 4) !== "STRC") {
504
+ for (let j = 0; j < 8; j++) {
505
+ if (toString(_data, offset2, offset2 + 4) === "STRC") break;
506
+ offset2++;
507
+ }
508
+ }
509
+ if (toString(_data, offset2, offset2 + 4) !== "STRC") {
510
+ debugger;
511
+ }
512
+ offset2 += 4;
513
+ const structure_count = data.getInt32(offset2, BIG_ENDIAN);
514
+ offset2 += 4;
515
+ curr_count = 0;
516
+ while (curr_count < structure_count) {
517
+ const struct_name = types[data.getInt16(offset2, BIG_ENDIAN)];
518
+ offset2 += 2;
519
+ const obj = [];
520
+ count = data.getInt16(offset2, BIG_ENDIAN);
521
+ offset2 += 2;
522
+ curr_count2 = 0;
523
+ struct_names.push(struct_name);
524
+ while (curr_count2 < count) {
525
+ obj.push(names[data.getInt16(offset2 + 2, BIG_ENDIAN)], types[data.getInt16(offset2, BIG_ENDIAN)], lengths[data.getInt16(offset2, BIG_ENDIAN)]);
526
+ offset2 += 4;
527
+ curr_count2++;
528
+ }
529
+ current_SDNA_template.getSDNAStructureConstructor(struct_name, obj);
530
+ curr_count++;
531
+ }
532
+ current_SDNA_template.SDNA_SET = true;
533
+ current_SDNA_template.SDNA_NAMES = struct_names;
534
+ break;
535
+ }
536
+ offset2 += block_length;
537
+ }
538
+ }
539
+ while (true) {
540
+ for (let j = 0; j < 8; j++) {
541
+ if (data.getInt8(offset) === 0) {
542
+ offset++;
543
+ continue;
544
+ }
545
+ break;
546
+ }
547
+ if (data.getInt8(offset) === 0) {
548
+ debugger;
549
+ }
550
+ data_offset = offset;
551
+ if (offset + pointer_size + 12 >= data.byteLength) {
552
+ ERROR = "Unexpected end of file while parsing";
553
+ break;
554
+ }
555
+ sdna_index = data.getInt32(offset + pointer_size + 8, BIG_ENDIAN);
556
+ const code_str = toString(_data, offset, offset + 4);
557
+ offset2 = offset + 16 + pointer_size;
558
+ const blockLength = data.getInt32(offset + 4, true);
559
+ if (blockLength < 0 || offset + blockLength + 16 + pointer_size > data.byteLength) {
560
+ ERROR = "Invalid block length detected";
561
+ break;
562
+ }
563
+ offset += blockLength + 16 + pointer_size;
564
+ if (code_str === "DNA1") ;
565
+ else if (code_str === "ENDB") break;
566
+ else if (code_str === "TEST") {
567
+ const data_start = data_offset + pointer_size + 16;
568
+ const width = data.getInt32(data_start, BIG_ENDIAN);
569
+ const height = data.getInt32(data_start + 4, BIG_ENDIAN);
570
+ if (width * height > 0) {
571
+ const data_len = width * height * 4;
572
+ if (blockLength < data_len + 8) {
573
+ ERROR = "Invalid TEST block length detected";
574
+ break;
575
+ }
576
+ const image_data = new Uint32Array(_data, data_start + 8, data_len >> 2);
577
+ const image = {
578
+ width,
579
+ height,
580
+ data: image_data
581
+ };
582
+ FILE.thumbnail = image;
583
+ }
584
+ } else {
585
+ const data_start = data_offset + pointer_size + 16;
586
+ const constructor = current_SDNA_template.getSDNAStructureConstructor(current_SDNA_template.SDNA_NAMES[sdna_index]);
587
+ const size = data.getInt32(data_offset + 4, BIG_ENDIAN);
588
+ count = data.getInt32(data_offset + 12 + pointer_size, BIG_ENDIAN);
589
+ if (count > 0 && constructor) {
590
+ let obj = new constructor();
591
+ const length = constructor.prototype._length;
592
+ const address = FILE.getPointer(data_offset + 8);
593
+ obj.address = address + "";
594
+ obj.setData(address, data_start, data_start + size, FILE);
595
+ if (count > 1) {
596
+ let array = [];
597
+ array.push(obj);
598
+ for (let u = 1; u < count; u++) {
599
+ obj = new constructor();
600
+ obj.setData(address, data_start + length * u, data_start + length * u + length, FILE);
601
+ array.push(obj);
602
+ }
603
+ FILE.memory_lookup[address] = array;
604
+ } else {
605
+ FILE.memory_lookup[address] = obj;
606
+ }
607
+ }
608
+ }
609
+ }
610
+ }
611
+ }
612
+ worker = new worker_code();
613
+ worker.postMessage = function(message, err) {
614
+ return_object.onParseReady(message, err);
615
+ };
9
616
  /**
10
617
  * JS.Blend
11
618
  * Original Repo: https://github.com/acweathersby/js.blend
@@ -14,5 +621,390 @@ import{PointLight as t,BufferGeometry as e,BufferAttribute as n,MeshPhysicalMate
14
621
  * MIT License
15
622
  * Copyright (c) 2020 Anthony C, Weathersby
16
623
  * @license
17
- */await async function(t,e=""){return new Promise(((n,r)=>{c.onParseReady=(t,e)=>{e?r(e):n(t)},c.loadBlendFromArrayBuffer(t,e)}))}(n),s=await async function(t){const e=[],n=t.objects.Object;for(const t of n)switch(t.type){case b:e.push(p(t));break;case y:e.push(f(t));break;default:console.warn("Unsupported object type",t.type)}return e.filter((t=>!!t))}(r),_=new a;return _.add(...s),r.scene=_,r}transform(t,e){return t.scene}},["blend"],["application/x-blender"],!0)}}g.PluginType="BlendLoadPlugin";export{g as BlendLoadPlugin};
624
+ */
625
+ async function parseBlend(buffer, name = "") {
626
+ return new Promise((res, rej) => {
627
+ return_object.onParseReady = (file, error) => {
628
+ if (error) console.error(error);
629
+ res(file);
630
+ };
631
+ return_object.loadBlendFromArrayBuffer(buffer, name);
632
+ });
633
+ }
634
+ function createCamera(object, ctx) {
635
+ const cdata = object.data;
636
+ if (!cdata) return void 0;
637
+ const type = cdata.type;
638
+ let camera;
639
+ if (type === 0) {
640
+ camera = new ctx.PerspectiveCamera(
641
+ cdata.lens || 50,
642
+ // fov or lens
643
+ (cdata.sensor_x || 36) / (cdata.sensor_y || 24),
644
+ // aspect
645
+ cdata.clipsta || 0.1,
646
+ // near
647
+ cdata.clipend || 1e3
648
+ // far
649
+ );
650
+ camera.position.set(0, 0, 0);
651
+ if ("shiftx" in cdata) camera.userData.shiftX = cdata.shiftx;
652
+ if ("shifty" in cdata) camera.userData.shiftY = cdata.shifty;
653
+ } else if (type === 1) {
654
+ const scale = cdata.ortho_scale || 1;
655
+ const aspect = (cdata.sensor_x || 36) / (cdata.sensor_y || 24);
656
+ const left = -scale * aspect / 2;
657
+ const right = scale * aspect / 2;
658
+ const top = scale / 2;
659
+ const bottom = -scale / 2;
660
+ camera = new ctx.OrthographicCamera(
661
+ left,
662
+ right,
663
+ top,
664
+ bottom,
665
+ cdata.clipsta || 0.1,
666
+ cdata.clipend || 1e3
667
+ );
668
+ camera.position.set(0, 0, 0);
669
+ if ("shiftx" in cdata) camera.userData.shiftX = cdata.shiftx;
670
+ if ("shifty" in cdata) camera.userData.shiftY = cdata.shifty;
671
+ } else {
672
+ camera = new ctx.PerspectiveCamera();
673
+ console.warn("Unsupported camera type", type);
674
+ }
675
+ return camera;
676
+ }
677
+ const blenderLightTypes = {
678
+ point: 0,
679
+ sun: 1
680
+ };
681
+ function createLight(lamp, ctx) {
682
+ const ldata = lamp.data;
683
+ const position = [lamp.loc[0], lamp.loc[2], -lamp.loc[1]];
684
+ const color = ldata.r * 255 << 16 | ldata.g * 255 << 8 | ldata.b * 255 << 0;
685
+ const intensity = ldata.energy;
686
+ const distance = 0;
687
+ let light = void 0;
688
+ switch (ldata.type) {
689
+ case blenderLightTypes.point:
690
+ light = new ctx.PointLight(color, intensity, distance);
691
+ light.position.fromArray(position, 0);
692
+ light.castShadow = true;
693
+ break;
694
+ case blenderLightTypes.sun:
695
+ light = new ctx.PointLight(color, intensity, distance);
696
+ light.position.fromArray(position, 0);
697
+ light.castShadow = true;
698
+ if (light.shadow) {
699
+ light.shadow.mapSize.width = 1024;
700
+ light.shadow.mapSize.height = 1024;
701
+ light.shadow.camera.near = 0.01;
702
+ light.shadow.camera.far = 500;
703
+ }
704
+ break;
705
+ default:
706
+ console.warn("Unsupported light type", ldata.type);
707
+ }
708
+ return light;
709
+ }
710
+ function getLayer(layers, i) {
711
+ if (!Array.isArray(layers)) return layers;
712
+ return layers[i];
713
+ }
714
+ function createBufferGeometry(meshData, ctx) {
715
+ var _a;
716
+ if (meshData.mpoly) return createBufferGeometryOld(meshData, ctx);
717
+ const geometry = new ctx.BufferGeometry();
718
+ geometry.name = meshData.aname || "";
719
+ let vertices;
720
+ let indices;
721
+ if (meshData.vdata && meshData.vdata.layers && meshData.vdata.totlayer > 0) {
722
+ for (let i = 0; i < meshData.vdata.totlayer; i++) {
723
+ const layer = getLayer(meshData.vdata.layers, i);
724
+ const data = layer.data || [];
725
+ if (data.length === meshData.totvert) {
726
+ if (vertices && (layer.name !== "position" || vertices.name === "position")) {
727
+ continue;
728
+ }
729
+ vertices = layer;
730
+ }
731
+ }
732
+ }
733
+ if (meshData.ldata && meshData.ldata.layers) {
734
+ for (let i = 0; i < meshData.ldata.totlayer; i++) {
735
+ const layer = getLayer(meshData.ldata.layers, i);
736
+ const data = layer.data || [];
737
+ if (data.length === meshData.totloop) {
738
+ if (indices && (layer.name !== ".corner_vert" || indices.name === ".corner_vert")) {
739
+ continue;
740
+ }
741
+ indices = layer;
742
+ }
743
+ }
744
+ }
745
+ let faceIndices = [];
746
+ if (meshData.poly_offset_indices && meshData.totpoly > 0) {
747
+ faceIndices = [...new Int32Array(meshData.poly_offset_indices.__blender_file__.AB, meshData.poly_offset_indices.__data_address__, meshData.totpoly + 1)];
748
+ }
749
+ if ((vertices == null ? void 0 : vertices.data) && vertices.data.length > 0) {
750
+ const positions = new Float32Array(vertices.data.length * 3);
751
+ for (let j = 0; j < vertices.data.length; j++) {
752
+ const vertex = vertices.data[j];
753
+ if (vertex.x !== void 0) {
754
+ positions[j * 3] = vertex.x;
755
+ positions[j * 3 + 1] = vertex.z;
756
+ positions[j * 3 + 2] = -vertex.y;
757
+ } else if (vertex.co !== void 0) {
758
+ positions[j * 3] = vertex.co[0];
759
+ positions[j * 3 + 1] = vertex.co[2];
760
+ positions[j * 3 + 2] = -vertex.co[1];
761
+ } else {
762
+ console.error("BlendLoader - unknown vertex", vertex);
763
+ break;
764
+ }
765
+ }
766
+ geometry.setAttribute("position", new ctx.BufferAttribute(positions, 3));
767
+ }
768
+ if ((indices == null ? void 0 : indices.data) && indices.data.length > 0 && ((_a = vertices == null ? void 0 : vertices.data) == null ? void 0 : _a.length)) {
769
+ const faceSize = meshData.totloop / meshData.totpoly;
770
+ if (faceIndices.length > 0) {
771
+ let totalTriangles = 0;
772
+ for (let i = 0; i < faceIndices.length - 1; i++) {
773
+ const faceVertCount = faceIndices[i + 1] - faceIndices[i];
774
+ totalTriangles += Math.max(0, faceVertCount - 2);
775
+ }
776
+ const indexes = new Uint32Array(totalTriangles * 3);
777
+ let t = 0;
778
+ for (let i = 0; i < faceIndices.length - 1; i++) {
779
+ const faceStart = faceIndices[i];
780
+ const faceEnd = faceIndices[i + 1];
781
+ const faceVertCount = faceEnd - faceStart;
782
+ if (faceVertCount >= 3) {
783
+ const firstVert = indices.data[faceStart].i;
784
+ for (let k = 1; k < faceVertCount - 1; k++) {
785
+ indexes[t++] = firstVert;
786
+ indexes[t++] = indices.data[faceStart + k].i;
787
+ indexes[t++] = indices.data[faceStart + k + 1].i;
788
+ }
789
+ }
790
+ }
791
+ geometry.setIndex(new ctx.BufferAttribute(indexes, 1));
792
+ } else if (faceSize === 3 || faceSize === 4) {
793
+ const isQuad = faceSize === 4;
794
+ const faceCount = indices.length / faceSize;
795
+ const indexes = new Uint32Array(faceCount * 3 * (isQuad ? 2 : 1));
796
+ if (faceSize !== 3 && faceSize !== 4) return geometry;
797
+ for (let j = 0, t = 0; j < indices.length; j += faceSize) {
798
+ const a = indices[j].i;
799
+ const b = indices[j + 1].i;
800
+ const c = indices[j + 2].i;
801
+ indexes[t++] = a;
802
+ indexes[t++] = b;
803
+ indexes[t++] = c;
804
+ if (isQuad) {
805
+ const d = indices[j + 3].i;
806
+ indexes[t++] = a;
807
+ indexes[t++] = c;
808
+ indexes[t++] = d;
809
+ }
810
+ }
811
+ geometry.setIndex(new ctx.BufferAttribute(indexes, 1));
812
+ }
813
+ } else if (faceIndices) {
814
+ console.error("BlendLoader - no indices data found, but face indices are present", faceIndices);
815
+ }
816
+ if (geometry.attributes.position && !geometry.attributes.normal)
817
+ geometry.computeVertexNormals();
818
+ return geometry;
819
+ }
820
+ function createBufferGeometryOld(mesh, ctx) {
821
+ const faces = Array.isArray(mesh.mpoly) ? mesh.mpoly : [mesh.mpoly], loops = mesh.mloop, uv = mesh.mloopuv, vertices = mesh.mvert;
822
+ const geometry = new ctx.BufferGeometry();
823
+ if (!faces) return geometry;
824
+ const size = faces.reduce((acc, face) => acc + Math.floor(face.totloop * 3 / 2), 0);
825
+ const indices = new Uint32Array(size);
826
+ const uvs = new Float32Array(size * 2);
827
+ const normals = new Float32Array(size * 3);
828
+ const positions = new Float32Array(size * 3);
829
+ let currentIndex = 0;
830
+ let computeNormals = false;
831
+ for (const face of faces) {
832
+ const len = face.totloop;
833
+ const start = face.loopstart;
834
+ let indexi = 1;
835
+ while (indexi < len) {
836
+ let index = 0;
837
+ for (let l = 0; l < 3; l++) {
838
+ index = start;
839
+ if (indexi - 1 + l < len)
840
+ index += indexi - 1 + l;
841
+ const loop = loops[index];
842
+ const vert = vertices[loop.v];
843
+ indices[currentIndex] = currentIndex;
844
+ positions[currentIndex * 3 + 0] = vert.co[0];
845
+ positions[currentIndex * 3 + 1] = vert.co[2];
846
+ positions[currentIndex * 3 + 2] = -vert.co[1];
847
+ if (vert.no) {
848
+ normals[currentIndex * 3 + 0] = vert.no[0];
849
+ normals[currentIndex * 3 + 1] = vert.no[2];
850
+ normals[currentIndex * 3 + 2] = -vert.no[1];
851
+ } else {
852
+ computeNormals = true;
853
+ }
854
+ if (uv) {
855
+ uvs[currentIndex * 2 + 0] = uv[index].uv[0];
856
+ uvs[currentIndex * 2 + 1] = uv[index].uv[1];
857
+ }
858
+ currentIndex++;
859
+ }
860
+ indexi += 2;
861
+ }
862
+ }
863
+ geometry.setAttribute("position", new ctx.BufferAttribute(positions, 3));
864
+ geometry.setIndex(new ctx.BufferAttribute(indices, 1));
865
+ geometry.setAttribute("normal", new ctx.BufferAttribute(normals, 3));
866
+ geometry.setAttribute("uv", new ctx.BufferAttribute(uvs, 2));
867
+ if (computeNormals) {
868
+ geometry.computeVertexNormals();
869
+ }
870
+ return geometry;
871
+ }
872
+ function createMaterial(mat, ctx) {
873
+ const material = new ctx.MeshPhysicalMaterial();
874
+ material.color.setRGB(mat.r, mat.g, mat.b);
875
+ material.roughness = mat.roughness !== void 0 ? mat.roughness : 0.4;
876
+ material.metalness = mat.metallic !== void 0 ? mat.metallic : 0;
877
+ material.opacity = 1;
878
+ material.transparent = material.opacity < 1;
879
+ return material;
880
+ }
881
+ function setCreateTransform(object, obj) {
882
+ obj.name = object.aname;
883
+ obj.quaternion.set(object.quat[1], object.quat[3], -object.quat[2], object.quat[0]);
884
+ obj.scale.set(object.size[0], object.size[1], object.size[2]);
885
+ obj.position.set(object.loc[0], object.loc[2], -object.loc[1]);
886
+ obj.updateMatrix();
887
+ }
888
+ function createMesh(object, loaded, ctx) {
889
+ if (!object.data) {
890
+ return void 0;
891
+ }
892
+ const geometry = loaded.get(object.data) ?? createBufferGeometry(object.data, ctx);
893
+ loaded.set(object.data, geometry);
894
+ const mat = object.data.mat[0];
895
+ const material = mat ? loaded.get(mat) ?? createMaterial(mat, ctx) : new ctx.MeshPhysicalMaterial();
896
+ if (mat) loaded.set(mat, material);
897
+ const mesh = new ctx.Mesh(geometry, material);
898
+ mesh.castShadow = true;
899
+ mesh.receiveShadow = true;
900
+ return mesh;
901
+ }
902
+ const blenderObjectTypes = {
903
+ empty: 0,
904
+ mesh: 1,
905
+ lamp: 10,
906
+ camera: 11
907
+ };
908
+ async function createObjects(file, ctx) {
909
+ const objects = [];
910
+ const childMap = /* @__PURE__ */ new Map();
911
+ const objMap = /* @__PURE__ */ new Map();
912
+ const blendObjects = file.objects.Object ?? [];
913
+ const loaded = /* @__PURE__ */ new WeakMap();
914
+ for (const object of blendObjects) {
915
+ if (loaded.has(object)) {
916
+ console.warn("BlendLoader - duplicate object");
917
+ continue;
918
+ }
919
+ let obj = void 0;
920
+ switch (object.type) {
921
+ case blenderObjectTypes.empty:
922
+ obj = new ctx.Object3D();
923
+ break;
924
+ case blenderObjectTypes.mesh:
925
+ obj = createMesh(object, loaded, ctx);
926
+ break;
927
+ case blenderObjectTypes.lamp:
928
+ obj = createLight(object, ctx);
929
+ break;
930
+ case blenderObjectTypes.camera:
931
+ obj = createCamera(object, ctx);
932
+ break;
933
+ default:
934
+ obj = new ctx.Object3D();
935
+ console.warn("Unsupported object type", object.type, object, obj);
936
+ }
937
+ if (obj) {
938
+ setCreateTransform(object, obj);
939
+ const exChildren = childMap.get(object);
940
+ if (exChildren) {
941
+ for (const exChild of exChildren) {
942
+ obj.add(exChild);
943
+ }
944
+ childMap.delete(object);
945
+ }
946
+ objMap.set(object, obj);
947
+ if (object.parent === object) {
948
+ console.error("invalid, parent same as object, adding to root", object);
949
+ objects.push(obj);
950
+ } else if (!object.parent) {
951
+ objects.push(obj);
952
+ } else {
953
+ const parent = objMap.get(object.parent);
954
+ if (!parent) {
955
+ const chi = childMap.get(object.parent) ?? [];
956
+ chi.push(obj);
957
+ childMap.set(object, chi);
958
+ } else {
959
+ parent.add(obj);
960
+ }
961
+ }
962
+ loaded.set(object, obj);
963
+ }
964
+ }
965
+ if (childMap.size) {
966
+ const vals = [...childMap.values()].flat();
967
+ console.warn("unknown objects with parents, adding to root", vals, childMap);
968
+ objects.push(...vals);
969
+ }
970
+ return objects.filter((o) => !!o);
971
+ }
972
+ const _BlendLoadPlugin = class _BlendLoadPlugin extends BaseImporterPlugin {
973
+ constructor() {
974
+ super();
975
+ this._importer = new Importer(class extends FileLoader {
976
+ async loadAsync(url, onProgress) {
977
+ this.setResponseType("arraybuffer");
978
+ const res = await super.loadAsync(url, onProgress);
979
+ const blend = await parseBlend(res);
980
+ const ctx = {
981
+ Object3D: Object3D2,
982
+ Mesh: Mesh2,
983
+ MeshPhysicalMaterial: PhysicalMaterial,
984
+ PerspectiveCamera: PerspectiveCamera0,
985
+ OrthographicCamera: OrthographicCamera0,
986
+ PointLight: PointLight2,
987
+ BufferGeometry: BufferGeometry2,
988
+ BufferAttribute
989
+ };
990
+ const objects = await createObjects(blend, ctx);
991
+ const root = new Object3D();
992
+ root.add(...objects);
993
+ blend.scene = root;
994
+ return blend;
995
+ }
996
+ transform(res, options) {
997
+ if (typeof options.onBlendLoad === "function") {
998
+ options.onBlendLoad(res);
999
+ }
1000
+ return res.scene;
1001
+ }
1002
+ }, ["blend"], ["application/x-blender"], true);
1003
+ }
1004
+ };
1005
+ _BlendLoadPlugin.PluginType = "BlendLoadPlugin";
1006
+ let BlendLoadPlugin = _BlendLoadPlugin;
1007
+ export {
1008
+ BlendLoadPlugin
1009
+ };
18
1010
  //# sourceMappingURL=index.mjs.map