OBJLoader.js 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428
  1. /**
  2. * @author mrdoob / http://mrdoob.com/
  3. */
  4. THREE.OBJLoader = function () {
  5. THREE.EventDispatcher.call( this );
  6. };
  7. THREE.OBJLoader.prototype = {
  8. constructor: THREE.OBJLoader,
  9. load: function ( url, callback ) {
  10. var scope = this;
  11. var request = new XMLHttpRequest();
  12. request.addEventListener( 'load', function ( event ) {
  13. var hierarchy = scope.parse( event.target.responseText );
  14. scope.dispatchEvent( { type: 'load', content: hierarchy } );
  15. if ( callback ) callback( hierarchy );
  16. }, false );
  17. request.addEventListener( 'progress', function ( event ) {
  18. scope.dispatchEvent( { type: 'progress', loaded: event.loaded, total: event.total } );
  19. }, false );
  20. request.addEventListener( 'error', function () {
  21. scope.dispatchEvent( { type: 'error', message: 'Couldn\'t load URL [' + url + ']' } );
  22. }, false );
  23. request.open( 'GET', url, true );
  24. request.send( null );
  25. },
  26. parse: function ( data ) {
  27. // fixes
  28. data = data.replace( /\ \\\r\n/g, '' ); // rhino adds ' \\r\n' some times.
  29. //
  30. function vector( x, y, z ) {
  31. return new THREE.Vector3( x, y, z );
  32. }
  33. function uv( u, v ) {
  34. return new THREE.Vector2( u, v );
  35. }
  36. function face3( a, b, c, normals ) {
  37. return new THREE.Face3( a, b, c, normals );
  38. }
  39. function face4( a, b, c, d, normals ) {
  40. return new THREE.Face4( a, b, c, d, normals );
  41. }
  42. function meshN( meshName, materialName ) {
  43. if ( geometry.vertices.length > 0 ) {
  44. geometry.mergeVertices();
  45. geometry.computeCentroids();
  46. geometry.computeFaceNormals();
  47. geometry.computeBoundingSphere();
  48. object.add( mesh );
  49. geometry = new THREE.Geometry();
  50. mesh = new THREE.Mesh( geometry, material );
  51. verticesCount = 0;
  52. }
  53. if ( meshName !== undefined ) mesh.name = meshName;
  54. if ( materialName !== undefined ) {
  55. material = new THREE.MeshLambertMaterial();
  56. material.name = materialName;
  57. mesh.material = material;
  58. }
  59. }
  60. var group = new THREE.Object3D();
  61. var object = group;
  62. var geometry = new THREE.Geometry();
  63. var material = new THREE.MeshLambertMaterial();
  64. var mesh = new THREE.Mesh( geometry, material );
  65. var vertices = [];
  66. var verticesCount = 0;
  67. var normals = [];
  68. var uvs = [];
  69. // v float float float
  70. var vertex_pattern = /v( +[\d|\.|\+|\-|e]+)( [\d|\.|\+|\-|e]+)( [\d|\.|\+|\-|e]+)/;
  71. // vn float float float
  72. var normal_pattern = /vn( +[\d|\.|\+|\-|e]+)( [\d|\.|\+|\-|e]+)( [\d|\.|\+|\-|e]+)/;
  73. // vt float float
  74. var uv_pattern = /vt( +[\d|\.|\+|\-|e]+)( [\d|\.|\+|\-|e]+)/;
  75. // f vertex vertex vertex ...
  76. var face_pattern1 = /f( +[\d]+)( [\d]+)( [\d]+)( [\d]+)?/;
  77. // f vertex/uv vertex/uv vertex/uv ...
  78. var face_pattern2 = /f( +([\d]+)\/([\d]+))( ([\d]+)\/([\d]+))( ([\d]+)\/([\d]+))( ([\d]+)\/([\d]+))?/;
  79. // f vertex/uv/normal vertex/uv/normal vertex/uv/normal ...
  80. var face_pattern3 = /f( +([\d]+)\/([\d]+)\/([\d]+))( ([\d]+)\/([\d]+)\/([\d]+))( ([\d]+)\/([\d]+)\/([\d]+))( ([\d]+)\/([\d]+)\/([\d]+))?/;
  81. // f vertex//normal vertex//normal vertex//normal ...
  82. var face_pattern4 = /f( +([\d]+)\/\/([\d]+))( ([\d]+)\/\/([\d]+))( ([\d]+)\/\/([\d]+))( ([\d]+)\/\/([\d]+))?/;
  83. //
  84. var lines = data.split( "\n" );
  85. for ( var i = 0; i < lines.length; i ++ ) {
  86. var line = lines[ i ];
  87. line = line.trim();
  88. var result;
  89. if ( line.length === 0 || line.charAt( 0 ) === '#' ) {
  90. continue;
  91. } else if ( ( result = vertex_pattern.exec( line ) ) !== null ) {
  92. // ["v 1.0 2.0 3.0", "1.0", "2.0", "3.0"]
  93. vertices.push( vector(
  94. parseFloat( result[ 1 ] ),
  95. parseFloat( result[ 2 ] ),
  96. parseFloat( result[ 3 ] )
  97. ) );
  98. } else if ( ( result = normal_pattern.exec( line ) ) !== null ) {
  99. // ["vn 1.0 2.0 3.0", "1.0", "2.0", "3.0"]
  100. normals.push( vector(
  101. parseFloat( result[ 1 ] ),
  102. parseFloat( result[ 2 ] ),
  103. parseFloat( result[ 3 ] )
  104. ) );
  105. } else if ( ( result = uv_pattern.exec( line ) ) !== null ) {
  106. // ["vt 0.1 0.2", "0.1", "0.2"]
  107. uvs.push( uv(
  108. parseFloat( result[ 1 ] ),
  109. parseFloat( result[ 2 ] )
  110. ) );
  111. } else if ( ( result = face_pattern1.exec( line ) ) !== null ) {
  112. // ["f 1 2 3", "1", "2", "3", undefined]
  113. if ( result[ 4 ] === undefined ) {
  114. geometry.vertices.push(
  115. vertices[ parseInt( result[ 1 ] ) - 1 ],
  116. vertices[ parseInt( result[ 2 ] ) - 1 ],
  117. vertices[ parseInt( result[ 3 ] ) - 1 ]
  118. );
  119. geometry.faces.push( face3(
  120. verticesCount ++,
  121. verticesCount ++,
  122. verticesCount ++
  123. ) );
  124. } else {
  125. geometry.vertices.push(
  126. vertices[ parseInt( result[ 1 ] ) - 1 ],
  127. vertices[ parseInt( result[ 2 ] ) - 1 ],
  128. vertices[ parseInt( result[ 3 ] ) - 1 ],
  129. vertices[ parseInt( result[ 4 ] ) - 1 ]
  130. );
  131. geometry.faces.push( face4(
  132. verticesCount ++,
  133. verticesCount ++,
  134. verticesCount ++,
  135. verticesCount ++
  136. ) );
  137. }
  138. } else if ( ( result = face_pattern2.exec( line ) ) !== null ) {
  139. // ["f 1/1 2/2 3/3", " 1/1", "1", "1", " 2/2", "2", "2", " 3/3", "3", "3", undefined, undefined, undefined]
  140. if ( result[ 10 ] === undefined ) {
  141. geometry.vertices.push(
  142. vertices[ parseInt( result[ 2 ] ) - 1 ],
  143. vertices[ parseInt( result[ 5 ] ) - 1 ],
  144. vertices[ parseInt( result[ 8 ] ) - 1 ]
  145. );
  146. geometry.faces.push( face3(
  147. verticesCount ++,
  148. verticesCount ++,
  149. verticesCount ++
  150. ) );
  151. geometry.faceVertexUvs[ 0 ].push( [
  152. uvs[ parseInt( result[ 3 ] ) - 1 ],
  153. uvs[ parseInt( result[ 6 ] ) - 1 ],
  154. uvs[ parseInt( result[ 9 ] ) - 1 ]
  155. ] );
  156. } else {
  157. geometry.vertices.push(
  158. vertices[ parseInt( result[ 2 ] ) - 1 ],
  159. vertices[ parseInt( result[ 5 ] ) - 1 ],
  160. vertices[ parseInt( result[ 8 ] ) - 1 ],
  161. vertices[ parseInt( result[ 11 ] ) - 1 ]
  162. );
  163. geometry.faces.push( face4(
  164. verticesCount ++,
  165. verticesCount ++,
  166. verticesCount ++,
  167. verticesCount ++
  168. ) );
  169. geometry.faceVertexUvs[ 0 ].push( [
  170. uvs[ parseInt( result[ 3 ] ) - 1 ],
  171. uvs[ parseInt( result[ 6 ] ) - 1 ],
  172. uvs[ parseInt( result[ 9 ] ) - 1 ],
  173. uvs[ parseInt( result[ 12 ] ) - 1 ]
  174. ] );
  175. }
  176. } else if ( ( result = face_pattern3.exec( line ) ) !== null ) {
  177. // ["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]
  178. if ( result[ 13 ] === undefined ) {
  179. geometry.vertices.push(
  180. vertices[ parseInt( result[ 2 ] ) - 1 ],
  181. vertices[ parseInt( result[ 6 ] ) - 1 ],
  182. vertices[ parseInt( result[ 10 ] ) - 1 ]
  183. );
  184. geometry.faces.push( face3(
  185. verticesCount ++,
  186. verticesCount ++,
  187. verticesCount ++,
  188. [
  189. normals[ parseInt( result[ 4 ] ) - 1 ],
  190. normals[ parseInt( result[ 8 ] ) - 1 ],
  191. normals[ parseInt( result[ 12 ] ) - 1 ]
  192. ]
  193. ) );
  194. geometry.faceVertexUvs[ 0 ].push( [
  195. uvs[ parseInt( result[ 3 ] ) - 1 ],
  196. uvs[ parseInt( result[ 7 ] ) - 1 ],
  197. uvs[ parseInt( result[ 11 ] ) - 1 ]
  198. ] );
  199. } else {
  200. geometry.vertices.push(
  201. vertices[ parseInt( result[ 2 ] ) - 1 ],
  202. vertices[ parseInt( result[ 6 ] ) - 1 ],
  203. vertices[ parseInt( result[ 10 ] ) - 1 ],
  204. vertices[ parseInt( result[ 14 ] ) - 1 ]
  205. );
  206. geometry.faces.push( face4(
  207. verticesCount ++,
  208. verticesCount ++,
  209. verticesCount ++,
  210. verticesCount ++,
  211. [
  212. normals[ parseInt( result[ 4 ] ) - 1 ],
  213. normals[ parseInt( result[ 8 ] ) - 1 ],
  214. normals[ parseInt( result[ 12 ] ) - 1 ],
  215. normals[ parseInt( result[ 16 ] ) - 1 ]
  216. ]
  217. ) );
  218. geometry.faceVertexUvs[ 0 ].push( [
  219. uvs[ parseInt( result[ 3 ] ) - 1 ],
  220. uvs[ parseInt( result[ 7 ] ) - 1 ],
  221. uvs[ parseInt( result[ 11 ] ) - 1 ],
  222. uvs[ parseInt( result[ 15 ] ) - 1 ]
  223. ] );
  224. }
  225. } else if ( ( result = face_pattern4.exec( line ) ) !== null ) {
  226. // ["f 1//1 2//2 3//3", " 1//1", "1", "1", " 2//2", "2", "2", " 3//3", "3", "3", undefined, undefined, undefined]
  227. if ( result[ 10 ] === undefined ) {
  228. geometry.vertices.push(
  229. vertices[ parseInt( result[ 2 ] ) - 1 ],
  230. vertices[ parseInt( result[ 5 ] ) - 1 ],
  231. vertices[ parseInt( result[ 8 ] ) - 1 ]
  232. );
  233. geometry.faces.push( face3(
  234. verticesCount ++,
  235. verticesCount ++,
  236. verticesCount ++,
  237. [
  238. normals[ parseInt( result[ 3 ] ) - 1 ],
  239. normals[ parseInt( result[ 6 ] ) - 1 ],
  240. normals[ parseInt( result[ 9 ] ) - 1 ]
  241. ]
  242. ) );
  243. } else {
  244. geometry.vertices.push(
  245. vertices[ parseInt( result[ 2 ] ) - 1 ],
  246. vertices[ parseInt( result[ 5 ] ) - 1 ],
  247. vertices[ parseInt( result[ 8 ] ) - 1 ],
  248. vertices[ parseInt( result[ 11 ] ) - 1 ]
  249. );
  250. geometry.faces.push( face4(
  251. verticesCount ++,
  252. verticesCount ++,
  253. verticesCount ++,
  254. verticesCount ++,
  255. [
  256. normals[ parseInt( result[ 3 ] ) - 1 ],
  257. normals[ parseInt( result[ 6 ] ) - 1 ],
  258. normals[ parseInt( result[ 9 ] ) - 1 ],
  259. normals[ parseInt( result[ 12 ] ) - 1 ]
  260. ]
  261. ) );
  262. }
  263. } else if ( line.startsWith( "o " ) ) {
  264. // object
  265. object = new THREE.Object3D();
  266. object.name = line.substring( 2 ).trim();
  267. group.add( object );
  268. } else if ( line.startsWith( "g " ) ) {
  269. // group
  270. meshN( line.substring( 2 ).trim(), undefined );
  271. } else if ( line.startsWith( "usemtl " ) ) {
  272. // material
  273. meshN( undefined, line.substring( 7 ).trim() );
  274. } else if ( line.startsWith( "mtllib ") ) {
  275. // mtl file
  276. } else if ( line.startsWith( "s ") ) {
  277. // smooth shading
  278. } else {
  279. // console.log( "THREE.OBJLoader: Unhandled line " + line );
  280. }
  281. }
  282. // add the last group
  283. meshN( undefined, undefined );
  284. return group;
  285. }
  286. }