Overview

These are notes on how to convert OBJ files to glTF and GLB files.

Target Data

The target is the “Ishibuchi Family Globe” from the “Kikuchi City / Digital Archive.”

https://adeac.jp/kikuchi-city/catalog/e0001

The OBJ file can be accessed from the following URL.

https://adeac.jp/viewitem/kikuchi-city/viewer/3d/dc-e0097/models/Kikuchi_Globe_180820.obj

Downloading the Target Data

Download the library.

npm i axios

Prepare the following file.

const axios = require('axios');
const fs = require('fs');
const path = require('path');

// Function to download a file from a specified URL
async function downloadFile(url, outputPath) {
    const writer = fs.createWriteStream(outputPath);

    const response = await axios({
        url,
        method: 'GET',
        responseType: 'stream',
    });

    response.data.pipe(writer);

    return new Promise((resolve, reject) => {
        writer.on('finish', resolve);
        writer.on('error', reject);
    });
}

// Load .obj file and download related files
async function processObjFile(objUrl, outputDir) {
    try {
        // Download .obj file and get its content
        const objResponse = await axios.get(objUrl);
        const objContent = objResponse.data;

        // Save .obj file
        const objFileName = path.basename(objUrl);
        const objFilePath = path.join(outputDir, objFileName);
        fs.writeFileSync(objFilePath, objContent);
        console.log(`Downloaded OBJ file: ${objFilePath}`);

        // Search for .mtl file path
        const mtlMatch = objContent.match(/^mtllib\s+(.+)$/m);
        if (mtlMatch) {
            const mtlFileName = mtlMatch[1];
            const mtlUrl = new URL(mtlFileName, objUrl).href;
            const mtlFilePath = path.join(outputDir, mtlFileName);

            // Download .mtl file
            await downloadFile(mtlUrl, mtlFilePath);
            console.log(`Downloaded MTL file: ${mtlFilePath}`);

            // Get .mtl file content and find related files
            const mtlContent = fs.readFileSync(mtlFilePath, 'utf-8');
            const textureMatches = [...mtlContent.matchAll(/^map_Kd\s+(.+)$/gm)];

            for (const match of textureMatches) {
                const textureFileName = match[1];
                const textureUrl = new URL(textureFileName, objUrl).href;
                const textureFilePath = path.join(outputDir, path.basename(textureFileName));

                // Download texture image
                await downloadFile(textureUrl, textureFilePath);
                console.log(`Downloaded texture file: ${textureFilePath}`);
            }
        } else {
            console.log('No MTL file referenced in the OBJ file.');
        }
    } catch (error) {
        console.error(`Error processing OBJ file: ${error.message}`);
    }
}

// Usage example
const objUrl = 'https://adeac.jp/viewitem/kikuchi-city/viewer/3d/dc-e0097/models/Kikuchi_Globe_180820.obj';
const outputDir = './downloads';

if (!fs.existsSync(outputDir)) {
    fs.mkdirSync(outputDir, { recursive: true });
}

processObjFile(objUrl, outputDir);

Execute it.

node dwn.js

The .obj, .mtl, and .jpg files are downloaded to the downloads folder.

Converting to glTF

Download the library.

npm i obj2gltf

Prepare the following file.

const obj2gltf = require("obj2gltf");
const fs = require("fs");

obj2gltf("./downloads/Kikuchi_Globe_180820.obj").then(function (gltf) {
    const data = Buffer.from(JSON.stringify(gltf));
    fs.writeFileSync("./model.gltf", data);
});

Execute it.

node convert.js

A model.gltf file is created.

Converting to GLB

Download the library.

npm i gltf-pipeline

Convert the glTF file to a GLB file.

gltf-pipeline -i model.gltf -o model.glb

Summary

There may be other appropriate conversion methods, but I hope this serves as a helpful reference.