2016-08-31 5 views
2

Код выполняет то, что он должен делать, но я получаю 2 ошибки в консоли: «Невозможно прочитать свойство« rotation »undefined». Смутно, почему он бросает ошибки, поскольку две переменные определяются как глобальные переменные. Я что-то упускаю? (Использование TextureLoader(), поскольку ImageUtils.loadTexture() устарел).Невозможно прочитать свойство «rotation» of undefined - Three.js

<!DOCTYPE html> 
<html lang="en"> 
<head> 
    <meta charset="UTF-8"> 
    <title>Three.js</title> 
    <style> 
     body{ 
      margin: 0; 
      width: 100%; 
      height: 100%; 
      overflow: hidden; 
     } 
    </style> 
</head> 
<body> 
    <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r80/three.js"></script> 
    <script src="js/OrbitControls.js"></script> 
    <script> 

     //GLOBAL VARIABLES 
     var scene, camera, renderer, cameraControl, earthMesh, cloudMesh; 

     function init(){ 

      //scene 
      scene = new THREE.Scene(); 

      //renderer 
      renderer = new THREE.WebGLRenderer(); 
      renderer.setSize(window.innerWidth, window.innerHeight); 
      renderer.setClearColor('#000', 1.0); 
      renderer.shadowMap.enabled = true; 

      //camera 
      camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 1, 1000); 
      camera.position.x = 35; 
      camera.position.y = 36; 
      camera.position.z = 33; 
      camera.lookAt(scene.position); 

      //earth mesh 
      var sphereGeometry = new THREE.SphereGeometry(10, 60, 60); 
      var sphereMaterial; 
      var sphereMaterialLoader = new THREE.TextureLoader(); 
      sphereMaterialLoader.load(
       'images/earth.jpg', 
       function(earthImage){ 
        sphereMaterial = new THREE.MeshBasicMaterial({ 
         map: earthImage 
        }); 
        earthMesh = new THREE.Mesh(sphereGeometry, sphereMaterial); 
        earthMesh.name = 'earth'; 
        scene.add(earthMesh); 
        render(); 
       } 
      ); 

      //cloud mesh 
      var cloudGeometry = new THREE.SphereGeometry(sphereGeometry.parameters.radius * 1.02, 
       sphereGeometry.parameters.widthSegments, sphereGeometry.parameters.heightSegments); 
      var cloudMaterial; 
      var cloudMaterialLoader = new THREE.TextureLoader(); 
      cloudMaterialLoader.load(
       'images/clouds.png', 
       function(cloudImage){ 
        cloudMaterial = new THREE.MeshBasicMaterial({ 
         map: cloudImage 
        }); 
        cloudMaterial.transparent = true; 
        cloudMesh = new THREE.Mesh(cloudGeometry, cloudMaterial); 
        cloudMesh.name = 'cloud'; 
        scene.add(cloudMesh); 
        render(); 
       } 
      ); 

      //camera control 
      cameraControl = new THREE.OrbitControls(camera); 

      document.body.appendChild(renderer.domElement); 
      render(); 
     } 

     function render(){ 
      renderer.render(scene, camera); 
      earthMesh.rotation.y += -0.001; 
      cloudMesh.rotation.y += 0.0005; 
      cameraControl.update(); 
      requestAnimationFrame(render); 
     } 

     //initialize scene/render 
     window.onload = init; 

    </script> 
</body> 
</html> 

ответ

4

Похоже earthMesh инициализируется асинхронно в вашем cloudMaterialLoader.load() функцию - вы должны быть осторожны, так как при первом вызове визуализации() earthMesh не может быть уже загружен, в этом случае он будет все еще не определены.

Несколько способов работы с этим состоять в том, чтобы не вызывать render() до загрузки earthMesh или проверить, загружен ли earthMesh в вызове render(), или что-либо до вашего воображения.

+0

Есть ли способ проверить, были ли все текстуры загружены до вызова функции рендеринга в первый раз? –

Смежные вопросы