0
import * as THREE from 'three';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';

const canvas = document.querySelector('#frontPageCanvas');
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth 
window.innerHeight, 0.1, 1000);

const renderer = new THREE.WebGLRenderer({canvas, antialias: true});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor( 0xffffff, 0);


function loadFiles(capsulesFiles, scene) {

  const capsuleloader = new GLTFLoader();

  capsulesFiles.forEach((capsulesFile) => {
    capsuleloader.load(capsulesFile, (gltf) => {
      scene.add(gltf.scene);
    });
  });
 };

let capsulesFiles = ['../three.js/models/capsule_1.glb',  
'../three.js/models/capsule_1.glb'];
loadFiles(capsulesFiles, scene);


//const geometry = new THREE.BoxGeometry(2, 2, 2);
//const material = new THREE.MeshBasicMaterial({color: 0x0000ff});
//const cube = new THREE.Mesh(geometry, material);
//scene.add(cube);

camera.position.z = 5;

console.log(scene);

function animate()  {
    requestAnimationFrame(animate);
//    cube.rotation.x += 0.05
//    cube.rotation.y += 0.05
    scene.children[0].rotation.y += 0.05;
    scene.children[1].rotation.x -= 0.01;
    scene.children[1].rotation.y -= 0.01;

    renderer.render(scene, camera);
}

animate();

Hi, I am new to Three.js and JavaScript! I was trying to see if I could insert my glb models via array (to save code time instead of having unique functions for each one). I figured I could use the scene object to do this, but when I run this code I get this error for the rotation code which says Uncaught TypeError: Cannot read properties of undefined (reading 'rotation') at animate (threejsanimations.js:49:23) at threejsanimations.js:56:1

However, after a little delay, one of my models does rotate (makes no sense since all rotation code shouldn't work). Not sure how to fix this. Also, if any additional help as to why my models have no texture/material would be cool (I used Maya to make them with aiStandardSurface of Glass and Plastic for the materials and the Verge3D plugin to export them as .glb files).

1 Answer 1

0

First of all, keep in mind that GLTFLoader is asynchronous, so loop doesn't have access to model, because is not loaded yet, so you getting undefined, you need time to download, decoding and finally add to the scene, and loop works immediately. Generally, first load then animate...

You can make empty array to holding references of loaded models. Then you have to check, if model is loaded, then make some animations.

Secondly, you have typo in constructor of PerspectiveCamera:

In aspect ratio you should dividing (in your case) window.innerWidth by window.innerHeight.

const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);

About textures, hard to say I don't use Maya, but probably process is the same like in Blender... Try export file like a GLB, and then from Three.js level, map it or bake in Maya.

<script type="importmap">
  {
"imports": {
  "three": "https://unpkg.com/[email protected]/build/three.module.js",
  "three/addons/": "https://unpkg.com/[email protected]/examples/jsm/"
}
  }
</script>

<canvas id="frontPageCanvas"><canvas>

<script type="module">
import * as THREE from 'three';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';

const canvas = document.querySelector('#frontPageCanvas');
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);

const renderer = new THREE.WebGLRenderer({ canvas, antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0xffffff, 0);

const ambientLight = new THREE.AmbientLight(0xffffff, 1);
scene.add(ambientLight);

const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
directionalLight.position.set(4, 5, 5);
scene.add(directionalLight);

let loadedModels = [];

function loadFiles(capsulesFiles) {
    const capsuleLoader = new GLTFLoader();

    capsulesFiles.forEach((capsulesFile, index) => {
        capsuleLoader.load(capsulesFile, (gltf) => {
            const model = gltf.scene;
            scene.add(model);
            loadedModels[index] = model;

            if (index === 0) {
                model.position.set(-3.5, 0, 0);
                model.scale.set(15.5, 15.5, 15.5);
            } else if (index === 1) {
                model.position.set(3.5, 0, 0);
                model.scale.set(0.2, 0.2, 0.2);
            }
        });
    });
}

let capsulesFiles = [
    'https://threejs.org/examples/models/gltf/Flower/Flower.glb',
    'https://threejs.org/examples/models/gltf/Nefertiti/Nefertiti.glb'
];
loadFiles(capsulesFiles);

camera.position.z = 10;

function animate() {
    requestAnimationFrame(animate);

    if (loadedModels[0]) {
        loadedModels[0].rotation.y += 0.05;
    }
    if (loadedModels[1]) {
        loadedModels[1].rotation.y -= 0.01;
    }

    renderer.render(scene, camera);
}

animate();

</script>

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.