@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
|
-
|
|
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
|