OBJLoader.js 9.8 KB

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