@needle-tools/three 0.162.10 → 0.162.12

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.
@@ -14,6 +14,7 @@ import {
14
14
  Vector3,
15
15
  Color
16
16
  } from 'three';
17
+ import { MTLLoader } from './MTLLoader.js';
17
18
 
18
19
  // o object_name | g group_name
19
20
  const _object_pattern = /^[og]\s*(.+)?/;
@@ -440,6 +441,7 @@ class OBJLoader extends Loader {
440
441
  super( manager );
441
442
 
442
443
  this.materials = null;
444
+ this.materialsLoader = new MTLLoader( manager );
443
445
 
444
446
  }
445
447
 
@@ -451,11 +453,35 @@ class OBJLoader extends Loader {
451
453
  loader.setPath( this.path );
452
454
  loader.setRequestHeader( this.requestHeader );
453
455
  loader.setWithCredentials( this.withCredentials );
454
- loader.load( url, function ( text ) {
456
+ loader.load( url, async function ( text ) {
455
457
 
456
458
  try {
457
459
 
458
- onLoad( scope.parse( text ) );
460
+ const state = scope.parse( text, true );
461
+
462
+
463
+ for ( let i = 0, l = state.materialLibraries.length; i < l; i ++ ) {
464
+
465
+ const mtlfile = state.materialLibraries[ i ];
466
+
467
+ const newUrl = url.startsWith("blob:")
468
+ ? (url + "/" + mtlfile)
469
+ : new URL(mtlfile, url);
470
+
471
+ console.debug( 'Loading MTL file: ' + newUrl );
472
+
473
+ await (new Promise((resolve, reject) => {
474
+ scope.materialsLoader.load( newUrl.toString(), creator => {
475
+
476
+ scope.setMaterials( creator );
477
+ resolve();
478
+
479
+ }, null, reject );
480
+ }));
481
+
482
+ }
483
+
484
+ onLoad( scope.createObjects( state ) );
459
485
 
460
486
  } catch ( e ) {
461
487
 
@@ -477,6 +503,14 @@ class OBJLoader extends Loader {
477
503
 
478
504
  }
479
505
 
506
+ setMTLLoader ( loader ) {
507
+
508
+ this.materialsLoader = loader;
509
+
510
+ return this;
511
+
512
+ }
513
+
480
514
  setMaterials( materials ) {
481
515
 
482
516
  this.materials = materials;
@@ -485,7 +519,7 @@ class OBJLoader extends Loader {
485
519
 
486
520
  }
487
521
 
488
- parse( text ) {
522
+ parse( text, parseOnly = false ) {
489
523
 
490
524
  const state = new ParserState();
491
525
 
@@ -715,6 +749,16 @@ class OBJLoader extends Loader {
715
749
 
716
750
  state.finalize();
717
751
 
752
+ // If the method is called from the load() function we do first load materials before creating the objects
753
+ // This is to not modify the functionality of parse() e.g. by making it async
754
+ if ( parseOnly ) return state;
755
+
756
+ return this.createObjects(state);
757
+ }
758
+
759
+
760
+ createObjects ( state ) {
761
+
718
762
  const container = new Group();
719
763
  container.materialLibraries = [].concat( state.materialLibraries );
720
764
 
@@ -897,9 +941,7 @@ class OBJLoader extends Loader {
897
941
  }
898
942
 
899
943
  return container;
900
-
901
944
  }
902
-
903
945
  }
904
946
 
905
947
  export { OBJLoader };
@@ -0,0 +1,832 @@
1
+ import {
2
+ BufferGeometry,
3
+ Color,
4
+ DefaultLoadingManager,
5
+ FileLoader,
6
+ Float32BufferAttribute,
7
+ FrontSide,
8
+ Group,
9
+ LineBasicMaterial,
10
+ LineSegments,
11
+ Loader,
12
+ LoaderUtils,
13
+ Material,
14
+ Mesh,
15
+ MeshPhongMaterial,
16
+ Points,
17
+ PointsMaterial,
18
+ RepeatWrapping,
19
+ SRGBColorSpace,
20
+ TextureLoader,
21
+ Vector2,
22
+ Vector3
23
+ } from "/node_modules/.vite/deps/chunk-VUIPKYI2.js?v=df97e3aa";
24
+ import "/node_modules/.vite/deps/chunk-2TUXWMP5.js?v=df97e3aa";
25
+
26
+ // ../../needle-engine-dev/modules/needle-engine/js/package~/node_modules/three/examples/jsm/loaders/MTLLoader.js
27
+ var MTLLoader = class extends Loader {
28
+ constructor(manager) {
29
+ super(manager);
30
+ }
31
+ /**
32
+ * Loads and parses a MTL asset from a URL.
33
+ *
34
+ * @param {String} url - URL to the MTL file.
35
+ * @param {Function} [onLoad] - Callback invoked with the loaded object.
36
+ * @param {Function} [onProgress] - Callback for download progress.
37
+ * @param {Function} [onError] - Callback for download errors.
38
+ *
39
+ * @see setPath setResourcePath
40
+ *
41
+ * @note In order for relative texture references to resolve correctly
42
+ * you must call setResourcePath() explicitly prior to load.
43
+ */
44
+ load(url, onLoad, onProgress, onError) {
45
+ const scope = this;
46
+ const path = this.path === "" ? LoaderUtils.extractUrlBase(url) : this.path;
47
+ const loader = new FileLoader(this.manager);
48
+ loader.setPath(this.path);
49
+ loader.setRequestHeader(this.requestHeader);
50
+ loader.setWithCredentials(this.withCredentials);
51
+ loader.load(url, function(text) {
52
+ try {
53
+ onLoad(scope.parse(text, path));
54
+ } catch (e) {
55
+ if (onError) {
56
+ onError(e);
57
+ } else {
58
+ console.error(e);
59
+ }
60
+ scope.manager.itemError(url);
61
+ }
62
+ }, onProgress, onError);
63
+ }
64
+ setMaterialOptions(value) {
65
+ this.materialOptions = value;
66
+ return this;
67
+ }
68
+ /**
69
+ * Parses a MTL file.
70
+ *
71
+ * @param {String} text - Content of MTL file
72
+ * @return {MaterialCreator}
73
+ *
74
+ * @see setPath setResourcePath
75
+ *
76
+ * @note In order for relative texture references to resolve correctly
77
+ * you must call setResourcePath() explicitly prior to parse.
78
+ */
79
+ parse(text, path) {
80
+ const lines = text.split("\n");
81
+ let info = {};
82
+ const delimiter_pattern = /\s+/;
83
+ const materialsInfo = {};
84
+ for (let i = 0; i < lines.length; i++) {
85
+ let line = lines[i];
86
+ line = line.trim();
87
+ if (line.length === 0 || line.charAt(0) === "#") {
88
+ continue;
89
+ }
90
+ const pos = line.indexOf(" ");
91
+ let key = pos >= 0 ? line.substring(0, pos) : line;
92
+ key = key.toLowerCase();
93
+ let value = pos >= 0 ? line.substring(pos + 1) : "";
94
+ value = value.trim();
95
+ if (key === "newmtl") {
96
+ info = { name: value };
97
+ materialsInfo[value] = info;
98
+ } else {
99
+ if (key === "ka" || key === "kd" || key === "ks" || key === "ke") {
100
+ const ss = value.split(delimiter_pattern, 3);
101
+ info[key] = [parseFloat(ss[0]), parseFloat(ss[1]), parseFloat(ss[2])];
102
+ } else {
103
+ info[key] = value;
104
+ }
105
+ }
106
+ }
107
+ const materialCreator = new MaterialCreator(this.resourcePath || path, this.materialOptions);
108
+ materialCreator.setCrossOrigin(this.crossOrigin);
109
+ materialCreator.setManager(this.manager);
110
+ materialCreator.setMaterials(materialsInfo);
111
+ return materialCreator;
112
+ }
113
+ };
114
+ var MaterialCreator = class {
115
+ constructor(baseUrl = "", options = {}) {
116
+ this.baseUrl = baseUrl;
117
+ this.options = options;
118
+ this.materialsInfo = {};
119
+ this.materials = {};
120
+ this.materialsArray = [];
121
+ this.nameLookup = {};
122
+ this.crossOrigin = "anonymous";
123
+ this.side = this.options.side !== void 0 ? this.options.side : FrontSide;
124
+ this.wrap = this.options.wrap !== void 0 ? this.options.wrap : RepeatWrapping;
125
+ }
126
+ setCrossOrigin(value) {
127
+ this.crossOrigin = value;
128
+ return this;
129
+ }
130
+ setManager(value) {
131
+ this.manager = value;
132
+ }
133
+ setMaterials(materialsInfo) {
134
+ this.materialsInfo = this.convert(materialsInfo);
135
+ this.materials = {};
136
+ this.materialsArray = [];
137
+ this.nameLookup = {};
138
+ }
139
+ convert(materialsInfo) {
140
+ if (!this.options) return materialsInfo;
141
+ const converted = {};
142
+ for (const mn in materialsInfo) {
143
+ const mat = materialsInfo[mn];
144
+ const covmat = {};
145
+ converted[mn] = covmat;
146
+ for (const prop in mat) {
147
+ let save = true;
148
+ let value = mat[prop];
149
+ const lprop = prop.toLowerCase();
150
+ switch (lprop) {
151
+ case "kd":
152
+ case "ka":
153
+ case "ks":
154
+ if (this.options && this.options.normalizeRGB) {
155
+ value = [value[0] / 255, value[1] / 255, value[2] / 255];
156
+ }
157
+ if (this.options && this.options.ignoreZeroRGBs) {
158
+ if (value[0] === 0 && value[1] === 0 && value[2] === 0) {
159
+ save = false;
160
+ }
161
+ }
162
+ break;
163
+ default:
164
+ break;
165
+ }
166
+ if (save) {
167
+ covmat[lprop] = value;
168
+ }
169
+ }
170
+ }
171
+ return converted;
172
+ }
173
+ preload() {
174
+ for (const mn in this.materialsInfo) {
175
+ this.create(mn);
176
+ }
177
+ }
178
+ getIndex(materialName) {
179
+ return this.nameLookup[materialName];
180
+ }
181
+ getAsArray() {
182
+ let index = 0;
183
+ for (const mn in this.materialsInfo) {
184
+ this.materialsArray[index] = this.create(mn);
185
+ this.nameLookup[mn] = index;
186
+ index++;
187
+ }
188
+ return this.materialsArray;
189
+ }
190
+ create(materialName) {
191
+ if (this.materials[materialName] === void 0) {
192
+ this.createMaterial_(materialName);
193
+ }
194
+ return this.materials[materialName];
195
+ }
196
+ createMaterial_(materialName) {
197
+ const scope = this;
198
+ const mat = this.materialsInfo[materialName];
199
+ const params = {
200
+ name: materialName,
201
+ side: this.side
202
+ };
203
+ function resolveURL(baseUrl, url) {
204
+ if (typeof url !== "string" || url === "")
205
+ return "";
206
+ if (/^https?:\/\//i.test(url)) return url;
207
+ return baseUrl + url;
208
+ }
209
+ function setMapForType(mapType, value) {
210
+ if (params[mapType]) return;
211
+ const texParams = scope.getTextureParams(value, params);
212
+ const map = scope.loadTexture(resolveURL(scope.baseUrl, texParams.url));
213
+ map.repeat.copy(texParams.scale);
214
+ map.offset.copy(texParams.offset);
215
+ map.wrapS = scope.wrap;
216
+ map.wrapT = scope.wrap;
217
+ if (mapType === "map" || mapType === "emissiveMap") {
218
+ map.colorSpace = SRGBColorSpace;
219
+ }
220
+ params[mapType] = map;
221
+ }
222
+ for (const prop in mat) {
223
+ const value = mat[prop];
224
+ let n;
225
+ if (value === "") continue;
226
+ switch (prop.toLowerCase()) {
227
+ case "kd":
228
+ params.color = new Color().fromArray(value).convertSRGBToLinear();
229
+ break;
230
+ case "ks":
231
+ params.specular = new Color().fromArray(value).convertSRGBToLinear();
232
+ break;
233
+ case "ke":
234
+ params.emissive = new Color().fromArray(value).convertSRGBToLinear();
235
+ break;
236
+ case "map_kd":
237
+ setMapForType("map", value);
238
+ break;
239
+ case "map_ks":
240
+ setMapForType("specularMap", value);
241
+ break;
242
+ case "map_ke":
243
+ setMapForType("emissiveMap", value);
244
+ break;
245
+ case "norm":
246
+ setMapForType("normalMap", value);
247
+ break;
248
+ case "map_bump":
249
+ case "bump":
250
+ setMapForType("bumpMap", value);
251
+ break;
252
+ case "map_d":
253
+ setMapForType("alphaMap", value);
254
+ params.transparent = true;
255
+ break;
256
+ case "ns":
257
+ params.shininess = parseFloat(value);
258
+ break;
259
+ case "d":
260
+ n = parseFloat(value);
261
+ if (n < 1) {
262
+ params.opacity = n;
263
+ params.transparent = true;
264
+ }
265
+ break;
266
+ case "tr":
267
+ n = parseFloat(value);
268
+ if (this.options && this.options.invertTrProperty) n = 1 - n;
269
+ if (n > 0) {
270
+ params.opacity = 1 - n;
271
+ params.transparent = true;
272
+ }
273
+ break;
274
+ default:
275
+ break;
276
+ }
277
+ }
278
+ this.materials[materialName] = new MeshPhongMaterial(params);
279
+ return this.materials[materialName];
280
+ }
281
+ getTextureParams(value, matParams) {
282
+ const texParams = {
283
+ scale: new Vector2(1, 1),
284
+ offset: new Vector2(0, 0)
285
+ };
286
+ const items = value.split(/\s+/);
287
+ let pos;
288
+ pos = items.indexOf("-bm");
289
+ if (pos >= 0) {
290
+ matParams.bumpScale = parseFloat(items[pos + 1]);
291
+ items.splice(pos, 2);
292
+ }
293
+ pos = items.indexOf("-s");
294
+ if (pos >= 0) {
295
+ texParams.scale.set(parseFloat(items[pos + 1]), parseFloat(items[pos + 2]));
296
+ items.splice(pos, 4);
297
+ }
298
+ pos = items.indexOf("-o");
299
+ if (pos >= 0) {
300
+ texParams.offset.set(parseFloat(items[pos + 1]), parseFloat(items[pos + 2]));
301
+ items.splice(pos, 4);
302
+ }
303
+ texParams.url = items.join(" ").trim();
304
+ return texParams;
305
+ }
306
+ loadTexture(url, mapping, onLoad, onProgress, onError) {
307
+ const manager = this.manager !== void 0 ? this.manager : DefaultLoadingManager;
308
+ let loader = manager.getHandler(url);
309
+ if (loader === null) {
310
+ loader = new TextureLoader(manager);
311
+ }
312
+ if (loader.setCrossOrigin) loader.setCrossOrigin(this.crossOrigin);
313
+ const texture = loader.load(url, onLoad, onProgress, onError);
314
+ if (mapping !== void 0) texture.mapping = mapping;
315
+ return texture;
316
+ }
317
+ };
318
+
319
+ // ../../needle-engine-dev/modules/needle-engine/js/package~/node_modules/three/examples/jsm/loaders/OBJLoader.js
320
+ var _object_pattern = /^[og]\s*(.+)?/;
321
+ var _material_library_pattern = /^mtllib /;
322
+ var _material_use_pattern = /^usemtl /;
323
+ var _map_use_pattern = /^usemap /;
324
+ var _face_vertex_data_separator_pattern = /\s+/;
325
+ var _vA = new Vector3();
326
+ var _vB = new Vector3();
327
+ var _vC = new Vector3();
328
+ var _ab = new Vector3();
329
+ var _cb = new Vector3();
330
+ var _color = new Color();
331
+ function ParserState() {
332
+ const state = {
333
+ objects: [],
334
+ object: {},
335
+ vertices: [],
336
+ normals: [],
337
+ colors: [],
338
+ uvs: [],
339
+ materials: {},
340
+ materialLibraries: [],
341
+ startObject: function(name, fromDeclaration) {
342
+ if (this.object && this.object.fromDeclaration === false) {
343
+ this.object.name = name;
344
+ this.object.fromDeclaration = fromDeclaration !== false;
345
+ return;
346
+ }
347
+ const previousMaterial = this.object && typeof this.object.currentMaterial === "function" ? this.object.currentMaterial() : void 0;
348
+ if (this.object && typeof this.object._finalize === "function") {
349
+ this.object._finalize(true);
350
+ }
351
+ this.object = {
352
+ name: name || "",
353
+ fromDeclaration: fromDeclaration !== false,
354
+ geometry: {
355
+ vertices: [],
356
+ normals: [],
357
+ colors: [],
358
+ uvs: [],
359
+ hasUVIndices: false
360
+ },
361
+ materials: [],
362
+ smooth: true,
363
+ startMaterial: function(name2, libraries) {
364
+ const previous = this._finalize(false);
365
+ if (previous && (previous.inherited || previous.groupCount <= 0)) {
366
+ this.materials.splice(previous.index, 1);
367
+ }
368
+ const material = {
369
+ index: this.materials.length,
370
+ name: name2 || "",
371
+ mtllib: Array.isArray(libraries) && libraries.length > 0 ? libraries[libraries.length - 1] : "",
372
+ smooth: previous !== void 0 ? previous.smooth : this.smooth,
373
+ groupStart: previous !== void 0 ? previous.groupEnd : 0,
374
+ groupEnd: -1,
375
+ groupCount: -1,
376
+ inherited: false,
377
+ clone: function(index) {
378
+ const cloned = {
379
+ index: typeof index === "number" ? index : this.index,
380
+ name: this.name,
381
+ mtllib: this.mtllib,
382
+ smooth: this.smooth,
383
+ groupStart: 0,
384
+ groupEnd: -1,
385
+ groupCount: -1,
386
+ inherited: false
387
+ };
388
+ cloned.clone = this.clone.bind(cloned);
389
+ return cloned;
390
+ }
391
+ };
392
+ this.materials.push(material);
393
+ return material;
394
+ },
395
+ currentMaterial: function() {
396
+ if (this.materials.length > 0) {
397
+ return this.materials[this.materials.length - 1];
398
+ }
399
+ return void 0;
400
+ },
401
+ _finalize: function(end) {
402
+ const lastMultiMaterial = this.currentMaterial();
403
+ if (lastMultiMaterial && lastMultiMaterial.groupEnd === -1) {
404
+ lastMultiMaterial.groupEnd = this.geometry.vertices.length / 3;
405
+ lastMultiMaterial.groupCount = lastMultiMaterial.groupEnd - lastMultiMaterial.groupStart;
406
+ lastMultiMaterial.inherited = false;
407
+ }
408
+ if (end && this.materials.length > 1) {
409
+ for (let mi = this.materials.length - 1; mi >= 0; mi--) {
410
+ if (this.materials[mi].groupCount <= 0) {
411
+ this.materials.splice(mi, 1);
412
+ }
413
+ }
414
+ }
415
+ if (end && this.materials.length === 0) {
416
+ this.materials.push({
417
+ name: "",
418
+ smooth: this.smooth
419
+ });
420
+ }
421
+ return lastMultiMaterial;
422
+ }
423
+ };
424
+ if (previousMaterial && previousMaterial.name && typeof previousMaterial.clone === "function") {
425
+ const declared = previousMaterial.clone(0);
426
+ declared.inherited = true;
427
+ this.object.materials.push(declared);
428
+ }
429
+ this.objects.push(this.object);
430
+ },
431
+ finalize: function() {
432
+ if (this.object && typeof this.object._finalize === "function") {
433
+ this.object._finalize(true);
434
+ }
435
+ },
436
+ parseVertexIndex: function(value, len) {
437
+ const index = parseInt(value, 10);
438
+ return (index >= 0 ? index - 1 : index + len / 3) * 3;
439
+ },
440
+ parseNormalIndex: function(value, len) {
441
+ const index = parseInt(value, 10);
442
+ return (index >= 0 ? index - 1 : index + len / 3) * 3;
443
+ },
444
+ parseUVIndex: function(value, len) {
445
+ const index = parseInt(value, 10);
446
+ return (index >= 0 ? index - 1 : index + len / 2) * 2;
447
+ },
448
+ addVertex: function(a, b, c) {
449
+ const src = this.vertices;
450
+ const dst = this.object.geometry.vertices;
451
+ dst.push(src[a + 0], src[a + 1], src[a + 2]);
452
+ dst.push(src[b + 0], src[b + 1], src[b + 2]);
453
+ dst.push(src[c + 0], src[c + 1], src[c + 2]);
454
+ },
455
+ addVertexPoint: function(a) {
456
+ const src = this.vertices;
457
+ const dst = this.object.geometry.vertices;
458
+ dst.push(src[a + 0], src[a + 1], src[a + 2]);
459
+ },
460
+ addVertexLine: function(a) {
461
+ const src = this.vertices;
462
+ const dst = this.object.geometry.vertices;
463
+ dst.push(src[a + 0], src[a + 1], src[a + 2]);
464
+ },
465
+ addNormal: function(a, b, c) {
466
+ const src = this.normals;
467
+ const dst = this.object.geometry.normals;
468
+ dst.push(src[a + 0], src[a + 1], src[a + 2]);
469
+ dst.push(src[b + 0], src[b + 1], src[b + 2]);
470
+ dst.push(src[c + 0], src[c + 1], src[c + 2]);
471
+ },
472
+ addFaceNormal: function(a, b, c) {
473
+ const src = this.vertices;
474
+ const dst = this.object.geometry.normals;
475
+ _vA.fromArray(src, a);
476
+ _vB.fromArray(src, b);
477
+ _vC.fromArray(src, c);
478
+ _cb.subVectors(_vC, _vB);
479
+ _ab.subVectors(_vA, _vB);
480
+ _cb.cross(_ab);
481
+ _cb.normalize();
482
+ dst.push(_cb.x, _cb.y, _cb.z);
483
+ dst.push(_cb.x, _cb.y, _cb.z);
484
+ dst.push(_cb.x, _cb.y, _cb.z);
485
+ },
486
+ addColor: function(a, b, c) {
487
+ const src = this.colors;
488
+ const dst = this.object.geometry.colors;
489
+ if (src[a] !== void 0) dst.push(src[a + 0], src[a + 1], src[a + 2]);
490
+ if (src[b] !== void 0) dst.push(src[b + 0], src[b + 1], src[b + 2]);
491
+ if (src[c] !== void 0) dst.push(src[c + 0], src[c + 1], src[c + 2]);
492
+ },
493
+ addUV: function(a, b, c) {
494
+ const src = this.uvs;
495
+ const dst = this.object.geometry.uvs;
496
+ dst.push(src[a + 0], src[a + 1]);
497
+ dst.push(src[b + 0], src[b + 1]);
498
+ dst.push(src[c + 0], src[c + 1]);
499
+ },
500
+ addDefaultUV: function() {
501
+ const dst = this.object.geometry.uvs;
502
+ dst.push(0, 0);
503
+ dst.push(0, 0);
504
+ dst.push(0, 0);
505
+ },
506
+ addUVLine: function(a) {
507
+ const src = this.uvs;
508
+ const dst = this.object.geometry.uvs;
509
+ dst.push(src[a + 0], src[a + 1]);
510
+ },
511
+ addFace: function(a, b, c, ua, ub, uc, na, nb, nc) {
512
+ const vLen = this.vertices.length;
513
+ let ia = this.parseVertexIndex(a, vLen);
514
+ let ib = this.parseVertexIndex(b, vLen);
515
+ let ic = this.parseVertexIndex(c, vLen);
516
+ this.addVertex(ia, ib, ic);
517
+ this.addColor(ia, ib, ic);
518
+ if (na !== void 0 && na !== "") {
519
+ const nLen = this.normals.length;
520
+ ia = this.parseNormalIndex(na, nLen);
521
+ ib = this.parseNormalIndex(nb, nLen);
522
+ ic = this.parseNormalIndex(nc, nLen);
523
+ this.addNormal(ia, ib, ic);
524
+ } else {
525
+ this.addFaceNormal(ia, ib, ic);
526
+ }
527
+ if (ua !== void 0 && ua !== "") {
528
+ const uvLen = this.uvs.length;
529
+ ia = this.parseUVIndex(ua, uvLen);
530
+ ib = this.parseUVIndex(ub, uvLen);
531
+ ic = this.parseUVIndex(uc, uvLen);
532
+ this.addUV(ia, ib, ic);
533
+ this.object.geometry.hasUVIndices = true;
534
+ } else {
535
+ this.addDefaultUV();
536
+ }
537
+ },
538
+ addPointGeometry: function(vertices) {
539
+ this.object.geometry.type = "Points";
540
+ const vLen = this.vertices.length;
541
+ for (let vi = 0, l = vertices.length; vi < l; vi++) {
542
+ const index = this.parseVertexIndex(vertices[vi], vLen);
543
+ this.addVertexPoint(index);
544
+ this.addColor(index);
545
+ }
546
+ },
547
+ addLineGeometry: function(vertices, uvs) {
548
+ this.object.geometry.type = "Line";
549
+ const vLen = this.vertices.length;
550
+ const uvLen = this.uvs.length;
551
+ for (let vi = 0, l = vertices.length; vi < l; vi++) {
552
+ this.addVertexLine(this.parseVertexIndex(vertices[vi], vLen));
553
+ }
554
+ for (let uvi = 0, l = uvs.length; uvi < l; uvi++) {
555
+ this.addUVLine(this.parseUVIndex(uvs[uvi], uvLen));
556
+ }
557
+ }
558
+ };
559
+ state.startObject("", false);
560
+ return state;
561
+ }
562
+ var OBJLoader = class extends Loader {
563
+ constructor(manager) {
564
+ super(manager);
565
+ this.materials = null;
566
+ this.materialsLoader = new MTLLoader(manager);
567
+ }
568
+ load(url, onLoad, onProgress, onError) {
569
+ const scope = this;
570
+ const loader = new FileLoader(this.manager);
571
+ loader.setPath(this.path);
572
+ loader.setRequestHeader(this.requestHeader);
573
+ loader.setWithCredentials(this.withCredentials);
574
+ loader.load(url, async function(text) {
575
+ try {
576
+ const state = scope.parse(text, true);
577
+ for (let i = 0, l = state.materialLibraries.length; i < l; i++) {
578
+ const mtlfile = state.materialLibraries[i];
579
+ const newUrl = new URL(mtlfile, url);
580
+ await new Promise((resolve, reject) => {
581
+ scope.materialsLoader.load(newUrl.toString(), (creator) => {
582
+ scope.setMaterials(creator);
583
+ resolve();
584
+ }, null, reject);
585
+ });
586
+ }
587
+ onLoad(scope.createObjects(state));
588
+ } catch (e) {
589
+ if (onError) {
590
+ onError(e);
591
+ } else {
592
+ console.error(e);
593
+ }
594
+ scope.manager.itemError(url);
595
+ }
596
+ }, onProgress, onError);
597
+ }
598
+ setMTLLoader(loader) {
599
+ this.materialsLoader = loader;
600
+ return this;
601
+ }
602
+ setMaterials(materials) {
603
+ this.materials = materials;
604
+ return this;
605
+ }
606
+ parse(text, parseOnly = false) {
607
+ const state = new ParserState();
608
+ if (text.indexOf("\r\n") !== -1) {
609
+ text = text.replace(/\r\n/g, "\n");
610
+ }
611
+ if (text.indexOf("\\\n") !== -1) {
612
+ text = text.replace(/\\\n/g, "");
613
+ }
614
+ const lines = text.split("\n");
615
+ let result = [];
616
+ for (let i = 0, l = lines.length; i < l; i++) {
617
+ const line = lines[i].trimStart();
618
+ if (line.length === 0) continue;
619
+ const lineFirstChar = line.charAt(0);
620
+ if (lineFirstChar === "#") continue;
621
+ if (lineFirstChar === "v") {
622
+ const data = line.split(_face_vertex_data_separator_pattern);
623
+ switch (data[0]) {
624
+ case "v":
625
+ state.vertices.push(
626
+ parseFloat(data[1]),
627
+ parseFloat(data[2]),
628
+ parseFloat(data[3])
629
+ );
630
+ if (data.length >= 7) {
631
+ _color.setRGB(
632
+ parseFloat(data[4]),
633
+ parseFloat(data[5]),
634
+ parseFloat(data[6])
635
+ ).convertSRGBToLinear();
636
+ state.colors.push(_color.r, _color.g, _color.b);
637
+ } else {
638
+ state.colors.push(void 0, void 0, void 0);
639
+ }
640
+ break;
641
+ case "vn":
642
+ state.normals.push(
643
+ parseFloat(data[1]),
644
+ parseFloat(data[2]),
645
+ parseFloat(data[3])
646
+ );
647
+ break;
648
+ case "vt":
649
+ state.uvs.push(
650
+ parseFloat(data[1]),
651
+ parseFloat(data[2])
652
+ );
653
+ break;
654
+ }
655
+ } else if (lineFirstChar === "f") {
656
+ const lineData = line.slice(1).trim();
657
+ const vertexData = lineData.split(_face_vertex_data_separator_pattern);
658
+ const faceVertices = [];
659
+ for (let j = 0, jl = vertexData.length; j < jl; j++) {
660
+ const vertex = vertexData[j];
661
+ if (vertex.length > 0) {
662
+ const vertexParts = vertex.split("/");
663
+ faceVertices.push(vertexParts);
664
+ }
665
+ }
666
+ const v1 = faceVertices[0];
667
+ for (let j = 1, jl = faceVertices.length - 1; j < jl; j++) {
668
+ const v2 = faceVertices[j];
669
+ const v3 = faceVertices[j + 1];
670
+ state.addFace(
671
+ v1[0],
672
+ v2[0],
673
+ v3[0],
674
+ v1[1],
675
+ v2[1],
676
+ v3[1],
677
+ v1[2],
678
+ v2[2],
679
+ v3[2]
680
+ );
681
+ }
682
+ } else if (lineFirstChar === "l") {
683
+ const lineParts = line.substring(1).trim().split(" ");
684
+ let lineVertices = [];
685
+ const lineUVs = [];
686
+ if (line.indexOf("/") === -1) {
687
+ lineVertices = lineParts;
688
+ } else {
689
+ for (let li = 0, llen = lineParts.length; li < llen; li++) {
690
+ const parts = lineParts[li].split("/");
691
+ if (parts[0] !== "") lineVertices.push(parts[0]);
692
+ if (parts[1] !== "") lineUVs.push(parts[1]);
693
+ }
694
+ }
695
+ state.addLineGeometry(lineVertices, lineUVs);
696
+ } else if (lineFirstChar === "p") {
697
+ const lineData = line.slice(1).trim();
698
+ const pointData = lineData.split(" ");
699
+ state.addPointGeometry(pointData);
700
+ } else if ((result = _object_pattern.exec(line)) !== null) {
701
+ const name = (" " + result[0].slice(1).trim()).slice(1);
702
+ state.startObject(name);
703
+ } else if (_material_use_pattern.test(line)) {
704
+ state.object.startMaterial(line.substring(7).trim(), state.materialLibraries);
705
+ } else if (_material_library_pattern.test(line)) {
706
+ state.materialLibraries.push(line.substring(7).trim());
707
+ } else if (_map_use_pattern.test(line)) {
708
+ console.warn('THREE.OBJLoader: Rendering identifier "usemap" not supported. Textures must be defined in MTL files.');
709
+ } else if (lineFirstChar === "s") {
710
+ result = line.split(" ");
711
+ if (result.length > 1) {
712
+ const value = result[1].trim().toLowerCase();
713
+ state.object.smooth = value !== "0" && value !== "off";
714
+ } else {
715
+ state.object.smooth = true;
716
+ }
717
+ const material = state.object.currentMaterial();
718
+ if (material) material.smooth = state.object.smooth;
719
+ } else {
720
+ if (line === "\0") continue;
721
+ console.warn('THREE.OBJLoader: Unexpected line: "' + line + '"');
722
+ }
723
+ }
724
+ state.finalize();
725
+ if (parseOnly) return state;
726
+ return this.createObjects(state);
727
+ }
728
+ createObjects(state) {
729
+ const container = new Group();
730
+ container.materialLibraries = [].concat(state.materialLibraries);
731
+ const hasPrimitives = !(state.objects.length === 1 && state.objects[0].geometry.vertices.length === 0);
732
+ if (hasPrimitives === true) {
733
+ for (let i = 0, l = state.objects.length; i < l; i++) {
734
+ const object = state.objects[i];
735
+ const geometry = object.geometry;
736
+ const materials = object.materials;
737
+ const isLine = geometry.type === "Line";
738
+ const isPoints = geometry.type === "Points";
739
+ let hasVertexColors = false;
740
+ if (geometry.vertices.length === 0) continue;
741
+ const buffergeometry = new BufferGeometry();
742
+ buffergeometry.setAttribute("position", new Float32BufferAttribute(geometry.vertices, 3));
743
+ if (geometry.normals.length > 0) {
744
+ buffergeometry.setAttribute("normal", new Float32BufferAttribute(geometry.normals, 3));
745
+ }
746
+ if (geometry.colors.length > 0) {
747
+ hasVertexColors = true;
748
+ buffergeometry.setAttribute("color", new Float32BufferAttribute(geometry.colors, 3));
749
+ }
750
+ if (geometry.hasUVIndices === true) {
751
+ buffergeometry.setAttribute("uv", new Float32BufferAttribute(geometry.uvs, 2));
752
+ }
753
+ const createdMaterials = [];
754
+ for (let mi = 0, miLen = materials.length; mi < miLen; mi++) {
755
+ const sourceMaterial = materials[mi];
756
+ const materialHash = sourceMaterial.name + "_" + sourceMaterial.smooth + "_" + hasVertexColors;
757
+ let material = state.materials[materialHash];
758
+ if (this.materials !== null) {
759
+ material = this.materials.create(sourceMaterial.name);
760
+ if (isLine && material && !(material instanceof LineBasicMaterial)) {
761
+ const materialLine = new LineBasicMaterial();
762
+ Material.prototype.copy.call(materialLine, material);
763
+ materialLine.color.copy(material.color);
764
+ material = materialLine;
765
+ } else if (isPoints && material && !(material instanceof PointsMaterial)) {
766
+ const materialPoints = new PointsMaterial({ size: 10, sizeAttenuation: false });
767
+ Material.prototype.copy.call(materialPoints, material);
768
+ materialPoints.color.copy(material.color);
769
+ materialPoints.map = material.map;
770
+ material = materialPoints;
771
+ }
772
+ }
773
+ if (material === void 0) {
774
+ if (isLine) {
775
+ material = new LineBasicMaterial();
776
+ } else if (isPoints) {
777
+ material = new PointsMaterial({ size: 1, sizeAttenuation: false });
778
+ } else {
779
+ material = new MeshPhongMaterial();
780
+ }
781
+ material.name = sourceMaterial.name;
782
+ material.flatShading = sourceMaterial.smooth ? false : true;
783
+ material.vertexColors = hasVertexColors;
784
+ state.materials[materialHash] = material;
785
+ }
786
+ createdMaterials.push(material);
787
+ }
788
+ let mesh;
789
+ if (createdMaterials.length > 1) {
790
+ for (let mi = 0, miLen = materials.length; mi < miLen; mi++) {
791
+ const sourceMaterial = materials[mi];
792
+ buffergeometry.addGroup(sourceMaterial.groupStart, sourceMaterial.groupCount, mi);
793
+ }
794
+ if (isLine) {
795
+ mesh = new LineSegments(buffergeometry, createdMaterials);
796
+ } else if (isPoints) {
797
+ mesh = new Points(buffergeometry, createdMaterials);
798
+ } else {
799
+ mesh = new Mesh(buffergeometry, createdMaterials);
800
+ }
801
+ } else {
802
+ if (isLine) {
803
+ mesh = new LineSegments(buffergeometry, createdMaterials[0]);
804
+ } else if (isPoints) {
805
+ mesh = new Points(buffergeometry, createdMaterials[0]);
806
+ } else {
807
+ mesh = new Mesh(buffergeometry, createdMaterials[0]);
808
+ }
809
+ }
810
+ mesh.name = object.name;
811
+ container.add(mesh);
812
+ }
813
+ } else {
814
+ if (state.vertices.length > 0) {
815
+ const material = new PointsMaterial({ size: 1, sizeAttenuation: false });
816
+ const buffergeometry = new BufferGeometry();
817
+ buffergeometry.setAttribute("position", new Float32BufferAttribute(state.vertices, 3));
818
+ if (state.colors.length > 0 && state.colors[0] !== void 0) {
819
+ buffergeometry.setAttribute("color", new Float32BufferAttribute(state.colors, 3));
820
+ material.vertexColors = true;
821
+ }
822
+ const points = new Points(buffergeometry, material);
823
+ container.add(points);
824
+ }
825
+ }
826
+ return container;
827
+ }
828
+ };
829
+ export {
830
+ OBJLoader
831
+ };
832
+ //# sourceMappingURL=three_examples_jsm_loaders_OBJLoader__js.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@needle-tools/three",
3
- "version": "0.162.10",
3
+ "version": "0.162.12",
4
4
  "description": "JavaScript 3D library",
5
5
  "type": "module",
6
6
  "main": "./build/three.cjs",