3D Modal Automatic Rotation

Hi there, I am creating a threejs scene in which a user can import as many models as he want.
The issue is that if I upload a different modal then normal it rotates itself in different directions.
Is there a snippet or way to make the model rotate to a specific direction regardless of it original rotation?

here my modal code:

function loadLeePerrySmith() {
  const loader = new GLTFLoader();

  const dracoLoader = new DRACOLoader();
  dracoLoader.setDecoderPath("/examples/jsm/libs/draco/");
  loader.setDRACOLoader(dracoLoader);

  loader.load(
    "https://cdn.glitch.me/dc99a522-a347-4f3e-a04f-210e55dccd91/teethtall1.glb?v=1709205022462",
    function (gltf) {
      mesh = gltf.scene.children[0];
      mesh.material = new THREE.MeshPhongMaterial({
        specular: 0x111111,
        shininess: 5,
        side: THREE.DoubleSide,
        clippingPlanes: [localPlane],
        alphaToCoverage: true,
      });

      mesh.rotation.x = Math.PI * -0.5;
      mesh.scale.set(1, 1, 1);
      mesh.updateMatrixWorld(true);
      let bounds = new THREE.Box3();
      bounds.setFromObject(mesh);
      console.log(bounds)
      mesh.position.sub(bounds.getCenter(new THREE.Vector3()));

      {
        let bounds = new THREE.Box3().setFromObject(mesh);
        let size = bounds.getSize(new THREE.Vector3());
        let { max } = Math;
        let maxsz = max(size.x, max(size.y, size.z));
        //Rescale the model..
        mesh.scale.multiplyScalar(100 / maxsz);
        mesh.needsAutoUpdate = true;
        mesh.updateMatrixWorld();
        bounds.setFromObject(mesh);
        mesh.position.sub(bounds.getCenter(new THREE.Vector3()));
      }

      stretchMesh = () => {

        if (!mesh.geometry.savePosition) {
          mesh.geometry.savePosition =
            mesh.geometry.attributes.position.array.slice(0);
          mesh.originalBounds = mesh.geometry.boundingBox.clone();
        }
        let bx = mesh.originalBounds; //mesh.geometry.boundingBox;
        console.log(bx);
        let vin = mesh.geometry.savePosition;
        let vout = mesh.geometry.attributes.position.array;

        let location = startingPlane.constant;
        let v0 = new THREE.Vector3();
        let localNormal = new THREE.Vector3();
        localNormal
          .copy(startingPlane.normal)
          .multiplyScalar(location)
          .add(mesh.position);
        mesh.worldToLocal(localNormal);
        let nd = localNormal.length();
        localNormal.normalize();

        for (let i = 0; i < vin.length; i += 3) {
          let x = vin[i];
          let y = vin[i + 1];
          let z = vin[i + 2];
          v0.set(x, y, z);
          let dsc = -v0.dot(localNormal) - nd;

          //imma fix this.. 1 sec
          //if (z < bx.min.z + location)
          if (dsc > 0) z -= length;

          vout[i] = x;
          vout[i + 1] = y;
          vout[i + 2] = z;
        }
        mesh.geometry.attributes.position.needsUpdate = true;
      };

      scene.add(mesh);
    }
  );
}

The centering and scaling of the modal is also doing something same special thanks to Thrax for that.

Try to attach the mesh to an empty parent object and apply the transformations (rotate, position, scales) to the parent object.

well the issue is not that the object is not rotating, the issue is when I load the object GLTF or GLB it loads rotated at a specific degree for example: when I load it, it appears upside down. So I want to implement something to detect the rotation and automatically fix it.

To make an object take the same orientation as the camera (without changing its position), you can use:

object.quaternion.copy( camera.quaternion );
2 Likes

So now the object is still not facing up can’t I make like an if else statement to perform the rotation or something:

It should appear upside down

Then you can just rotate it.

Most likely the confusion is between the two meanings of “up”. People tend to have some default “up-down” orientation of 3D objects. For example, if you see a house, you can easily say what is up and what is down. However, software cannot identify this (unless some AI is used). So, for the software “up-down” is a mere notion coming from the coordinate system (e.g. some use Y as up, others use Z as up).

In this case, if you use some external model, you should know its orientation. After loading it, you can additionally turn it, if it does not adhere to the orientation of your scene (i.e. its orientation is not the same as your scene orientation).

In the most general case, when you have absolutely no idea what objects will come (e.g. user can upload own models), the software cannot find what is “up” according to the user.

The bottom line is that “automatic rotation” is possible only if you know in advance the orientation of the models, or if the models have this data encoded in them.

Be aware, that I might have misunderstood your question. So, I’m not sure whether my post makes any sense in your case.

1 Like

I was thinking of calculating the bounds and then figuring out the longest side and make it to display vertically rather then horizontally, but its not possible I may have to use Blender in-order to configure the right rotation thanks for the help though really appreciate it

check that your models, before exporting them to glb or gltf, have applied the transformations. That cause that your models load rotated.

2 Likes

As you have decided the way to proceed, this is just for info: if you can rotate the objects in Blender, then you already know the objects. Maybe it is best to just rotate them in Three.js.

I had a similar case in the past – I used some 20 objects from a collection and a few of them were with strange center (i.e. it was not convenient to me). So I made something like this:

var offsets = {
    modelA: new THREE.Vector3(3,0,0),
    modelB: new THREE.Vector3(-1,1,0),
    modelC: new THREE.Vector3(2,0,10)
}

And then, when I load an object, if it is in this list of offset, then I change its center, otherwise I keep it as it is.

You can do the same, have a list of object names and their rotations and apply the rotation after loading the object. This will eliminate the need to adjust the orientation in Blender. And each object may have individual rotation, different from rotations of other objects.

1 Like

Well I think this is the best work around for the situation thanks btw :sweat_smile:

1 Like