OBJLoader.js 9.6 KB

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