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
我是 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