UNPKG

angular-3d-viewer

Version:
125 lines (114 loc) 5.56 kB
import { FileFormat, GetFileName } from '../io/fileutils.js'; import { TextWriter } from '../io/textwriter.js'; import { MaterialType } from '../model/material.js'; import { ExportedFile, ExporterBase } from './exporterbase.js'; export class ExporterObj extends ExporterBase { constructor () { super (); } CanExport (format, extension) { return format === FileFormat.Text && extension === 'obj'; } ExportContent (exporterModel, format, files, onFinish) { function WriteTexture (mtlWriter, keyword, texture, files) { if (texture === null || !texture.IsValid ()) { return; } let fileName = GetFileName (texture.name); mtlWriter.WriteArrayLine ([keyword, fileName]); let fileIndex = files.findIndex ((file) => { return file.GetName () === fileName; }); if (fileIndex === -1) { let textureFile = new ExportedFile (fileName); textureFile.SetBufferContent (texture.buffer); files.push (textureFile); } } let mtlFile = new ExportedFile ('model.mtl'); let objFile = new ExportedFile ('model.obj'); files.push (mtlFile); files.push (objFile); let mtlWriter = new TextWriter (); mtlWriter.WriteLine (this.GetHeaderText ()); for (let materialIndex = 0; materialIndex < exporterModel.MaterialCount (); materialIndex++) { let material = exporterModel.GetMaterial (materialIndex); mtlWriter.WriteArrayLine (['newmtl', this.GetExportedMaterialName (material.name)]); mtlWriter.WriteArrayLine (['Kd', material.color.r / 255.0, material.color.g / 255.0, material.color.b / 255.0]); mtlWriter.WriteArrayLine (['d', material.opacity]); if (material.type === MaterialType.Phong) { mtlWriter.WriteArrayLine (['Ka', material.ambient.r / 255.0, material.ambient.g / 255.0, material.ambient.b / 255.0]); mtlWriter.WriteArrayLine (['Ks', material.specular.r / 255.0, material.specular.g / 255.0, material.specular.b / 255.0]); mtlWriter.WriteArrayLine (['Ns', material.shininess * 1000.0]); } WriteTexture (mtlWriter, 'map_Kd', material.diffuseMap, files); if (material.type === MaterialType.Phong) { WriteTexture (mtlWriter, 'map_Ks', material.specularMap, files); } WriteTexture (mtlWriter, 'bump', material.bumpMap, files); } mtlFile.SetTextContent (mtlWriter.GetText ()); let objWriter = new TextWriter (); objWriter.WriteLine (this.GetHeaderText ()); objWriter.WriteArrayLine (['mtllib', mtlFile.GetName ()]); let vertexOffset = 0; let normalOffset = 0; let uvOffset = 0; let usedMaterialName = null; exporterModel.EnumerateTransformedMeshInstances ((mesh) => { objWriter.WriteArrayLine (['g', this.GetExportedMeshName (mesh.GetName ())]); for (let vertexIndex = 0; vertexIndex < mesh.VertexCount (); vertexIndex++) { let vertex = mesh.GetVertex (vertexIndex); objWriter.WriteArrayLine (['v', vertex.x, vertex.y, vertex.z]); } for (let normalIndex = 0; normalIndex < mesh.NormalCount (); normalIndex++) { let normal = mesh.GetNormal (normalIndex); objWriter.WriteArrayLine (['vn', normal.x, normal.y, normal.z]); } for (let textureUVIndex = 0; textureUVIndex < mesh.TextureUVCount (); textureUVIndex++) { let uv = mesh.GetTextureUV (textureUVIndex); objWriter.WriteArrayLine (['vt', uv.x, uv.y]); } for (let triangleIndex = 0; triangleIndex < mesh.TriangleCount (); triangleIndex++) { let triangle = mesh.GetTriangle (triangleIndex); let v0 = triangle.v0 + vertexOffset + 1; let v1 = triangle.v1 + vertexOffset + 1; let v2 = triangle.v2 + vertexOffset + 1; let n0 = triangle.n0 + normalOffset + 1; let n1 = triangle.n1 + normalOffset + 1; let n2 = triangle.n2 + normalOffset + 1; if (triangle.mat !== null) { let material = exporterModel.GetMaterial (triangle.mat); let materialName = this.GetExportedMaterialName (material.name); if (materialName !== usedMaterialName) { objWriter.WriteArrayLine (['usemtl', materialName]); usedMaterialName = materialName; } } let u0 = ''; let u1 = ''; let u2 = ''; if (triangle.HasTextureUVs ()) { u0 = triangle.u0 + uvOffset + 1; u1 = triangle.u1 + uvOffset + 1; u2 = triangle.u2 + uvOffset + 1; } objWriter.WriteArrayLine (['f', [v0, u0, n0].join ('/'), [v1, u1, n1].join ('/'), [v2, u2, n2].join ('/')]); } vertexOffset += mesh.VertexCount (); normalOffset += mesh.NormalCount (); uvOffset += mesh.TextureUVCount (); }); objFile.SetTextContent (objWriter.GetText ()); onFinish (); } GetHeaderText () { return '# exported by https://3dviewer.net'; } }