Como Exportar Cenas 3D para glTF/GLB em TypeScript

Como Exportar Cenas 3D para glTF/GLB em TypeScript

Aspose.3D FOSS suporta glTF 2.0 como formato de importação e exportação. O mesmo objeto Scene pode ser preenchido a partir de um OBJ, FBX, STL ou outro arquivo de origem e então gravado em .gltf (JSON + binário externo) ou .glb (contêiner binário único) definindo uma única flag em GltfSaveOptions.

Guia passo a passo

Etapa 1: Instale @aspose/3d

npm install @aspose/3d

Confirme que o Node.js 18 ou posterior está ativo:

node --version   # must be >= 16.0.0

Etapa 2: Importar Scene, GltfSaveOptions e GltfFormat

import { Scene } from '@aspose/3d';
import { GltfSaveOptions, GltfFormat } from '@aspose/3d/formats/gltf';

GltfFormat é o descritor de formato passado para scene.save(). GltfSaveOptions contém toda a configuração de exportação.

Se você também estiver carregando um arquivo de origem (por exemplo, OBJ), importe as opções de carregamento correspondentes:

import { ObjLoadOptions } from '@aspose/3d/formats/obj';

Etapa 3: Construir ou carregar uma cena

Opção A: Carregar a partir de um arquivo existente (conversão OBJ → GLB):

import { Scene } from '@aspose/3d';
import { ObjLoadOptions } from '@aspose/3d/formats/obj';
import { GltfSaveOptions, GltfFormat } from '@aspose/3d/formats/gltf';

const scene = new Scene();
scene.open('model.obj', new ObjLoadOptions());

Opção B: Crie uma cena mínima programaticamente:

import { Scene, Node, Mesh } from '@aspose/3d';
import { GltfSaveOptions, GltfFormat } from '@aspose/3d/formats/gltf';

const scene = new Scene();
const childNode = new Node('cube');
scene.rootNode.addChildNode(childNode);
// Attach geometry to childNode as needed

Etapa 4: Configurar GltfSaveOptions

GltfSaveOptions controla o formato de saída e os detalhes de codificação.

const saveOpts = new GltfSaveOptions();

// Set to true for a single binary .glb file
// Set to false (default) for JSON .gltf + separate .bin
saveOpts.binaryMode = true;

Opções adicionais que você pode definir:

PropriedadeTipoPadrãoEfeito
binaryModebooleanfalsetrue → GLB, false → glTF JSON
flipTexCoordVbooleantrueInverter o eixo vertical UV para compatibilidade com o motor

Etapa 5: Salvar usando scene.save()

Passe o caminho de saída, o descritor GltfFormat e as opções configuradas:

import { Scene } from '@aspose/3d';
import { ObjLoadOptions } from '@aspose/3d/formats/obj';
import { GltfSaveOptions, GltfFormat } from '@aspose/3d/formats/gltf';

const scene = new Scene();
scene.open('model.obj', new ObjLoadOptions());

const saveOpts = new GltfSaveOptions();
saveOpts.binaryMode = true;   // produce .glb

scene.save('output.glb', GltfFormat.getInstance(), saveOpts);
console.log('Converted to GLB successfully');

Para produzir um arquivo JSON .gltf em vez disso:

saveOpts.binaryMode = false;
scene.save('output.gltf', GltfFormat.getInstance(), saveOpts);
console.log('Exported to glTF JSON successfully');

Etapa 6: Verificar o arquivo de saída

Verifique se o arquivo de saída existe e tem tamanho diferente de zero:

import * as fs from 'fs';

const outputPath = 'output.glb';
const stats = fs.statSync(outputPath);
console.log(`Output file size: ${stats.size} bytes`);

if (stats.size === 0) {
    throw new Error('Export produced an empty file: check scene content');
}

Para uma verificação de ida e volta, recarregue o GLB e inspecione a contagem de nós:

import { Scene } from '@aspose/3d';
import { GltfLoadOptions } from '@aspose/3d/formats/gltf';

const verify = new Scene();
verify.open('output.glb', new GltfLoadOptions());

let nodeCount = 0;
function countNodes(node: any): void {
    nodeCount++;
    for (const child of node.childNodes) countNodes(child);
}
countNodes(verify.rootNode);

console.log(`Round-trip verification: ${nodeCount} node(s) in output`);

Problemas Comuns e Soluções

OBJ material file not found after export
Ao salvar para OBJ via scene.save('output.obj'), o arquivo de material .mtl é escrito ao lado do arquivo .obj automaticamente. Certifique-se de que o diretório de saída seja gravável e de que ambos os arquivos sejam mantidos juntos.

Saída .glb é menor que o esperado / malhas estão ausentes
Se a cena carregada possui nós sem entidades (por exemplo, grupos vazios de um OBJ), o GLB não conterá a geometria desses nós. Confirme que seu arquivo de entrada possui dados de polígonos reais usando mesh.controlPoints.length > 0 antes de salvar.

Não foi possível encontrar o módulo ‘@aspose/3d/formats/gltf’
Certifique‑se de que está usando o Node.js 18+ e que @aspose/3d está instalado no mesmo node_modules que o seu ponto de entrada. Execute npm ls @aspose/3d para confirmar que a versão é 24.12.0 ou posterior.

GltfFormat.getInstance() retorna undefined
Isso indica uma incompatibilidade de versão entre o pacote principal @aspose/3d e uma versão mais antiga em cache. Exclua node_modules e package-lock.json, então execute npm install novamente.

Texturas estão faltando no GLB de saída
Certifique-se de que binaryMode = true esteja configurado para produzir um GLB autocontido. Para a saída JSON do glTF, os arquivos de imagem de textura devem estar presentes ao lado do arquivo de saída, pois são referenciados por caminho relativo.

Erro de tipo: Argumento do tipo ‘GltfSaveOptions’ não é atribuível
Certifique-se de que Scene e GltfSaveOptions sejam importados da mesma instância do pacote instalado. Instalações mistas (global + local) podem causar incompatibilidades de interface.

Perguntas Frequentes (FAQ)

Qual é a diferença entre glTF e GLB? glTF 2.0 JSON (.gltf) armazena o grafo da cena como um arquivo JSON legível por humanos com buffers .bin e arquivos de imagem separados. GLB (.glb) empacota tudo em um único contêiner binário. Defina binaryMode = true para GLB, false para JSON glTF.

Posso exportar uma cena que foi construída inteiramente em código (sem arquivo fonte)?
Sim. Crie um Scene, adicione objetos Node, anexe Mesh ou outras entidades, então chame scene.save(). A cena não precisa originar de um arquivo carregado.

A exportação glTF é sem perdas? Para geometria e transformações, sim. Os materiais são mapeados para as propriedades de material PBR do glTF, quando possível. Extensões proprietárias de material FBX podem não fazer o round‑trip perfeitamente.

Posso exportar para STL ou 3MF em vez disso? Sim. O padrão é idêntico; importe os *SaveOptions e *Format.getInstance() do formato correspondente:

import { StlSaveOptions, StlFormat } from '@aspose/3d/formats/stl';
const opts = new StlSaveOptions();
scene.save('output.stl', StlFormat.getInstance(), opts);

O scene.save() é executado de forma assíncrona?
Não. scene.save() é síncrono. Envolva‑o em uma thread de trabalho se precisar evitar bloquear o loop de eventos durante exportações grandes.

Quais versões do Node.js são suportadas? Node.js 18, 20 e 22+. Node.js 16 e anteriores não são suportados.

Veja também

 Português