0

I am new to Javascript and even newer to Three.JS. I have successfully taken a obj and converted and then loaded it in my site as a JSON object via three.js THREE.JSONLoader. It displays fine as I wanted but I need to be able to rotate, animate and manipulate it like any other THREE.Mesh Object. My first attempt at this is to rotate and animate it (a mesh chair) like the cube in the first three.js tutorial. However, after loading the object and attempting to rotate it within the "animate()" function, the variable I have set "myChair" is producing an "undefined" error when written:

myChair.rotation.x += 0.1;

I assume there is another step I must take for three.js to treat this JSON like any THREE.Mesh object?

Here is my code:

viewport = document.getElementById('mycanvas');
h = viewport.offsetHeight;
w = viewport.offsetWidth;
var scene = new THREE.Scene();
scene.background = new THREE.Color( 0xffffff );
var camera = new THREE.PerspectiveCamera( 75, w/h, 0.1, 1000 );
var renderer = new THREE.WebGLRenderer();
renderer.setSize(w, h);
viewport.appendChild(renderer.domElement);

//end viewport

var myChair = new THREE.JSONLoader();
myChair.load(
 'https://api.myjson.com/bins/iaxn7',
 function ( geometry, materials ) {
  var material = new THREE.MeshBasicMaterial( { color: 0x0000ff } );
  var object = new THREE.Mesh( geometry, material );
  scene.add(object);
 }
);

alert(myChair); //this alert confirms that an object is stored in the variable 

var animate = function () {
  requestAnimationFrame( animate );

  myChair.rotation.x += 0.1;
  myChair.rotation.y += 0.1;

  renderer.render(scene, camera);
};

animate();

Thanks so much! Any help is much appreciated.

UPDATE: after Marco's response.

 var myChairLoader = new THREE.JSONLoader();
 var chairMesh = null;

myChairLoader.load(
 'https://api.myjson.com/bins/iaxn7',
 function ( geometry, materials ) {
  var material = new THREE.MeshBasicMaterial( { color: 0x0000ff } );
  var chairMesh = new THREE.Mesh(geometry,material);
  scene.add(chairMesh);
    renderer.render(scene,camera);
 }
);

var animate = function (){
  requestAnimationFrame(animate);

  if(chairMesh !== null){
    alert();
    chairMesh.rotation.x += 0.1;
    chairMesh.rotation.y += 0.1;
  }
  renderer.render(scene,camera);
};

animate();
Joseph Ghaida
  • 129
  • 1
  • 12
  • https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call – Will Jun 26 '17 at 19:45

1 Answers1

1

You're attempting to animate myChair which is a THREE.JSONLoader object and cannot be animated. What you should be animating is the Mesh named object that you've added to the scene. I recommend you change your code to the following:

var chairLoader = new THREE.JSONLoader();

// 1: Will remain null until the JSON file is loaded
var chairMesh = null;

chairLoader.load(
    'https://api.myjson.com/bins/iaxn7',
    function ( geometry, materials ) {
        var material = new THREE.MeshBasicMaterial( { color: 0x0000ff } );

        // 2: Once JSON is loaded, we use the variable from above, and turn it into a Mesh.
        chairMesh = new THREE.Mesh( geometry, material );

        // 3: Now we add it to the scene
        scene.add(chairMesh);
    }
);

alert(chairLoader); //this is not the chair you want to animate. This is its loader.

var animate = function () {
    requestAnimationFrame( animate );

    // 4: Will animate chairMesh only after the JSON has been loaded.
    if(chairMesh !== null){
        chairMesh.rotation.x += 0.1;
        chairMesh.rotation.y += 0.1;
    }

    renderer.render(scene, camera);
};

Notice the chairMesh variable. THAT's the one you want to animate and add to the scene.

Side-note: you shouldn't use object as a variable name since that's already a reserved keyword for JavaScript objects, and can lead to confusion... For instance, using a variable named string can be very confusing.

M -
  • 26,908
  • 11
  • 49
  • 81
  • Marco, Thank you for clarifying that. I updated my code, unfortunately still no animation. – Joseph Ghaida Jun 27 '17 at 18:52
  • See how you're declaring `var chairMesh = null;` on the second line of code and then `var chairMesh = new ...` again inside the `chairLoader.load()` function? That's creating a new variable with the same name inside the scope of that function. This leads to scope confusion. Just keep it as I suggested `chairMesh = new THREE.Mesh( geometry, material );` without the `var` keyword, that way you only have one variable stored in memory, and when you update the rotation, the code will know that you're referencing the only `chairMesh` that exists. – M - Jun 27 '17 at 19:20