How to Add glTF Objects and Textures to an Existing Room Scene in a Browser Frontend

I have a glTF file representing a room loaded as a scene in my browser frontend. In my project, there’s a subfolder called “models” containing three glTF files of furniture models that I want to use to replace placeholders in the room scene. Each room (and its corresponding glTF file) is different, so I need a dynamic solution that can adapt to varying room layouts. Specifically, I require a method to access the glTF file of the scene dynamically and meaningfully replace the placeholders with the furniture models from the “models” folder. Furthermore, I want the furniture to be perfectly placed and scaled—for example, ensuring that a chair is correctly positioned on the floor, not upside down or excessively large. How can I achieve this in a professional and efficient manner?

A professional and efficient manner starts early, when you design all aspects of the project in advance, so that its implementation becomes smooth and manageable. For example:

  • all space units in all models are in meters; this will ensure compatibility of models without the need to rescale them; … and as a bonus, you could easily dive into VR/AR (as they specifically use 1 unit = 1 meter)
  • all placeholders have sufficient metadata, that guide you, so that you can easily put objects there; the metadata could define what objects could be placed, what is their minimal/maximal size, what is their default orientation (or possible orientations), do they require to be put next to another object (or should they be put away from them) etc.
  • all models have unified design, including their origin point, their initial orientation, their “contact” points (if you need to align/chain one object to other objects)
  • all GLTF models have structure (naming and hierarchy) that allows to easily find important elements (e.g. the placeholders; or the other elements like windows, doors, etc) and once found, to easily extract the metadata about their properties/constraints … in this case, you could easily find that the placeholder at the front door can accept a rug, but you should not put a wardrobe or a TV set there.
2 Likes

Thank you very much for the detailed and professional response. I understand the principles you mentioned, but I am struggling to implement them in my code. Specifically, I would like to apply your advice on how to efficiently extract and use metadata from a GLTF model to locate placeholders and replace them with appropriate furniture models.

How can I efficiently find placeholders in the loaded GLTF scene? Should I prepare tags or specific naming conventions in Blender or another tool for this purpose?

How can I ensure that the furniture piece is correctly scaled and positioned? Do I need to manually define additional information like contact points and orientation, or can this be calculated automatically?

Additionally, I need this to be handled in the backend so that the replacement occurs during the conversion process. This section demonstrates the process of uploading models and loading them into the scene.document.getElementById(‘upload-button’).addEventListener(‘click’, handleUpload);

function handleUpload() {
const fileInput = document.getElementById(‘file-input’);
const statusDiv = document.getElementById(‘status’);

if (fileInput.files.length === 0) {
    alert(' 3D-Datei.');
    return;
}

const file = fileInput.files[0];
const formData = new FormData();
formData.append('file', file);
statusDiv.innerText = 'Datei wird hochgeladen und konvertiert...';

fetch('/upload', {
    method: 'POST',
    body: formData
})
    .then(response => response.json())
    .then(data => {
        if (data.error) {
            statusDiv.innerText = 'Konvertierung fehlgeschlagen.';
        } else {
            statusDiv.innerText = 'Konvertierung erfolgreich!';
            loadModel(data.gltfFile);
        }
    })
    .catch(error => {
        console.error('Fehler:', error);
        statusDiv.innerText = 'Es ist ein Fehler aufgetreten.';
    });

}
Here, the scene is initialized, and placeholder meshes are identified.function processLoadedModel(gltf) {
gltf.scene.traverse(node => {
if (node.isMesh) {
node.castShadow = true;
node.receiveShadow = true;

        if (!node.material) {
            node.material = new THREE.MeshStandardMaterial({
                color: 0xaaaaaa,
                metalness: 0.5,
                roughness: 0.5
            });
        }

        const nameLower = node.name.toLowerCase();
        if (nameLower.includes('wall') || nameLower.includes('chair') || nameLower.includes('table')) {
            room.meshes.push(node);
        }
    }
});

room.box = new THREE.Box3().setFromObject(gltf.scene);
room.center = room.box.getCenter(new THREE.Vector3());

}