Three.js 转换后的 OBJ 可以很好地呈现为网格但记录为未定义?

Three.js Converted OBJ Renders as Mesh fine but Logs as Undefined?

我是 Three.js 的新手,正在做一些实验。我对 Javascript 也很陌生,我遇到的问题似乎与变量作用域和回调函数协议有关,而不是 Three.js...令人沮丧!

这是我的 app.js 的完整代码,感谢 WestLangley 提供的 geo2line 函数,我在这段代码中工作,感谢 Three.js 开发人员为我提供的 ObjLoader 和 JSONLoaders在这个实验性应用中工作。

// Initialization Vars
var scene;
var camera;
var renderer;

// Light Vars
var light;
var lightScene;

// Object Vars
var lineSphere;
var cube1;
var geodesicMesh;
var geodesicLine;
var lineGeometry;
var floorGeometry;
var floor;
var line1;

// Material Vars
var lineBlueMaterial;
var lineRedMaterial;
var geodesicMaterial;
var floorMaterial;

// Render Vars
var render;

// Callback Vars
var loadedMesh;


function init() {

 scene = new THREE.Scene();
 cameras();
 
 renderer = new THREE.WebGLRenderer();
 renderer.setSize( window.innerWidth, window.innerHeight );
 document.body.appendChild( renderer.domElement );

 // LIGHTS
 lights();
 
 // MATERIALS
 materials();
  
 // GEOMETRIES
 geometries();
 
 camera.position.z = 5;

 render = function () {
  requestAnimationFrame( render );
  
  lineSphere.rotation.x += 0.02;
  lineSphere.rotation.y += 0.02;
  lineSphere.rotation.z += 0.01;
  
  //geodesicMesh.rotation.x += 0.03;
  //geodesicMesh.rotation.y += 0.03;
  
  renderer.render(scene, camera);
 };

 render();

}

function cameras() {
 camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );
}

function lights() {
 light = new THREE.PointLight(0xAAAA66, 2, 100);
 light.position.set(50,50,50);
 scene.add(light);

 lightScene = new THREE.PointLight(0x66AAAA, 2, 100);
 lightScene.position.set (0,5,0);
 scene.add(lightScene);
}

function materials() {
 geodesicMaterial = new THREE.MeshPhongMaterial( { 
  color: 0x0000ff,
  specular: 0x8888ff,
  shininess: 20,
  shading: THREE.FlatShading  } );

 lineBlueMaterial = new THREE.LineDashedMaterial ({ 
  color: 0xff0000, 
  dashSize: .1, 
  gapSize: .1, 
  linewidth: 3 });
  
 lineRedMaterial = new THREE.LineDashedMaterial ({ 
  color: 0xff0000, 
  dashSize: .1, 
  gapSize: .1, 
  linewidth: 3 });
}

function geometries() {
 sphereGeometry = new THREE.SphereGeometry( 3, 24, 24 );
 lineSphere = new THREE.Line( geo2line(sphereGeometry), lineBlueMaterial, THREE.linePieces );
 scene.add( lineSphere );
  
 geodesicMesh = loadObjAsMesh( 'assets/objects/v2-icosahedron-simplest.obj' , function ( mesh ) { loadedMesh = mesh; scene.add( mesh ); return mesh; } );
 
 //loadedMesh;
 
 console.log ( loadedMesh );

 //geodesicMesh.computeLineDistances();
 
 //geodesicLine = new THREE.Line ( geo2line( geodesicMesh ), lineRedMaterial, THREE.linePieces );
 //scene.add( geodesicLine );

}

function geo2line( geo ) {

    var geometry = new THREE.Geometry();
    var vertices = geometry.vertices;

    for ( i = 0; i < geo.faces.length; i++ ) {

        var face = geo.faces[ i ];

        if ( face instanceof THREE.Face3 ) {

                vertices.push( geo.vertices[ face.a ].clone() );
                vertices.push( geo.vertices[ face.b ].clone() );
                vertices.push( geo.vertices[ face.b ].clone() );
                vertices.push( geo.vertices[ face.c ].clone() );
                vertices.push( geo.vertices[ face.c ].clone() );
                vertices.push( geo.vertices[ face.a ].clone() );

        } else if ( face instanceof THREE.Face4 ) {

                vertices.push( geo.vertices[ face.a ].clone() );
                vertices.push( geo.vertices[ face.b ].clone() );
                vertices.push( geo.vertices[ face.b ].clone() );
                vertices.push( geo.vertices[ face.c ].clone() );
                vertices.push( geo.vertices[ face.c ].clone() );
                vertices.push( geo.vertices[ face.d ].clone() );
                vertices.push( geo.vertices[ face.d ].clone() );
                vertices.push( geo.vertices[ face.a ].clone() );

        }

    }

    geometry.computeLineDistances();

    return geometry;
}

function loadObjAsMesh( obj , callback ) {  // Obj Resource URL: Example: 'assets/monster.obj'

 var geometry;
 var mesh;

 var loader = new THREE.OBJLoader();
   
 loader.load(
  obj , function ( object ) { 
  
   geometry = new THREE.Geometry().fromBufferGeometry( object.children["0"].geometry );
      
   mesh = new THREE.Mesh ( geometry, geodesicMaterial ); 
   
   console.log( mesh );
   //scene.add( mesh );
   callback( mesh );
  
   } );
}

function loadJSON( obj ) {  // Obj Resource URL: Example: 'assets/monster.obj'

 var loader = new THREE.JSONLoader();
   
 loader.load(
  obj , function ( object ) { return( object ); } );
}

旋转的球体运行得很漂亮,二十面体渲染成几何体也很好。

但是我在第 113 行碰壁,控制台中的 'loadedMesh' returns 为 'Undefined.' 据我所知,这不应该发生,因为我'已经在全局上下文中声明了这个变量,回调函数只是设置它的值(我认为是全局的?),而不是实际在内部声明它。

由于它以未定义状态返回,我不能做我接下来想做的事情,即通过第 117 行将网格对象传递给 geo2line 函数(希望将 geodesicMesh 变量设置为 loadedMesh 变量) ,然后将其渲染为一系列虚线。

那么,我在这里没理解什么?

谢谢!

加载程序中的回调是异步的。您正在记录未定义,因为它是未定义的:

// Callback Vars
var loadedMesh;   //loadedMesh === undefined