Spaces:
Running
Running
| /** | |
| * @author mrdoob / http://mrdoob.com/ | |
| */ | |
| import { | |
| BufferGeometry, | |
| Geometry, | |
| Line, | |
| Matrix3, | |
| Mesh, | |
| Vector2, | |
| Vector3 | |
| } from "../../../build/three.module.js"; | |
| var OBJExporter = function () {}; | |
| OBJExporter.prototype = { | |
| constructor: OBJExporter, | |
| parse: function ( object ) { | |
| var output = ''; | |
| var indexVertex = 0; | |
| var indexVertexUvs = 0; | |
| var indexNormals = 0; | |
| var vertex = new Vector3(); | |
| var normal = new Vector3(); | |
| var uv = new Vector2(); | |
| var i, j, k, l, m, face = []; | |
| var parseMesh = function ( mesh ) { | |
| var nbVertex = 0; | |
| var nbNormals = 0; | |
| var nbVertexUvs = 0; | |
| var geometry = mesh.geometry; | |
| var normalMatrixWorld = new Matrix3(); | |
| if ( geometry instanceof Geometry ) { | |
| geometry = new BufferGeometry().setFromObject( mesh ); | |
| } | |
| if ( geometry instanceof BufferGeometry ) { | |
| // shortcuts | |
| var vertices = geometry.getAttribute( 'position' ); | |
| var normals = geometry.getAttribute( 'normal' ); | |
| var uvs = geometry.getAttribute( 'uv' ); | |
| var indices = geometry.getIndex(); | |
| // name of the mesh object | |
| output += 'o ' + mesh.name + '\n'; | |
| // name of the mesh material | |
| if ( mesh.material && mesh.material.name ) { | |
| output += 'usemtl ' + mesh.material.name + '\n'; | |
| } | |
| // vertices | |
| if ( vertices !== undefined ) { | |
| for ( i = 0, l = vertices.count; i < l; i ++, nbVertex ++ ) { | |
| vertex.x = vertices.getX( i ); | |
| vertex.y = vertices.getY( i ); | |
| vertex.z = vertices.getZ( i ); | |
| // transfrom the vertex to world space | |
| vertex.applyMatrix4( mesh.matrixWorld ); | |
| // transform the vertex to export format | |
| output += 'v ' + vertex.x + ' ' + vertex.y + ' ' + vertex.z + '\n'; | |
| } | |
| } | |
| // uvs | |
| if ( uvs !== undefined ) { | |
| for ( i = 0, l = uvs.count; i < l; i ++, nbVertexUvs ++ ) { | |
| uv.x = uvs.getX( i ); | |
| uv.y = uvs.getY( i ); | |
| // transform the uv to export format | |
| output += 'vt ' + uv.x + ' ' + uv.y + '\n'; | |
| } | |
| } | |
| // normals | |
| if ( normals !== undefined ) { | |
| normalMatrixWorld.getNormalMatrix( mesh.matrixWorld ); | |
| for ( i = 0, l = normals.count; i < l; i ++, nbNormals ++ ) { | |
| normal.x = normals.getX( i ); | |
| normal.y = normals.getY( i ); | |
| normal.z = normals.getZ( i ); | |
| // transfrom the normal to world space | |
| normal.applyMatrix3( normalMatrixWorld ); | |
| // transform the normal to export format | |
| output += 'vn ' + normal.x + ' ' + normal.y + ' ' + normal.z + '\n'; | |
| } | |
| } | |
| // faces | |
| if ( indices !== null ) { | |
| for ( i = 0, l = indices.count; i < l; i += 3 ) { | |
| for ( m = 0; m < 3; m ++ ) { | |
| j = indices.getX( i + m ) + 1; | |
| face[ m ] = ( indexVertex + j ) + ( normals || uvs ? '/' + ( uvs ? ( indexVertexUvs + j ) : '' ) + ( normals ? '/' + ( indexNormals + j ) : '' ) : '' ); | |
| } | |
| // transform the face to export format | |
| output += 'f ' + face.join( ' ' ) + "\n"; | |
| } | |
| } else { | |
| for ( i = 0, l = vertices.count; i < l; i += 3 ) { | |
| for ( m = 0; m < 3; m ++ ) { | |
| j = i + m + 1; | |
| face[ m ] = ( indexVertex + j ) + ( normals || uvs ? '/' + ( uvs ? ( indexVertexUvs + j ) : '' ) + ( normals ? '/' + ( indexNormals + j ) : '' ) : '' ); | |
| } | |
| // transform the face to export format | |
| output += 'f ' + face.join( ' ' ) + "\n"; | |
| } | |
| } | |
| } else { | |
| console.warn( 'THREE.OBJExporter.parseMesh(): geometry type unsupported', geometry ); | |
| } | |
| // update index | |
| indexVertex += nbVertex; | |
| indexVertexUvs += nbVertexUvs; | |
| indexNormals += nbNormals; | |
| }; | |
| var parseLine = function ( line ) { | |
| var nbVertex = 0; | |
| var geometry = line.geometry; | |
| var type = line.type; | |
| if ( geometry instanceof Geometry ) { | |
| geometry = new BufferGeometry().setFromObject( line ); | |
| } | |
| if ( geometry instanceof BufferGeometry ) { | |
| // shortcuts | |
| var vertices = geometry.getAttribute( 'position' ); | |
| // name of the line object | |
| output += 'o ' + line.name + '\n'; | |
| if ( vertices !== undefined ) { | |
| for ( i = 0, l = vertices.count; i < l; i ++, nbVertex ++ ) { | |
| vertex.x = vertices.getX( i ); | |
| vertex.y = vertices.getY( i ); | |
| vertex.z = vertices.getZ( i ); | |
| // transfrom the vertex to world space | |
| vertex.applyMatrix4( line.matrixWorld ); | |
| // transform the vertex to export format | |
| output += 'v ' + vertex.x + ' ' + vertex.y + ' ' + vertex.z + '\n'; | |
| } | |
| } | |
| if ( type === 'Line' ) { | |
| output += 'l '; | |
| for ( j = 1, l = vertices.count; j <= l; j ++ ) { | |
| output += ( indexVertex + j ) + ' '; | |
| } | |
| output += '\n'; | |
| } | |
| if ( type === 'LineSegments' ) { | |
| for ( j = 1, k = j + 1, l = vertices.count; j < l; j += 2, k = j + 1 ) { | |
| output += 'l ' + ( indexVertex + j ) + ' ' + ( indexVertex + k ) + '\n'; | |
| } | |
| } | |
| } else { | |
| console.warn( 'THREE.OBJExporter.parseLine(): geometry type unsupported', geometry ); | |
| } | |
| // update index | |
| indexVertex += nbVertex; | |
| }; | |
| object.traverse( function ( child ) { | |
| if ( child instanceof Mesh ) { | |
| parseMesh( child ); | |
| } | |
| if ( child instanceof Line ) { | |
| parseLine( child ); | |
| } | |
| } ); | |
| return output; | |
| } | |
| }; | |
| export { OBJExporter }; | |