Can't scale a custom model from Sketchfab in three js

const sphereGeometry = new THREE.SphereGeometry(0.5, 16, 16);
    const particles = [];
    const originalPositions = [];
    const originalMaterials = [];
    const highlightMaterial = new THREE.MeshStandardMaterial({ color: 0x00ff00 });


    loader.load('/mesh3.glb', (gltf) => {
      const model = gltf.scene;
      console.log(model);
      if (model) {
        model.scale.set(0.001, 0.001, 0.001);

        model.traverse((child) => {
          if (child.isMesh) {
            const vertices = child.geometry.attributes.position;
            console.log(child);
            child.parent.scale.set(0.01, 0.01, 0.01);
            child.parent.parent.scale.set(0.01, 0.01, 0.01);
            child.parent.parent.parent.scale.set(0.01, 0.01, 0.01);
            child.scale.set(0.01, 0.01, 0.01);
            for (let i = 0; i < vertices.count; i++) {
              const x = vertices.getX(i);
              const y = vertices.getY(i);
              const z = vertices.getZ(i);

              const particle = new THREE.Mesh(sphereGeometry, new THREE.MeshStandardMaterial());
              particle.position.set(x, y, z);
              particles.push(particle);
              originalPositions.push(new THREE.Vector3(x, y, z));
              originalMaterials.push(particle.material.clone());
            }
          }
        });

        scene.add(...particles);
      }
    });

Essentially you need to apply the scale change to the geometry as that’s what you’re using to create the particles positions…

    loader.load('/mesh3.glb', (gltf) => {
      const model = gltf.scene;
      console.log(model);
      if (model) {
        model.scale.set(0.001, 0.001, 0.001);
        model.updateMatrix()

        model.traverse((child) => {
          if (child.isMesh) { 
            child.geometry.applyMatrix4(model.matrix)
//otherwise you can use child.geometry.scale(0.001,0.001,0.001)
            const vertices = child.geometry.attributes.position;
            
            for (let i = 0; i < vertices.count; i++) {
              const x = vertices.getX(i);
              const y = vertices.getY(i);
              const z = vertices.getZ(i);

              const particle = new THREE.Mesh(sphereGeometry, new THREE.MeshStandardMaterial());
              particle.position.set(x, y, z);
              particles.push(particle);
              originalPositions.push(new THREE.Vector3(x, y, z));
              originalMaterials.push(particle.material.clone());
            }
          }
        });

        scene.add(...particles);
      }
    });

still not working.

any chance you could explain what part is not working? if you could, please provide the model “mesh3.glb” in this thread so we can have a look…

mesh3.glb (420.7 KB)

https://firebasestorage.googleapis.com/v0/b/fir-48ad5.appspot.com/o/2023-09-19%2010-01-56.mp4?alt=media&token=c0682bcc-cd3a-4af9-8b36-6cfff45bd4b2[see this]

@unni_krishnan

Glb you have provided has scaling at multiple object.

That’s why you need to apply world matrix to position of sphere

Here is result you want according to me

import * as THREE from 'three'
import { ThreeViewer } from './threeCustom/viewer/ThreeViewer'
import { loadGlb } from './loadGlb';
import { BufferGeoUtils } from 'utils-three-js';

let threeViewer = new ThreeViewer({
    element: document.getElementById('container3D')
})
let sphereGeometry = new THREE.SphereGeometry(0.001, 32, 32);
const particles = []
threeViewer.initViewer()

threeViewer.loadENV('./env.hdr').then(() => {
    loadGlb('./mesh3.glb').then((root) => {
        const model = root.scene;
        model.scale.set(0.5, 0.5, 0.5);
        model.position.set(0, -0.5, 0);
        threeViewer.scene.add(model);

        model.updateMatrixWorld(); // Update world matrices for all objects in the scene
        
        if (model) {
            model.traverse((child) => {
                if (child.isMesh) {
                    let matrix =  child.matrixWorld // get the world matrix of the mesh
                    const vertices = child.geometry.attributes.position;

                    for (let i = 0; i < vertices.count; i++) {
                        let position = BufferGeoUtils.getPoint(child.geometry, i); // get the position of the vertex
                        position.applyMatrix4(matrix); // apply the world matrix to the vertex

                        const particle = new THREE.Mesh(sphereGeometry, new THREE.MeshBasicMaterial({ color: 0xff0000 }));
                        particles.push(particle);
                        particle.position.copy(position);
                    }
                    threeViewer.scene.add(...particles);
                }
            })
        }

    })
})

1 Like

thank you . very helpfull

1 Like