├── obj
├── gg.jpg
└── jj.mtl
├── .gitattributes
├── pdf
└── marker89.pdf
├── data
└── camera_para.dat
├── README.md
├── bulid
├── stats.js
├── OBJMTLLoader.js
├── MTLLoader.js
└── OBJLoader.js
├── basic.html
└── arcode
└── marker89.td
/obj/gg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webglzhang/WebARDemo/HEAD/obj/gg.jpg
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/pdf/marker89.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webglzhang/WebARDemo/HEAD/pdf/marker89.pdf
--------------------------------------------------------------------------------
/data/camera_para.dat:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webglzhang/WebARDemo/HEAD/data/camera_para.dat
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # WebARDemo
2 |
3 | 这是我大学做WebAR导航试验性的ARdemo,也仅仅作为功能性的验证,没有任何的代码规范和工程结构。Demo开发时间大约在2019年,早已经不在维护。我专注于可视化相关的技术应用,有兴趣的同学,可以加入我的QQ群或者关注我的公众号,公众号正在开发中,qq群经常会交流一些技术问题。
4 |
5 | QQ群:740855975
6 |
--------------------------------------------------------------------------------
/obj/jj.mtl:
--------------------------------------------------------------------------------
1 | # 3ds Max Wavefront OBJ Exporter v0.97b - (c)2007 guruware
2 | # File Created: 26.05.2017 23:41:18
3 |
4 | newmtl 1d908e75_dds
5 | Ns 10.0000
6 | Ni 1.5000
7 | d 1.0000
8 | Tr 0.0000
9 | Tf 1.0000 1.0000 1.0000
10 | illum 2
11 | Ka 0.7000 0.7000 0.7000
12 | Kd 0.7000 0.7000 0.7000
13 | Ks 0.1000 0.1000 0.1000
14 | Ke 0.0000 0.0000 0.0000
15 | map_Ka gg.jpg
16 | map_Kd gg.jpg
17 | map_d gg.jpg
--------------------------------------------------------------------------------
/bulid/stats.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author mrdoob / http://mrdoob.com/
3 | */
4 |
5 | var Stats = function () {
6 |
7 | var startTime = Date.now(), prevTime = startTime;
8 | var ms = 0, msMin = Infinity, msMax = 0;
9 | var fps = 0, fpsMin = Infinity, fpsMax = 0;
10 | var frames = 0, mode = 0;
11 |
12 | var container = document.createElement( 'div' );
13 | container.id = 'stats';
14 | container.addEventListener( 'mousedown', function ( event ) { event.preventDefault(); setMode( ++ mode % 2 ) }, false );
15 | container.style.cssText = 'width:80px;opacity:0.9;cursor:pointer';
16 |
17 | var fpsDiv = document.createElement( 'div' );
18 | fpsDiv.id = 'fps';
19 | fpsDiv.style.cssText = 'padding:0 0 3px 3px;text-align:left;background-color:#002';
20 | container.appendChild( fpsDiv );
21 |
22 | var fpsText = document.createElement( 'div' );
23 | fpsText.id = 'fpsText';
24 | fpsText.style.cssText = 'color:#0ff;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px';
25 | fpsText.innerHTML = 'FPS';
26 | fpsDiv.appendChild( fpsText );
27 |
28 | var fpsGraph = document.createElement( 'div' );
29 | fpsGraph.id = 'fpsGraph';
30 | fpsGraph.style.cssText = 'position:relative;width:74px;height:30px;background-color:#0ff';
31 | fpsDiv.appendChild( fpsGraph );
32 |
33 | while ( fpsGraph.children.length < 74 ) {
34 |
35 | var bar = document.createElement( 'span' );
36 | bar.style.cssText = 'width:1px;height:30px;float:left;background-color:#113';
37 | fpsGraph.appendChild( bar );
38 |
39 | }
40 |
41 | var msDiv = document.createElement( 'div' );
42 | msDiv.id = 'ms';
43 | msDiv.style.cssText = 'padding:0 0 3px 3px;text-align:left;background-color:#020;display:none';
44 | container.appendChild( msDiv );
45 |
46 | var msText = document.createElement( 'div' );
47 | msText.id = 'msText';
48 | msText.style.cssText = 'color:#0f0;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px';
49 | msText.innerHTML = 'MS';
50 | msDiv.appendChild( msText );
51 |
52 | var msGraph = document.createElement( 'div' );
53 | msGraph.id = 'msGraph';
54 | msGraph.style.cssText = 'position:relative;width:74px;height:30px;background-color:#0f0';
55 | msDiv.appendChild( msGraph );
56 |
57 | while ( msGraph.children.length < 74 ) {
58 |
59 | var bar = document.createElement( 'span' );
60 | bar.style.cssText = 'width:1px;height:30px;float:left;background-color:#131';
61 | msGraph.appendChild( bar );
62 |
63 | }
64 |
65 | var setMode = function ( value ) {
66 |
67 | mode = value;
68 |
69 | switch ( mode ) {
70 |
71 | case 0:
72 | fpsDiv.style.display = 'block';
73 | msDiv.style.display = 'none';
74 | break;
75 | case 1:
76 | fpsDiv.style.display = 'none';
77 | msDiv.style.display = 'block';
78 | break;
79 | }
80 |
81 | }
82 |
83 | var updateGraph = function ( dom, value ) {
84 |
85 | var child = dom.appendChild( dom.firstChild );
86 | child.style.height = value + 'px';
87 |
88 | }
89 |
90 | return {
91 |
92 | REVISION: 11,
93 |
94 | domElement: container,
95 |
96 | setMode: setMode,
97 |
98 | begin: function () {
99 |
100 | startTime = Date.now();
101 |
102 | },
103 |
104 | end: function () {
105 |
106 | var time = Date.now();
107 |
108 | ms = time - startTime;
109 | msMin = Math.min( msMin, ms );
110 | msMax = Math.max( msMax, ms );
111 |
112 | msText.textContent = ms + ' MS (' + msMin + '-' + msMax + ')';
113 | updateGraph( msGraph, Math.min( 30, 30 - ( ms / 200 ) * 30 ) );
114 |
115 | frames ++;
116 |
117 | if ( time > prevTime + 1000 ) {
118 |
119 | fps = Math.round( ( frames * 1000 ) / ( time - prevTime ) );
120 | fpsMin = Math.min( fpsMin, fps );
121 | fpsMax = Math.max( fpsMax, fps );
122 |
123 | fpsText.textContent = fps + ' FPS (' + fpsMin + '-' + fpsMax + ')';
124 | updateGraph( fpsGraph, Math.min( 30, 30 - ( fps / 100 ) * 30 ) );
125 |
126 | prevTime = time;
127 | frames = 0;
128 |
129 | }
130 |
131 | return time;
132 |
133 | },
134 |
135 | update: function () {
136 |
137 | startTime = this.end();
138 |
139 | }
140 |
141 | }
142 |
143 | };
144 |
--------------------------------------------------------------------------------
/basic.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
AR.js - three.js camera transform
21 |
22 | Contact me any time at
@jerome_etienne
23 |
24 |
207 |
--------------------------------------------------------------------------------
/bulid/OBJMTLLoader.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Loads a Wavefront .obj file with materials
3 | *
4 | * @author mrdoob / http://mrdoob.com/
5 | * @author angelxuanchang
6 | */
7 |
8 | THREE.OBJMTLLoader = function ( manager ) {
9 |
10 | this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
11 |
12 | };
13 |
14 | THREE.OBJMTLLoader.prototype = {
15 |
16 | constructor: THREE.OBJMTLLoader,
17 |
18 | load: function ( url, mtlurl, onLoad, onProgress, onError ) {
19 |
20 | var scope = this;
21 |
22 | var mtlLoader = new THREE.MTLLoader( url.substr( 0, url.lastIndexOf( "/" ) + 1 ) );
23 | mtlLoader.load( mtlurl, function ( materials ) {
24 |
25 | var materialsCreator = materials;
26 | materialsCreator.preload();
27 |
28 | var loader = new THREE.XHRLoader( scope.manager );
29 | loader.setCrossOrigin( this.crossOrigin );
30 | loader.load( url, function ( text ) {
31 |
32 | var object = scope.parse( text );
33 |
34 | object.traverse( function ( object ) {
35 |
36 | if ( object instanceof THREE.Mesh ) {
37 |
38 | if ( object.material.name ) {
39 |
40 | var material = materialsCreator.create( object.material.name );
41 |
42 | if ( material ) object.material = material;
43 |
44 | }
45 |
46 | }
47 |
48 | } );
49 |
50 | onLoad( object );
51 |
52 | }, onProgress, onError );
53 |
54 | }, onProgress, onError );
55 |
56 | },
57 |
58 | /**
59 | * Parses loaded .obj file
60 | * @param data - content of .obj file
61 | * @param mtllibCallback - callback to handle mtllib declaration (optional)
62 | * @return {THREE.Object3D} - Object3D (with default material)
63 | */
64 |
65 | parse: function ( data, mtllibCallback ) {
66 |
67 | function vector( x, y, z ) {
68 |
69 | return new THREE.Vector3( x, y, z );
70 |
71 | }
72 |
73 | function uv( u, v ) {
74 |
75 | return new THREE.Vector2( u, v );
76 |
77 | }
78 |
79 | function face3( a, b, c, normals ) {
80 |
81 | return new THREE.Face3( a, b, c, normals );
82 |
83 | }
84 |
85 | var face_offset = 0;
86 |
87 | function meshN( meshName, materialName ) {
88 |
89 | if ( vertices.length > 0 ) {
90 |
91 | geometry.vertices = vertices;
92 |
93 | geometry.mergeVertices();
94 | geometry.computeFaceNormals();
95 | geometry.computeBoundingSphere();
96 |
97 | object.add( mesh );
98 |
99 | geometry = new THREE.Geometry();
100 | mesh = new THREE.Mesh( geometry, material );
101 |
102 | }
103 |
104 | if ( meshName !== undefined ) mesh.name = meshName;
105 |
106 | if ( materialName !== undefined ) {
107 |
108 | material = new THREE.MeshLambertMaterial();
109 | material.name = materialName;
110 |
111 | mesh.material = material;
112 |
113 | }
114 |
115 | }
116 |
117 | var group = new THREE.Group();
118 | var object = group;
119 |
120 | var geometry = new THREE.Geometry();
121 | var material = new THREE.MeshLambertMaterial();
122 | var mesh = new THREE.Mesh( geometry, material );
123 |
124 | var vertices = [];
125 | var normals = [];
126 | var uvs = [];
127 |
128 | function add_face( a, b, c, normals_inds ) {
129 |
130 | if ( normals_inds === undefined ) {
131 |
132 | geometry.faces.push( face3(
133 | parseInt( a ) - (face_offset + 1),
134 | parseInt( b ) - (face_offset + 1),
135 | parseInt( c ) - (face_offset + 1)
136 | ) );
137 |
138 | } else {
139 |
140 | geometry.faces.push( face3(
141 | parseInt( a ) - (face_offset + 1),
142 | parseInt( b ) - (face_offset + 1),
143 | parseInt( c ) - (face_offset + 1),
144 | [
145 | normals[ parseInt( normals_inds[ 0 ] ) - 1 ].clone(),
146 | normals[ parseInt( normals_inds[ 1 ] ) - 1 ].clone(),
147 | normals[ parseInt( normals_inds[ 2 ] ) - 1 ].clone()
148 | ]
149 | ) );
150 |
151 | }
152 |
153 | }
154 |
155 | function add_uvs( a, b, c ) {
156 |
157 | geometry.faceVertexUvs[ 0 ].push( [
158 | uvs[ parseInt( a ) - 1 ].clone(),
159 | uvs[ parseInt( b ) - 1 ].clone(),
160 | uvs[ parseInt( c ) - 1 ].clone()
161 | ] );
162 |
163 | }
164 |
165 | function handle_face_line(faces, uvs, normals_inds) {
166 |
167 | if ( faces[ 3 ] === undefined ) {
168 |
169 | add_face( faces[ 0 ], faces[ 1 ], faces[ 2 ], normals_inds );
170 |
171 | if (!(uvs === undefined) && uvs.length > 0) {
172 | add_uvs( uvs[ 0 ], uvs[ 1 ], uvs[ 2 ] );
173 | }
174 |
175 | } else {
176 |
177 | if (!(normals_inds === undefined) && normals_inds.length > 0) {
178 |
179 | add_face( faces[ 0 ], faces[ 1 ], faces[ 3 ], [ normals_inds[ 0 ], normals_inds[ 1 ], normals_inds[ 3 ] ]);
180 | add_face( faces[ 1 ], faces[ 2 ], faces[ 3 ], [ normals_inds[ 1 ], normals_inds[ 2 ], normals_inds[ 3 ] ]);
181 |
182 | } else {
183 |
184 | add_face( faces[ 0 ], faces[ 1 ], faces[ 3 ]);
185 | add_face( faces[ 1 ], faces[ 2 ], faces[ 3 ]);
186 |
187 | }
188 |
189 | if (!(uvs === undefined) && uvs.length > 0) {
190 |
191 | add_uvs( uvs[ 0 ], uvs[ 1 ], uvs[ 3 ] );
192 | add_uvs( uvs[ 1 ], uvs[ 2 ], uvs[ 3 ] );
193 |
194 | }
195 |
196 | }
197 |
198 | }
199 |
200 |
201 | // v float float float
202 |
203 | var vertex_pattern = /v( +[\d|\.|\+|\-|e]+)( +[\d|\.|\+|\-|e]+)( +[\d|\.|\+|\-|e]+)/;
204 |
205 | // vn float float float
206 |
207 | var normal_pattern = /vn( +[\d|\.|\+|\-|e]+)( +[\d|\.|\+|\-|e]+)( +[\d|\.|\+|\-|e]+)/;
208 |
209 | // vt float float
210 |
211 | var uv_pattern = /vt( +[\d|\.|\+|\-|e]+)( +[\d|\.|\+|\-|e]+)/;
212 |
213 | // f vertex vertex vertex ...
214 |
215 | var face_pattern1 = /f( +\d+)( +\d+)( +\d+)( +\d+)?/;
216 |
217 | // f vertex/uv vertex/uv vertex/uv ...
218 |
219 | var face_pattern2 = /f( +(\d+)\/(\d+))( +(\d+)\/(\d+))( +(\d+)\/(\d+))( +(\d+)\/(\d+))?/;
220 |
221 | // f vertex/uv/normal vertex/uv/normal vertex/uv/normal ...
222 |
223 | var face_pattern3 = /f( +(\d+)\/(\d+)\/(\d+))( +(\d+)\/(\d+)\/(\d+))( +(\d+)\/(\d+)\/(\d+))( +(\d+)\/(\d+)\/(\d+))?/;
224 |
225 | // f vertex//normal vertex//normal vertex//normal ...
226 |
227 | var face_pattern4 = /f( +(\d+)\/\/(\d+))( +(\d+)\/\/(\d+))( +(\d+)\/\/(\d+))( +(\d+)\/\/(\d+))?/
228 |
229 | //
230 |
231 | var lines = data.split( "\n" );
232 |
233 | for ( var i = 0; i < lines.length; i ++ ) {
234 |
235 | var line = lines[ i ];
236 | line = line.trim();
237 |
238 | var result;
239 |
240 | if ( line.length === 0 || line.charAt( 0 ) === '#' ) {
241 |
242 | continue;
243 |
244 | } else if ( ( result = vertex_pattern.exec( line ) ) !== null ) {
245 |
246 | // ["v 1.0 2.0 3.0", "1.0", "2.0", "3.0"]
247 |
248 | vertices.push( vector(
249 | parseFloat( result[ 1 ] ),
250 | parseFloat( result[ 2 ] ),
251 | parseFloat( result[ 3 ] )
252 | ) );
253 |
254 | } else if ( ( result = normal_pattern.exec( line ) ) !== null ) {
255 |
256 | // ["vn 1.0 2.0 3.0", "1.0", "2.0", "3.0"]
257 |
258 | normals.push( vector(
259 | parseFloat( result[ 1 ] ),
260 | parseFloat( result[ 2 ] ),
261 | parseFloat( result[ 3 ] )
262 | ) );
263 |
264 | } else if ( ( result = uv_pattern.exec( line ) ) !== null ) {
265 |
266 | // ["vt 0.1 0.2", "0.1", "0.2"]
267 |
268 | uvs.push( uv(
269 | parseFloat( result[ 1 ] ),
270 | parseFloat( result[ 2 ] )
271 | ) );
272 |
273 | } else if ( ( result = face_pattern1.exec( line ) ) !== null ) {
274 |
275 | // ["f 1 2 3", "1", "2", "3", undefined]
276 |
277 | handle_face_line([ result[ 1 ], result[ 2 ], result[ 3 ], result[ 4 ] ]);
278 |
279 | } else if ( ( result = face_pattern2.exec( line ) ) !== null ) {
280 |
281 | // ["f 1/1 2/2 3/3", " 1/1", "1", "1", " 2/2", "2", "2", " 3/3", "3", "3", undefined, undefined, undefined]
282 |
283 | handle_face_line(
284 | [ result[ 2 ], result[ 5 ], result[ 8 ], result[ 11 ] ], //faces
285 | [ result[ 3 ], result[ 6 ], result[ 9 ], result[ 12 ] ] //uv
286 | );
287 |
288 | } else if ( ( result = face_pattern3.exec( line ) ) !== null ) {
289 |
290 | // ["f 1/1/1 2/2/2 3/3/3", " 1/1/1", "1", "1", "1", " 2/2/2", "2", "2", "2", " 3/3/3", "3", "3", "3", undefined, undefined, undefined, undefined]
291 |
292 | handle_face_line(
293 | [ result[ 2 ], result[ 6 ], result[ 10 ], result[ 14 ] ], //faces
294 | [ result[ 3 ], result[ 7 ], result[ 11 ], result[ 15 ] ], //uv
295 | [ result[ 4 ], result[ 8 ], result[ 12 ], result[ 16 ] ] //normal
296 | );
297 |
298 | } else if ( ( result = face_pattern4.exec( line ) ) !== null ) {
299 |
300 | // ["f 1//1 2//2 3//3", " 1//1", "1", "1", " 2//2", "2", "2", " 3//3", "3", "3", undefined, undefined, undefined]
301 |
302 | handle_face_line(
303 | [ result[ 2 ], result[ 5 ], result[ 8 ], result[ 11 ] ], //faces
304 | [ ], //uv
305 | [ result[ 3 ], result[ 6 ], result[ 9 ], result[ 12 ] ] //normal
306 | );
307 |
308 | } else if ( /^o /.test( line ) ) {
309 |
310 | // object
311 |
312 | meshN();
313 | face_offset = face_offset + vertices.length;
314 | vertices = [];
315 | object = new THREE.Object3D();
316 | object.name = line.substring( 2 ).trim();
317 | group.add( object );
318 |
319 | } else if ( /^g /.test( line ) ) {
320 |
321 | // group
322 |
323 | meshN( line.substring( 2 ).trim(), undefined );
324 |
325 | } else if ( /^usemtl /.test( line ) ) {
326 |
327 | // material
328 |
329 | meshN( undefined, line.substring( 7 ).trim() );
330 |
331 | } else if ( /^mtllib /.test( line ) ) {
332 |
333 | // mtl file
334 |
335 | if ( mtllibCallback ) {
336 |
337 | var mtlfile = line.substring( 7 );
338 | mtlfile = mtlfile.trim();
339 | mtllibCallback( mtlfile );
340 |
341 | }
342 |
343 | } else if ( /^s /.test( line ) ) {
344 |
345 | // Smooth shading
346 |
347 | } else {
348 |
349 | console.log( "THREE.OBJMTLLoader: Unhandled line " + line );
350 |
351 | }
352 |
353 | }
354 |
355 | //Add last object
356 | meshN(undefined, undefined);
357 |
358 | return group;
359 |
360 | }
361 |
362 | };
363 |
364 | THREE.EventDispatcher.prototype.apply( THREE.OBJMTLLoader.prototype );
365 |
--------------------------------------------------------------------------------
/arcode/marker89.td:
--------------------------------------------------------------------------------
1 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
2 | 255 251 255 255 255 0 253 255 0 255 0 255 255 255 251 255
3 | 255 254 0 0 255 0 255 0 254 0 0 255 0 0 254 255
4 | 255 254 0 0 255 0 1 0 254 255 0 255 0 0 254 255
5 | 255 254 255 255 255 0 255 0 254 255 0 255 255 255 254 255
6 | 255 0 0 0 0 0 0 254 252 0 0 0 0 0 0 255
7 | 255 255 0 254 0 0 0 0 254 255 254 255 0 255 254 255
8 | 255 0 254 254 254 254 0 254 2 0 254 0 0 254 0 255
9 | 255 0 254 254 254 254 255 254 2 0 254 0 1 254 0 255
10 | 255 254 0 0 255 0 0 255 255 0 1 0 255 0 0 255
11 | 255 0 0 0 0 0 255 254 253 0 254 255 254 255 255 255
12 | 255 254 255 255 255 0 0 1 1 255 0 255 255 0 0 255
13 | 255 254 0 0 255 0 253 0 0 255 0 0 2 255 2 255
14 | 255 254 0 0 255 0 0 0 0 0 254 0 0 0 254 255
15 | 255 251 255 255 255 0 255 0 1 1 255 0 0 255 255 255
16 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
17 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
18 | 255 251 255 255 255 0 253 255 0 255 0 255 255 255 251 255
19 | 255 254 0 0 255 0 255 0 254 0 0 255 0 0 254 255
20 | 255 254 0 0 255 0 1 0 254 255 0 255 0 0 254 255
21 | 255 254 255 255 255 0 255 0 254 255 0 255 255 255 254 255
22 | 255 0 0 0 0 0 0 254 252 0 0 0 0 0 0 255
23 | 255 255 0 254 0 0 0 0 254 255 254 255 0 255 254 255
24 | 255 0 254 254 254 254 0 254 2 0 254 0 0 254 0 255
25 | 255 0 254 254 254 254 255 254 2 0 254 0 1 254 0 255
26 | 255 254 0 0 255 0 0 255 255 0 1 0 255 0 0 255
27 | 255 0 0 0 0 0 255 254 253 0 254 255 254 255 255 255
28 | 255 254 255 255 255 0 0 1 1 255 0 255 255 0 0 255
29 | 255 254 0 0 255 0 253 0 0 255 0 0 2 255 2 255
30 | 255 254 0 0 255 0 0 0 0 0 254 0 0 0 254 255
31 | 255 251 255 255 255 0 255 0 1 1 255 0 0 255 255 255
32 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
33 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
34 | 255 251 255 255 255 0 253 255 0 255 0 255 255 255 251 255
35 | 255 254 0 0 255 0 255 0 254 0 0 255 0 0 254 255
36 | 255 254 0 0 255 0 1 0 254 255 0 255 0 0 254 255
37 | 255 254 255 255 255 0 255 0 254 255 0 255 255 255 254 255
38 | 255 0 0 0 0 0 0 254 252 0 0 0 0 0 0 255
39 | 255 255 0 254 0 0 0 0 254 255 254 255 0 255 254 255
40 | 255 0 254 254 254 254 0 254 2 0 254 0 0 254 0 255
41 | 255 0 254 254 254 254 255 254 2 0 254 0 1 254 0 255
42 | 255 254 0 0 255 0 0 255 255 0 1 0 255 0 0 255
43 | 255 0 0 0 0 0 255 254 253 0 254 255 254 255 255 255
44 | 255 254 255 255 255 0 0 1 1 255 0 255 255 0 0 255
45 | 255 254 0 0 255 0 253 0 0 255 0 0 2 255 2 255
46 | 255 254 0 0 255 0 0 0 0 0 254 0 0 0 254 255
47 | 255 251 255 255 255 0 255 0 1 1 255 0 0 255 255 255
48 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
49 |
50 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
51 | 255 252 254 254 254 0 255 1 1 0 255 0 2 254 255 255
52 | 255 255 0 0 255 0 255 254 254 0 255 0 255 0 255 255
53 | 255 255 0 0 255 0 0 1 1 255 255 255 2 0 0 255
54 | 255 255 255 255 255 0 255 0 0 0 255 255 0 0 0 255
55 | 255 0 0 0 0 0 255 254 254 2 254 0 0 254 255 255
56 | 255 255 0 255 255 0 255 0 0 0 0 255 255 0 2 255
57 | 255 0 254 254 254 253 254 3 3 255 253 1 0 0 1 255
58 | 255 255 0 0 0 254 0 254 254 255 254 1 0 0 0 255
59 | 255 254 255 2 255 0 0 0 255 0 255 0 254 0 255 255
60 | 255 0 0 0 0 0 0 254 254 0 0 0 0 0 0 255
61 | 255 255 255 255 255 0 0 254 254 255 0 255 255 255 255 255
62 | 255 255 0 0 255 0 255 254 254 0 0 255 0 0 255 255
63 | 255 255 0 0 255 0 0 254 254 0 0 255 0 0 255 255
64 | 255 252 254 254 254 0 255 0 0 255 0 254 254 254 252 255
65 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
66 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
67 | 255 252 254 254 254 0 255 1 1 0 255 0 2 254 255 255
68 | 255 255 0 0 255 0 255 254 254 0 255 0 255 0 255 255
69 | 255 255 0 0 255 0 0 1 1 255 255 255 2 0 0 255
70 | 255 255 255 255 255 0 255 0 0 0 255 255 0 0 0 255
71 | 255 0 0 0 0 0 255 254 254 2 254 0 0 254 255 255
72 | 255 255 0 255 255 0 255 0 0 0 0 255 255 0 2 255
73 | 255 0 254 254 254 253 254 3 3 255 253 1 0 0 1 255
74 | 255 255 0 0 0 254 0 254 254 255 254 1 0 0 0 255
75 | 255 254 255 2 255 0 0 0 255 0 255 0 254 0 255 255
76 | 255 0 0 0 0 0 0 254 254 0 0 0 0 0 0 255
77 | 255 255 255 255 255 0 0 254 254 255 0 255 255 255 255 255
78 | 255 255 0 0 255 0 255 254 254 0 0 255 0 0 255 255
79 | 255 255 0 0 255 0 0 254 254 0 0 255 0 0 255 255
80 | 255 252 254 254 254 0 255 0 0 255 0 254 254 254 252 255
81 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
82 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
83 | 255 252 254 254 254 0 255 1 1 0 255 0 2 254 255 255
84 | 255 255 0 0 255 0 255 254 254 0 255 0 255 0 255 255
85 | 255 255 0 0 255 0 0 1 1 255 255 255 2 0 0 255
86 | 255 255 255 255 255 0 255 0 0 0 255 255 0 0 0 255
87 | 255 0 0 0 0 0 255 254 254 2 254 0 0 254 255 255
88 | 255 255 0 255 255 0 255 0 0 0 0 255 255 0 2 255
89 | 255 0 254 254 254 253 254 3 3 255 253 1 0 0 1 255
90 | 255 255 0 0 0 254 0 254 254 255 254 1 0 0 0 255
91 | 255 254 255 2 255 0 0 0 255 0 255 0 254 0 255 255
92 | 255 0 0 0 0 0 0 254 254 0 0 0 0 0 0 255
93 | 255 255 255 255 255 0 0 254 254 255 0 255 255 255 255 255
94 | 255 255 0 0 255 0 255 254 254 0 0 255 0 0 255 255
95 | 255 255 0 0 255 0 0 254 254 0 0 255 0 0 255 255
96 | 255 252 254 254 254 0 255 0 0 255 0 254 254 254 252 255
97 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
98 |
99 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
100 | 255 255 255 0 0 255 1 1 0 255 0 255 255 255 251 255
101 | 255 254 0 0 0 254 0 0 0 0 0 255 0 0 254 255
102 | 255 2 255 2 0 0 255 0 0 253 0 255 0 0 254 255
103 | 255 0 0 255 255 0 255 1 1 0 0 255 255 255 254 255
104 | 255 255 255 254 255 254 0 253 254 255 0 0 0 0 0 255
105 | 255 0 0 255 0 1 0 255 255 0 0 255 0 0 254 255
106 | 255 0 254 1 0 254 0 2 254 255 254 254 254 254 0 255
107 | 255 0 254 0 0 254 0 2 254 0 254 254 254 254 0 255
108 | 255 254 255 0 255 254 255 254 0 0 0 0 254 0 255 255
109 | 255 0 0 0 0 0 0 252 254 0 0 0 0 0 0 255
110 | 255 254 255 255 255 0 255 254 0 255 0 255 255 255 254 255
111 | 255 254 0 0 255 0 255 254 0 1 0 255 0 0 254 255
112 | 255 254 0 0 255 0 0 254 0 255 0 255 0 0 254 255
113 | 255 251 255 255 255 0 255 0 255 253 0 255 255 255 251 255
114 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
115 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
116 | 255 255 255 0 0 255 1 1 0 255 0 255 255 255 251 255
117 | 255 254 0 0 0 254 0 0 0 0 0 255 0 0 254 255
118 | 255 2 255 2 0 0 255 0 0 253 0 255 0 0 254 255
119 | 255 0 0 255 255 0 255 1 1 0 0 255 255 255 254 255
120 | 255 255 255 254 255 254 0 253 254 255 0 0 0 0 0 255
121 | 255 0 0 255 0 1 0 255 255 0 0 255 0 0 254 255
122 | 255 0 254 1 0 254 0 2 254 255 254 254 254 254 0 255
123 | 255 0 254 0 0 254 0 2 254 0 254 254 254 254 0 255
124 | 255 254 255 0 255 254 255 254 0 0 0 0 254 0 255 255
125 | 255 0 0 0 0 0 0 252 254 0 0 0 0 0 0 255
126 | 255 254 255 255 255 0 255 254 0 255 0 255 255 255 254 255
127 | 255 254 0 0 255 0 255 254 0 1 0 255 0 0 254 255
128 | 255 254 0 0 255 0 0 254 0 255 0 255 0 0 254 255
129 | 255 251 255 255 255 0 255 0 255 253 0 255 255 255 251 255
130 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
131 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
132 | 255 255 255 0 0 255 1 1 0 255 0 255 255 255 251 255
133 | 255 254 0 0 0 254 0 0 0 0 0 255 0 0 254 255
134 | 255 2 255 2 0 0 255 0 0 253 0 255 0 0 254 255
135 | 255 0 0 255 255 0 255 1 1 0 0 255 255 255 254 255
136 | 255 255 255 254 255 254 0 253 254 255 0 0 0 0 0 255
137 | 255 0 0 255 0 1 0 255 255 0 0 255 0 0 254 255
138 | 255 0 254 1 0 254 0 2 254 255 254 254 254 254 0 255
139 | 255 0 254 0 0 254 0 2 254 0 254 254 254 254 0 255
140 | 255 254 255 0 255 254 255 254 0 0 0 0 254 0 255 255
141 | 255 0 0 0 0 0 0 252 254 0 0 0 0 0 0 255
142 | 255 254 255 255 255 0 255 254 0 255 0 255 255 255 254 255
143 | 255 254 0 0 255 0 255 254 0 1 0 255 0 0 254 255
144 | 255 254 0 0 255 0 0 254 0 255 0 255 0 0 254 255
145 | 255 251 255 255 255 0 255 0 255 253 0 255 255 255 251 255
146 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
147 |
148 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
149 | 255 252 254 254 254 0 255 0 0 255 0 254 254 254 252 255
150 | 255 255 0 0 255 0 0 254 254 0 0 255 0 0 255 255
151 | 255 255 0 0 255 0 0 254 254 255 0 255 0 0 255 255
152 | 255 255 255 255 255 0 255 254 254 0 0 255 255 255 255 255
153 | 255 0 0 0 0 0 0 254 254 0 0 0 0 0 0 255
154 | 255 255 0 254 0 255 0 255 0 0 0 255 2 255 254 255
155 | 255 0 0 0 1 254 255 254 254 0 254 0 0 0 255 255
156 | 255 1 0 0 1 253 255 3 3 254 253 254 254 254 0 255
157 | 255 2 0 255 255 0 0 0 0 255 0 255 255 0 255 255
158 | 255 255 254 0 0 254 2 254 254 255 0 0 0 0 0 255
159 | 255 0 0 0 255 255 0 0 0 255 0 255 255 255 255 255
160 | 255 0 0 2 255 255 255 1 1 0 0 255 0 0 255 255
161 | 255 255 0 255 0 255 0 254 254 255 0 255 0 0 255 255
162 | 255 255 254 2 0 255 0 1 1 255 0 254 254 254 252 255
163 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
164 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
165 | 255 252 254 254 254 0 255 0 0 255 0 254 254 254 252 255
166 | 255 255 0 0 255 0 0 254 254 0 0 255 0 0 255 255
167 | 255 255 0 0 255 0 0 254 254 255 0 255 0 0 255 255
168 | 255 255 255 255 255 0 255 254 254 0 0 255 255 255 255 255
169 | 255 0 0 0 0 0 0 254 254 0 0 0 0 0 0 255
170 | 255 255 0 254 0 255 0 255 0 0 0 255 2 255 254 255
171 | 255 0 0 0 1 254 255 254 254 0 254 0 0 0 255 255
172 | 255 1 0 0 1 253 255 3 3 254 253 254 254 254 0 255
173 | 255 2 0 255 255 0 0 0 0 255 0 255 255 0 255 255
174 | 255 255 254 0 0 254 2 254 254 255 0 0 0 0 0 255
175 | 255 0 0 0 255 255 0 0 0 255 0 255 255 255 255 255
176 | 255 0 0 2 255 255 255 1 1 0 0 255 0 0 255 255
177 | 255 255 0 255 0 255 0 254 254 255 0 255 0 0 255 255
178 | 255 255 254 2 0 255 0 1 1 255 0 254 254 254 252 255
179 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
180 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
181 | 255 252 254 254 254 0 255 0 0 255 0 254 254 254 252 255
182 | 255 255 0 0 255 0 0 254 254 0 0 255 0 0 255 255
183 | 255 255 0 0 255 0 0 254 254 255 0 255 0 0 255 255
184 | 255 255 255 255 255 0 255 254 254 0 0 255 255 255 255 255
185 | 255 0 0 0 0 0 0 254 254 0 0 0 0 0 0 255
186 | 255 255 0 254 0 255 0 255 0 0 0 255 2 255 254 255
187 | 255 0 0 0 1 254 255 254 254 0 254 0 0 0 255 255
188 | 255 1 0 0 1 253 255 3 3 254 253 254 254 254 0 255
189 | 255 2 0 255 255 0 0 0 0 255 0 255 255 0 255 255
190 | 255 255 254 0 0 254 2 254 254 255 0 0 0 0 0 255
191 | 255 0 0 0 255 255 0 0 0 255 0 255 255 255 255 255
192 | 255 0 0 2 255 255 255 1 1 0 0 255 0 0 255 255
193 | 255 255 0 255 0 255 0 254 254 255 0 255 0 0 255 255
194 | 255 255 254 2 0 255 0 1 1 255 0 254 254 254 252 255
195 | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
196 |
--------------------------------------------------------------------------------
/bulid/MTLLoader.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Loads a Wavefront .mtl file specifying materials
3 | *
4 | * @author angelxuanchang
5 | */
6 |
7 | THREE.MTLLoader = function ( manager ) {
8 |
9 | this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
10 |
11 | };
12 |
13 | THREE.MTLLoader.prototype = {
14 |
15 | constructor: THREE.MTLLoader,
16 |
17 | /**
18 | * Loads and parses a MTL asset from a URL.
19 | *
20 | * @param {String} url - URL to the MTL file.
21 | * @param {Function} [onLoad] - Callback invoked with the loaded object.
22 | * @param {Function} [onProgress] - Callback for download progress.
23 | * @param {Function} [onError] - Callback for download errors.
24 | *
25 | * @see setPath setTexturePath
26 | *
27 | * @note In order for relative texture references to resolve correctly
28 | * you must call setPath and/or setTexturePath explicitly prior to load.
29 | */
30 | load: function ( url, onLoad, onProgress, onError ) {
31 |
32 | var scope = this;
33 |
34 | var loader = new THREE.FileLoader( this.manager );
35 | loader.setPath( this.path );
36 | loader.load( url, function ( text ) {
37 |
38 | onLoad( scope.parse( text ) );
39 |
40 | }, onProgress, onError );
41 |
42 | },
43 |
44 | /**
45 | * Set base path for resolving references.
46 | * If set this path will be prepended to each loaded and found reference.
47 | *
48 | * @see setTexturePath
49 | * @param {String} path
50 | *
51 | * @example
52 | * mtlLoader.setPath( 'assets/obj/' );
53 | * mtlLoader.load( 'my.mtl', ... );
54 | */
55 | setPath: function ( path ) {
56 |
57 | this.path = path;
58 |
59 | },
60 |
61 | /**
62 | * Set base path for resolving texture references.
63 | * If set this path will be prepended found texture reference.
64 | * If not set and setPath is, it will be used as texture base path.
65 | *
66 | * @see setPath
67 | * @param {String} path
68 | *
69 | * @example
70 | * mtlLoader.setPath( 'assets/obj/' );
71 | * mtlLoader.setTexturePath( 'assets/textures/' );
72 | * mtlLoader.load( 'my.mtl', ... );
73 | */
74 | setTexturePath: function ( path ) {
75 |
76 | this.texturePath = path;
77 |
78 | },
79 |
80 | setBaseUrl: function ( path ) {
81 |
82 | console.warn( 'THREE.MTLLoader: .setBaseUrl() is deprecated. Use .setTexturePath( path ) for texture path or .setPath( path ) for general base path instead.' );
83 |
84 | this.setTexturePath( path );
85 |
86 | },
87 |
88 | setCrossOrigin: function ( value ) {
89 |
90 | this.crossOrigin = value;
91 |
92 | },
93 |
94 | setMaterialOptions: function ( value ) {
95 |
96 | this.materialOptions = value;
97 |
98 | },
99 |
100 | /**
101 | * Parses a MTL file.
102 | *
103 | * @param {String} text - Content of MTL file
104 | * @return {THREE.MTLLoader.MaterialCreator}
105 | *
106 | * @see setPath setTexturePath
107 | *
108 | * @note In order for relative texture references to resolve correctly
109 | * you must call setPath and/or setTexturePath explicitly prior to parse.
110 | */
111 | parse: function ( text ) {
112 |
113 | var lines = text.split( '\n' );
114 | var info = {};
115 | var delimiter_pattern = /\s+/;
116 | var materialsInfo = {};
117 |
118 | for ( var i = 0; i < lines.length; i ++ ) {
119 |
120 | var line = lines[ i ];
121 | line = line.trim();
122 |
123 | if ( line.length === 0 || line.charAt( 0 ) === '#' ) {
124 |
125 | // Blank line or comment ignore
126 | continue;
127 |
128 | }
129 |
130 | var pos = line.indexOf( ' ' );
131 |
132 | var key = ( pos >= 0 ) ? line.substring( 0, pos ) : line;
133 | key = key.toLowerCase();
134 |
135 | var value = ( pos >= 0 ) ? line.substring( pos + 1 ) : '';
136 | value = value.trim();
137 |
138 | if ( key === 'newmtl' ) {
139 |
140 | // New material
141 |
142 | info = { name: value };
143 | materialsInfo[ value ] = info;
144 |
145 | } else if ( info ) {
146 |
147 | if ( key === 'ka' || key === 'kd' || key === 'ks' ) {
148 |
149 | var ss = value.split( delimiter_pattern, 3 );
150 | info[ key ] = [ parseFloat( ss[ 0 ] ), parseFloat( ss[ 1 ] ), parseFloat( ss[ 2 ] ) ];
151 |
152 | } else {
153 |
154 | info[ key ] = value;
155 |
156 | }
157 |
158 | }
159 |
160 | }
161 |
162 | var materialCreator = new THREE.MTLLoader.MaterialCreator( this.texturePath || this.path, this.materialOptions );
163 | materialCreator.setCrossOrigin( this.crossOrigin );
164 | materialCreator.setManager( this.manager );
165 | materialCreator.setMaterials( materialsInfo );
166 | return materialCreator;
167 |
168 | }
169 |
170 | };
171 |
172 | /**
173 | * Create a new THREE-MTLLoader.MaterialCreator
174 | * @param baseUrl - Url relative to which textures are loaded
175 | * @param options - Set of options on how to construct the materials
176 | * side: Which side to apply the material
177 | * THREE.FrontSide (default), THREE.BackSide, THREE.DoubleSide
178 | * wrap: What type of wrapping to apply for textures
179 | * THREE.RepeatWrapping (default), THREE.ClampToEdgeWrapping, THREE.MirroredRepeatWrapping
180 | * normalizeRGB: RGBs need to be normalized to 0-1 from 0-255
181 | * Default: false, assumed to be already normalized
182 | * ignoreZeroRGBs: Ignore values of RGBs (Ka,Kd,Ks) that are all 0's
183 | * Default: false
184 | * @constructor
185 | */
186 |
187 | THREE.MTLLoader.MaterialCreator = function ( baseUrl, options ) {
188 |
189 | this.baseUrl = baseUrl || '';
190 | this.options = options;
191 | this.materialsInfo = {};
192 | this.materials = {};
193 | this.materialsArray = [];
194 | this.nameLookup = {};
195 |
196 | this.side = ( this.options && this.options.side ) ? this.options.side : THREE.FrontSide;
197 | this.wrap = ( this.options && this.options.wrap ) ? this.options.wrap : THREE.RepeatWrapping;
198 |
199 | };
200 |
201 | THREE.MTLLoader.MaterialCreator.prototype = {
202 |
203 | constructor: THREE.MTLLoader.MaterialCreator,
204 |
205 | crossOrigin: 'Anonymous',
206 |
207 | setCrossOrigin: function ( value ) {
208 |
209 | this.crossOrigin = value;
210 |
211 | },
212 |
213 | setManager: function ( value ) {
214 |
215 | this.manager = value;
216 |
217 | },
218 |
219 | setMaterials: function ( materialsInfo ) {
220 |
221 | this.materialsInfo = this.convert( materialsInfo );
222 | this.materials = {};
223 | this.materialsArray = [];
224 | this.nameLookup = {};
225 |
226 | },
227 |
228 | convert: function ( materialsInfo ) {
229 |
230 | if ( ! this.options ) return materialsInfo;
231 |
232 | var converted = {};
233 |
234 | for ( var mn in materialsInfo ) {
235 |
236 | // Convert materials info into normalized form based on options
237 |
238 | var mat = materialsInfo[ mn ];
239 |
240 | var covmat = {};
241 |
242 | converted[ mn ] = covmat;
243 |
244 | for ( var prop in mat ) {
245 |
246 | var save = true;
247 | var value = mat[ prop ];
248 | var lprop = prop.toLowerCase();
249 |
250 | switch ( lprop ) {
251 |
252 | case 'kd':
253 | case 'ka':
254 | case 'ks':
255 |
256 | // Diffuse color (color under white light) using RGB values
257 |
258 | if ( this.options && this.options.normalizeRGB ) {
259 |
260 | value = [ value[ 0 ] / 255, value[ 1 ] / 255, value[ 2 ] / 255 ];
261 |
262 | }
263 |
264 | if ( this.options && this.options.ignoreZeroRGBs ) {
265 |
266 | if ( value[ 0 ] === 0 && value[ 1 ] === 0 && value[ 2 ] === 0 ) {
267 |
268 | // ignore
269 |
270 | save = false;
271 |
272 | }
273 |
274 | }
275 |
276 | break;
277 |
278 | default:
279 |
280 | break;
281 |
282 | }
283 |
284 | if ( save ) {
285 |
286 | covmat[ lprop ] = value;
287 |
288 | }
289 |
290 | }
291 |
292 | }
293 |
294 | return converted;
295 |
296 | },
297 |
298 | preload: function () {
299 |
300 | for ( var mn in this.materialsInfo ) {
301 |
302 | this.create( mn );
303 |
304 | }
305 |
306 | },
307 |
308 | getIndex: function ( materialName ) {
309 |
310 | return this.nameLookup[ materialName ];
311 |
312 | },
313 |
314 | getAsArray: function () {
315 |
316 | var index = 0;
317 |
318 | for ( var mn in this.materialsInfo ) {
319 |
320 | this.materialsArray[ index ] = this.create( mn );
321 | this.nameLookup[ mn ] = index;
322 | index ++;
323 |
324 | }
325 |
326 | return this.materialsArray;
327 |
328 | },
329 |
330 | create: function ( materialName ) {
331 |
332 | if ( this.materials[ materialName ] === undefined ) {
333 |
334 | this.createMaterial_( materialName );
335 |
336 | }
337 |
338 | return this.materials[ materialName ];
339 |
340 | },
341 |
342 | createMaterial_: function ( materialName ) {
343 |
344 | // Create material
345 |
346 | var scope = this;
347 | var mat = this.materialsInfo[ materialName ];
348 | var params = {
349 |
350 | name: materialName,
351 | side: this.side
352 |
353 | };
354 |
355 | function resolveURL( baseUrl, url ) {
356 |
357 | if ( typeof url !== 'string' || url === '' )
358 | return '';
359 |
360 | // Absolute URL
361 | if ( /^https?:\/\//i.test( url ) ) return url;
362 |
363 | return baseUrl + url;
364 |
365 | }
366 |
367 | function setMapForType( mapType, value ) {
368 |
369 | if ( params[ mapType ] ) return; // Keep the first encountered texture
370 |
371 | var texParams = scope.getTextureParams( value, params );
372 | var map = scope.loadTexture( resolveURL( scope.baseUrl, texParams.url ) );
373 |
374 | map.repeat.copy( texParams.scale );
375 | map.offset.copy( texParams.offset );
376 |
377 | map.wrapS = scope.wrap;
378 | map.wrapT = scope.wrap;
379 |
380 | params[ mapType ] = map;
381 |
382 | }
383 |
384 | for ( var prop in mat ) {
385 |
386 | var value = mat[ prop ];
387 | var n;
388 |
389 | if ( value === '' ) continue;
390 |
391 | switch ( prop.toLowerCase() ) {
392 |
393 | // Ns is material specular exponent
394 |
395 | case 'kd':
396 |
397 | // Diffuse color (color under white light) using RGB values
398 |
399 | params.color = new THREE.Color().fromArray( value );
400 |
401 | break;
402 |
403 | case 'ks':
404 |
405 | // Specular color (color when light is reflected from shiny surface) using RGB values
406 | params.specular = new THREE.Color().fromArray( value );
407 |
408 | break;
409 |
410 | case 'map_kd':
411 |
412 | // Diffuse texture map
413 |
414 | setMapForType( "map", value );
415 |
416 | break;
417 |
418 | case 'map_ks':
419 |
420 | // Specular map
421 |
422 | setMapForType( "specularMap", value );
423 |
424 | break;
425 |
426 | case 'norm':
427 |
428 | setMapForType( "normalMap", value );
429 |
430 | break;
431 |
432 | case 'map_bump':
433 | case 'bump':
434 |
435 | // Bump texture map
436 |
437 | setMapForType( "bumpMap", value );
438 |
439 | break;
440 |
441 | case 'ns':
442 |
443 | // The specular exponent (defines the focus of the specular highlight)
444 | // A high exponent results in a tight, concentrated highlight. Ns values normally range from 0 to 1000.
445 |
446 | params.shininess = parseFloat( value );
447 |
448 | break;
449 |
450 | case 'd':
451 | n = parseFloat( value );
452 |
453 | if ( n < 1 ) {
454 |
455 | params.opacity = n;
456 | params.transparent = true;
457 |
458 | }
459 |
460 | break;
461 |
462 | case 'tr':
463 | n = parseFloat( value );
464 |
465 | if ( n > 0 ) {
466 |
467 | params.opacity = 1 - n;
468 | params.transparent = true;
469 |
470 | }
471 |
472 | break;
473 |
474 | default:
475 | break;
476 |
477 | }
478 |
479 | }
480 |
481 | this.materials[ materialName ] = new THREE.MeshPhongMaterial( params );
482 | return this.materials[ materialName ];
483 |
484 | },
485 |
486 | getTextureParams: function ( value, matParams ) {
487 |
488 | var texParams = {
489 |
490 | scale: new THREE.Vector2( 1, 1 ),
491 | offset: new THREE.Vector2( 0, 0 )
492 |
493 | };
494 |
495 | var items = value.split( /\s+/ );
496 | var pos;
497 |
498 | pos = items.indexOf( '-bm' );
499 |
500 | if ( pos >= 0 ) {
501 |
502 | matParams.bumpScale = parseFloat( items[ pos + 1 ] );
503 | items.splice( pos, 2 );
504 |
505 | }
506 |
507 | pos = items.indexOf( '-s' );
508 |
509 | if ( pos >= 0 ) {
510 |
511 | texParams.scale.set( parseFloat( items[ pos + 1 ] ), parseFloat( items[ pos + 2 ] ) );
512 | items.splice( pos, 4 ); // we expect 3 parameters here!
513 |
514 | }
515 |
516 | pos = items.indexOf( '-o' );
517 |
518 | if ( pos >= 0 ) {
519 |
520 | texParams.offset.set( parseFloat( items[ pos + 1 ] ), parseFloat( items[ pos + 2 ] ) );
521 | items.splice( pos, 4 ); // we expect 3 parameters here!
522 |
523 | }
524 |
525 | texParams.url = items.join( ' ' ).trim();
526 | return texParams;
527 |
528 | },
529 |
530 | loadTexture: function ( url, mapping, onLoad, onProgress, onError ) {
531 |
532 | var texture;
533 | var loader = THREE.Loader.Handlers.get( url );
534 | var manager = ( this.manager !== undefined ) ? this.manager : THREE.DefaultLoadingManager;
535 |
536 | if ( loader === null ) {
537 |
538 | loader = new THREE.TextureLoader( manager );
539 |
540 | }
541 |
542 | if ( loader.setCrossOrigin ) loader.setCrossOrigin( this.crossOrigin );
543 | texture = loader.load( url, onLoad, onProgress, onError );
544 |
545 | if ( mapping !== undefined ) texture.mapping = mapping;
546 |
547 | return texture;
548 |
549 | }
550 |
551 | };
552 |
--------------------------------------------------------------------------------
/bulid/OBJLoader.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author mrdoob / http://mrdoob.com/
3 | */
4 |
5 | THREE.OBJLoader = ( function () {
6 |
7 | // o object_name | g group_name
8 | var object_pattern = /^[og]\s*(.+)?/;
9 | // mtllib file_reference
10 | var material_library_pattern = /^mtllib /;
11 | // usemtl material_name
12 | var material_use_pattern = /^usemtl /;
13 |
14 | function ParserState() {
15 |
16 | var state = {
17 | objects: [],
18 | object: {},
19 |
20 | vertices: [],
21 | normals: [],
22 | colors: [],
23 | uvs: [],
24 |
25 | materialLibraries: [],
26 |
27 | startObject: function ( name, fromDeclaration ) {
28 |
29 | // If the current object (initial from reset) is not from a g/o declaration in the parsed
30 | // file. We need to use it for the first parsed g/o to keep things in sync.
31 | if ( this.object && this.object.fromDeclaration === false ) {
32 |
33 | this.object.name = name;
34 | this.object.fromDeclaration = ( fromDeclaration !== false );
35 | return;
36 |
37 | }
38 |
39 | var previousMaterial = ( this.object && typeof this.object.currentMaterial === 'function' ? this.object.currentMaterial() : undefined );
40 |
41 | if ( this.object && typeof this.object._finalize === 'function' ) {
42 |
43 | this.object._finalize( true );
44 |
45 | }
46 |
47 | this.object = {
48 | name: name || '',
49 | fromDeclaration: ( fromDeclaration !== false ),
50 |
51 | geometry: {
52 | vertices: [],
53 | normals: [],
54 | colors: [],
55 | uvs: []
56 | },
57 | materials: [],
58 | smooth: true,
59 |
60 | startMaterial: function ( name, libraries ) {
61 |
62 | var previous = this._finalize( false );
63 |
64 | // New usemtl declaration overwrites an inherited material, except if faces were declared
65 | // after the material, then it must be preserved for proper MultiMaterial continuation.
66 | if ( previous && ( previous.inherited || previous.groupCount <= 0 ) ) {
67 |
68 | this.materials.splice( previous.index, 1 );
69 |
70 | }
71 |
72 | var material = {
73 | index: this.materials.length,
74 | name: name || '',
75 | mtllib: ( Array.isArray( libraries ) && libraries.length > 0 ? libraries[ libraries.length - 1 ] : '' ),
76 | smooth: ( previous !== undefined ? previous.smooth : this.smooth ),
77 | groupStart: ( previous !== undefined ? previous.groupEnd : 0 ),
78 | groupEnd: - 1,
79 | groupCount: - 1,
80 | inherited: false,
81 |
82 | clone: function ( index ) {
83 |
84 | var cloned = {
85 | index: ( typeof index === 'number' ? index : this.index ),
86 | name: this.name,
87 | mtllib: this.mtllib,
88 | smooth: this.smooth,
89 | groupStart: 0,
90 | groupEnd: - 1,
91 | groupCount: - 1,
92 | inherited: false
93 | };
94 | cloned.clone = this.clone.bind( cloned );
95 | return cloned;
96 |
97 | }
98 | };
99 |
100 | this.materials.push( material );
101 |
102 | return material;
103 |
104 | },
105 |
106 | currentMaterial: function () {
107 |
108 | if ( this.materials.length > 0 ) {
109 |
110 | return this.materials[ this.materials.length - 1 ];
111 |
112 | }
113 |
114 | return undefined;
115 |
116 | },
117 |
118 | _finalize: function ( end ) {
119 |
120 | var lastMultiMaterial = this.currentMaterial();
121 | if ( lastMultiMaterial && lastMultiMaterial.groupEnd === - 1 ) {
122 |
123 | lastMultiMaterial.groupEnd = this.geometry.vertices.length / 3;
124 | lastMultiMaterial.groupCount = lastMultiMaterial.groupEnd - lastMultiMaterial.groupStart;
125 | lastMultiMaterial.inherited = false;
126 |
127 | }
128 |
129 | // Ignore objects tail materials if no face declarations followed them before a new o/g started.
130 | if ( end && this.materials.length > 1 ) {
131 |
132 | for ( var mi = this.materials.length - 1; mi >= 0; mi -- ) {
133 |
134 | if ( this.materials[ mi ].groupCount <= 0 ) {
135 |
136 | this.materials.splice( mi, 1 );
137 |
138 | }
139 |
140 | }
141 |
142 | }
143 |
144 | // Guarantee at least one empty material, this makes the creation later more straight forward.
145 | if ( end && this.materials.length === 0 ) {
146 |
147 | this.materials.push( {
148 | name: '',
149 | smooth: this.smooth
150 | } );
151 |
152 | }
153 |
154 | return lastMultiMaterial;
155 |
156 | }
157 | };
158 |
159 | // Inherit previous objects material.
160 | // Spec tells us that a declared material must be set to all objects until a new material is declared.
161 | // If a usemtl declaration is encountered while this new object is being parsed, it will
162 | // overwrite the inherited material. Exception being that there was already face declarations
163 | // to the inherited material, then it will be preserved for proper MultiMaterial continuation.
164 |
165 | if ( previousMaterial && previousMaterial.name && typeof previousMaterial.clone === 'function' ) {
166 |
167 | var declared = previousMaterial.clone( 0 );
168 | declared.inherited = true;
169 | this.object.materials.push( declared );
170 |
171 | }
172 |
173 | this.objects.push( this.object );
174 |
175 | },
176 |
177 | finalize: function () {
178 |
179 | if ( this.object && typeof this.object._finalize === 'function' ) {
180 |
181 | this.object._finalize( true );
182 |
183 | }
184 |
185 | },
186 |
187 | parseVertexIndex: function ( value, len ) {
188 |
189 | var index = parseInt( value, 10 );
190 | return ( index >= 0 ? index - 1 : index + len / 3 ) * 3;
191 |
192 | },
193 |
194 | parseNormalIndex: function ( value, len ) {
195 |
196 | var index = parseInt( value, 10 );
197 | return ( index >= 0 ? index - 1 : index + len / 3 ) * 3;
198 |
199 | },
200 |
201 | parseUVIndex: function ( value, len ) {
202 |
203 | var index = parseInt( value, 10 );
204 | return ( index >= 0 ? index - 1 : index + len / 2 ) * 2;
205 |
206 | },
207 |
208 | addVertex: function ( a, b, c ) {
209 |
210 | var src = this.vertices;
211 | var dst = this.object.geometry.vertices;
212 |
213 | dst.push( src[ a + 0 ], src[ a + 1 ], src[ a + 2 ] );
214 | dst.push( src[ b + 0 ], src[ b + 1 ], src[ b + 2 ] );
215 | dst.push( src[ c + 0 ], src[ c + 1 ], src[ c + 2 ] );
216 |
217 | },
218 |
219 | addVertexLine: function ( a ) {
220 |
221 | var src = this.vertices;
222 | var dst = this.object.geometry.vertices;
223 |
224 | dst.push( src[ a + 0 ], src[ a + 1 ], src[ a + 2 ] );
225 |
226 | },
227 |
228 | addNormal: function ( a, b, c ) {
229 |
230 | var src = this.normals;
231 | var dst = this.object.geometry.normals;
232 |
233 | dst.push( src[ a + 0 ], src[ a + 1 ], src[ a + 2 ] );
234 | dst.push( src[ b + 0 ], src[ b + 1 ], src[ b + 2 ] );
235 | dst.push( src[ c + 0 ], src[ c + 1 ], src[ c + 2 ] );
236 |
237 | },
238 |
239 | addColor: function ( a, b, c ) {
240 |
241 | var src = this.colors;
242 | var dst = this.object.geometry.colors;
243 |
244 | dst.push( src[ a + 0 ], src[ a + 1 ], src[ a + 2 ] );
245 | dst.push( src[ b + 0 ], src[ b + 1 ], src[ b + 2 ] );
246 | dst.push( src[ c + 0 ], src[ c + 1 ], src[ c + 2 ] );
247 |
248 | },
249 |
250 | addUV: function ( a, b, c ) {
251 |
252 | var src = this.uvs;
253 | var dst = this.object.geometry.uvs;
254 |
255 | dst.push( src[ a + 0 ], src[ a + 1 ] );
256 | dst.push( src[ b + 0 ], src[ b + 1 ] );
257 | dst.push( src[ c + 0 ], src[ c + 1 ] );
258 |
259 | },
260 |
261 | addUVLine: function ( a ) {
262 |
263 | var src = this.uvs;
264 | var dst = this.object.geometry.uvs;
265 |
266 | dst.push( src[ a + 0 ], src[ a + 1 ] );
267 |
268 | },
269 |
270 | addFace: function ( a, b, c, ua, ub, uc, na, nb, nc ) {
271 |
272 | var vLen = this.vertices.length;
273 |
274 | var ia = this.parseVertexIndex( a, vLen );
275 | var ib = this.parseVertexIndex( b, vLen );
276 | var ic = this.parseVertexIndex( c, vLen );
277 |
278 | this.addVertex( ia, ib, ic );
279 |
280 | if ( ua !== undefined ) {
281 |
282 | var uvLen = this.uvs.length;
283 |
284 | ia = this.parseUVIndex( ua, uvLen );
285 | ib = this.parseUVIndex( ub, uvLen );
286 | ic = this.parseUVIndex( uc, uvLen );
287 |
288 | this.addUV( ia, ib, ic );
289 |
290 | }
291 |
292 | if ( na !== undefined ) {
293 |
294 | // Normals are many times the same. If so, skip function call and parseInt.
295 | var nLen = this.normals.length;
296 | ia = this.parseNormalIndex( na, nLen );
297 |
298 | ib = na === nb ? ia : this.parseNormalIndex( nb, nLen );
299 | ic = na === nc ? ia : this.parseNormalIndex( nc, nLen );
300 |
301 | this.addNormal( ia, ib, ic );
302 |
303 | }
304 |
305 | if ( this.colors.length > 0 ) {
306 |
307 | this.addColor( ia, ib, ic );
308 |
309 | }
310 |
311 | },
312 |
313 | addLineGeometry: function ( vertices, uvs ) {
314 |
315 | this.object.geometry.type = 'Line';
316 |
317 | var vLen = this.vertices.length;
318 | var uvLen = this.uvs.length;
319 |
320 | for ( var vi = 0, l = vertices.length; vi < l; vi ++ ) {
321 |
322 | this.addVertexLine( this.parseVertexIndex( vertices[ vi ], vLen ) );
323 |
324 | }
325 |
326 | for ( var uvi = 0, l = uvs.length; uvi < l; uvi ++ ) {
327 |
328 | this.addUVLine( this.parseUVIndex( uvs[ uvi ], uvLen ) );
329 |
330 | }
331 |
332 | }
333 |
334 | };
335 |
336 | state.startObject( '', false );
337 |
338 | return state;
339 |
340 | }
341 |
342 | //
343 |
344 | function OBJLoader( manager ) {
345 |
346 | this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
347 |
348 | this.materials = null;
349 |
350 | }
351 |
352 | OBJLoader.prototype = {
353 |
354 | constructor: OBJLoader,
355 |
356 | load: function ( url, onLoad, onProgress, onError ) {
357 |
358 | var scope = this;
359 |
360 | var loader = new THREE.FileLoader( scope.manager );
361 | loader.setPath( this.path );
362 | loader.load( url, function ( text ) {
363 |
364 | onLoad( scope.parse( text ) );
365 |
366 | }, onProgress, onError );
367 |
368 | },
369 |
370 | setPath: function ( value ) {
371 |
372 | this.path = value;
373 |
374 | },
375 |
376 | setMaterials: function ( materials ) {
377 |
378 | this.materials = materials;
379 |
380 | return this;
381 |
382 | },
383 |
384 | parse: function ( text ) {
385 |
386 | console.time( 'OBJLoader' );
387 |
388 | var state = new ParserState();
389 |
390 | if ( text.indexOf( '\r\n' ) !== - 1 ) {
391 |
392 | // This is faster than String.split with regex that splits on both
393 | text = text.replace( /\r\n/g, '\n' );
394 |
395 | }
396 |
397 | if ( text.indexOf( '\\\n' ) !== - 1 ) {
398 |
399 | // join lines separated by a line continuation character (\)
400 | text = text.replace( /\\\n/g, '' );
401 |
402 | }
403 |
404 | var lines = text.split( '\n' );
405 | var line = '', lineFirstChar = '';
406 | var lineLength = 0;
407 | var result = [];
408 |
409 | // Faster to just trim left side of the line. Use if available.
410 | var trimLeft = ( typeof ''.trimLeft === 'function' );
411 |
412 | for ( var i = 0, l = lines.length; i < l; i ++ ) {
413 |
414 | line = lines[ i ];
415 |
416 | line = trimLeft ? line.trimLeft() : line.trim();
417 |
418 | lineLength = line.length;
419 |
420 | if ( lineLength === 0 ) continue;
421 |
422 | lineFirstChar = line.charAt( 0 );
423 |
424 | // @todo invoke passed in handler if any
425 | if ( lineFirstChar === '#' ) continue;
426 |
427 | if ( lineFirstChar === 'v' ) {
428 |
429 | var data = line.split( /\s+/ );
430 |
431 | switch ( data[ 0 ] ) {
432 |
433 | case 'v':
434 | state.vertices.push(
435 | parseFloat( data[ 1 ] ),
436 | parseFloat( data[ 2 ] ),
437 | parseFloat( data[ 3 ] )
438 | );
439 | if ( data.length === 8 ) {
440 |
441 | state.colors.push(
442 | parseFloat( data[ 4 ] ),
443 | parseFloat( data[ 5 ] ),
444 | parseFloat( data[ 6 ] )
445 |
446 | );
447 |
448 | }
449 | break;
450 | case 'vn':
451 | state.normals.push(
452 | parseFloat( data[ 1 ] ),
453 | parseFloat( data[ 2 ] ),
454 | parseFloat( data[ 3 ] )
455 | );
456 | break;
457 | case 'vt':
458 | state.uvs.push(
459 | parseFloat( data[ 1 ] ),
460 | parseFloat( data[ 2 ] )
461 | );
462 | break;
463 |
464 | }
465 |
466 | } else if ( lineFirstChar === 'f' ) {
467 |
468 | var lineData = line.substr( 1 ).trim();
469 | var vertexData = lineData.split( /\s+/ );
470 | var faceVertices = [];
471 |
472 | // Parse the face vertex data into an easy to work with format
473 |
474 | for ( var j = 0, jl = vertexData.length; j < jl; j ++ ) {
475 |
476 | var vertex = vertexData[ j ];
477 |
478 | if ( vertex.length > 0 ) {
479 |
480 | var vertexParts = vertex.split( '/' );
481 | faceVertices.push( vertexParts );
482 |
483 | }
484 |
485 | }
486 |
487 | // Draw an edge between the first vertex and all subsequent vertices to form an n-gon
488 |
489 | var v1 = faceVertices[ 0 ];
490 |
491 | for ( var j = 1, jl = faceVertices.length - 1; j < jl; j ++ ) {
492 |
493 | var v2 = faceVertices[ j ];
494 | var v3 = faceVertices[ j + 1 ];
495 |
496 | state.addFace(
497 | v1[ 0 ], v2[ 0 ], v3[ 0 ],
498 | v1[ 1 ], v2[ 1 ], v3[ 1 ],
499 | v1[ 2 ], v2[ 2 ], v3[ 2 ]
500 | );
501 |
502 | }
503 |
504 | } else if ( lineFirstChar === 'l' ) {
505 |
506 | var lineParts = line.substring( 1 ).trim().split( " " );
507 | var lineVertices = [], lineUVs = [];
508 |
509 | if ( line.indexOf( "/" ) === - 1 ) {
510 |
511 | lineVertices = lineParts;
512 |
513 | } else {
514 |
515 | for ( var li = 0, llen = lineParts.length; li < llen; li ++ ) {
516 |
517 | var parts = lineParts[ li ].split( "/" );
518 |
519 | if ( parts[ 0 ] !== "" ) lineVertices.push( parts[ 0 ] );
520 | if ( parts[ 1 ] !== "" ) lineUVs.push( parts[ 1 ] );
521 |
522 | }
523 |
524 | }
525 | state.addLineGeometry( lineVertices, lineUVs );
526 |
527 | } else if ( ( result = object_pattern.exec( line ) ) !== null ) {
528 |
529 | // o object_name
530 | // or
531 | // g group_name
532 |
533 | // WORKAROUND: https://bugs.chromium.org/p/v8/issues/detail?id=2869
534 | // var name = result[ 0 ].substr( 1 ).trim();
535 | var name = ( " " + result[ 0 ].substr( 1 ).trim() ).substr( 1 );
536 |
537 | state.startObject( name );
538 |
539 | } else if ( material_use_pattern.test( line ) ) {
540 |
541 | // material
542 |
543 | state.object.startMaterial( line.substring( 7 ).trim(), state.materialLibraries );
544 |
545 | } else if ( material_library_pattern.test( line ) ) {
546 |
547 | // mtl file
548 |
549 | state.materialLibraries.push( line.substring( 7 ).trim() );
550 |
551 | } else if ( lineFirstChar === 's' ) {
552 |
553 | result = line.split( ' ' );
554 |
555 | // smooth shading
556 |
557 | // @todo Handle files that have varying smooth values for a set of faces inside one geometry,
558 | // but does not define a usemtl for each face set.
559 | // This should be detected and a dummy material created (later MultiMaterial and geometry groups).
560 | // This requires some care to not create extra material on each smooth value for "normal" obj files.
561 | // where explicit usemtl defines geometry groups.
562 | // Example asset: examples/models/obj/cerberus/Cerberus.obj
563 |
564 | /*
565 | * http://paulbourke.net/dataformats/obj/
566 | * or
567 | * http://www.cs.utah.edu/~boulos/cs3505/obj_spec.pdf
568 | *
569 | * From chapter "Grouping" Syntax explanation "s group_number":
570 | * "group_number is the smoothing group number. To turn off smoothing groups, use a value of 0 or off.
571 | * Polygonal elements use group numbers to put elements in different smoothing groups. For free-form
572 | * surfaces, smoothing groups are either turned on or off; there is no difference between values greater
573 | * than 0."
574 | */
575 | if ( result.length > 1 ) {
576 |
577 | var value = result[ 1 ].trim().toLowerCase();
578 | state.object.smooth = ( value !== '0' && value !== 'off' );
579 |
580 | } else {
581 |
582 | // ZBrush can produce "s" lines #11707
583 | state.object.smooth = true;
584 |
585 | }
586 | var material = state.object.currentMaterial();
587 | if ( material ) material.smooth = state.object.smooth;
588 |
589 | } else {
590 |
591 | // Handle null terminated files without exception
592 | if ( line === '\0' ) continue;
593 |
594 | throw new Error( 'THREE.OBJLoader: Unexpected line: "' + line + '"' );
595 |
596 | }
597 |
598 | }
599 |
600 | state.finalize();
601 |
602 | var container = new THREE.Group();
603 | container.materialLibraries = [].concat( state.materialLibraries );
604 |
605 | for ( var i = 0, l = state.objects.length; i < l; i ++ ) {
606 |
607 | var object = state.objects[ i ];
608 | var geometry = object.geometry;
609 | var materials = object.materials;
610 | var isLine = ( geometry.type === 'Line' );
611 |
612 | // Skip o/g line declarations that did not follow with any faces
613 | if ( geometry.vertices.length === 0 ) continue;
614 |
615 | var buffergeometry = new THREE.BufferGeometry();
616 |
617 | buffergeometry.addAttribute( 'position', new THREE.Float32BufferAttribute( geometry.vertices, 3 ) );
618 |
619 | if ( geometry.normals.length > 0 ) {
620 |
621 | buffergeometry.addAttribute( 'normal', new THREE.Float32BufferAttribute( geometry.normals, 3 ) );
622 |
623 | } else {
624 |
625 | buffergeometry.computeVertexNormals();
626 |
627 | }
628 |
629 | if ( geometry.colors.length > 0 ) {
630 |
631 | buffergeometry.addAttribute( 'color', new THREE.Float32BufferAttribute( geometry.colors, 3 ) );
632 |
633 | }
634 |
635 | if ( geometry.uvs.length > 0 ) {
636 |
637 | buffergeometry.addAttribute( 'uv', new THREE.Float32BufferAttribute( geometry.uvs, 2 ) );
638 |
639 | }
640 |
641 | // Create materials
642 |
643 | var createdMaterials = [];
644 |
645 | for ( var mi = 0, miLen = materials.length; mi < miLen; mi ++ ) {
646 |
647 | var sourceMaterial = materials[ mi ];
648 | var material = undefined;
649 |
650 | if ( this.materials !== null ) {
651 |
652 | material = this.materials.create( sourceMaterial.name );
653 |
654 | // mtl etc. loaders probably can't create line materials correctly, copy properties to a line material.
655 | if ( isLine && material && ! ( material instanceof THREE.LineBasicMaterial ) ) {
656 |
657 | var materialLine = new THREE.LineBasicMaterial();
658 | materialLine.copy( material );
659 | material = materialLine;
660 |
661 | }
662 |
663 | }
664 |
665 | if ( ! material ) {
666 |
667 | material = ( ! isLine ? new THREE.MeshPhongMaterial() : new THREE.LineBasicMaterial() );
668 | material.name = sourceMaterial.name;
669 |
670 | }
671 |
672 | material.flatShading = sourceMaterial.smooth ? false : true;
673 |
674 | createdMaterials.push( material );
675 |
676 | }
677 |
678 | // Create mesh
679 |
680 | var mesh;
681 |
682 | if ( createdMaterials.length > 1 ) {
683 |
684 | for ( var mi = 0, miLen = materials.length; mi < miLen; mi ++ ) {
685 |
686 | var sourceMaterial = materials[ mi ];
687 | buffergeometry.addGroup( sourceMaterial.groupStart, sourceMaterial.groupCount, mi );
688 |
689 | }
690 |
691 | mesh = ( ! isLine ? new THREE.Mesh( buffergeometry, createdMaterials ) : new THREE.LineSegments( buffergeometry, createdMaterials ) );
692 |
693 | } else {
694 |
695 | mesh = ( ! isLine ? new THREE.Mesh( buffergeometry, createdMaterials[ 0 ] ) : new THREE.LineSegments( buffergeometry, createdMaterials[ 0 ] ) );
696 |
697 | }
698 |
699 | mesh.name = object.name;
700 |
701 | container.add( mesh );
702 |
703 | }
704 |
705 | console.timeEnd( 'OBJLoader' );
706 |
707 | return container;
708 |
709 | }
710 |
711 | };
712 |
713 | return OBJLoader;
714 |
715 | } )();
716 |
--------------------------------------------------------------------------------