使用 switch 语句加载 Three.JS 中的多个对象
Using a switch statement to load multiple objects in Three.JS
我有一个使用 Three.JS 的网络 3D 模型查看器。我正在尝试使用 dat.GUI 实现一种从下拉列表中选择不同模型的方法。我正在尝试使用 switch 语句来完成此操作,灵感来自 Three.JS 网站(materials/reflectivity 和 envmaps/hdr/nodes)上的一些示例。
当我只尝试加载一个模型时,我的加载器工作正常。但是当我尝试将它连接到 GUI 和 switch 语句时,模型没有出现(控制台日志显示 100% 加载,但我不知道这是真的还是我的负载报告器的错误)。控制台日志也 returns 这个错误:
Error: THREE.OBJLoader: Unexpected line: "<!DOCTYPE html>" OBJLoader.js:624:12
谷歌搜索错误 returns 建议 .obj 文件已损坏。我知道我的模型很好,因为我已经自己成功加载了它们。所以我只能假设问题是我正在加载加载程序的变量。我知道 OBJLoader 可以从变量加载,因为我尝试只定义一个变量作为模型(var model = 'my_model.obj',然后让加载器加载 "model"),这很有效。所以我将其缩小为 GUI 代码或 switch 语句的问题。
这是我的脚本,删除了一些不相关的部分。
var gui;
var camera, scene, renderer;
var species, params;
//3D models to choose from in dropdown list.
var speciesList = {
'Goldenrod': 'models/solidago_rugosa.obj',
'Mountain Laurel': 'models/kalmia_latifolia.obj',
};
//Model loaded by default
params = {
Species: 'models/solidago_rugosa.obj'
};
init();
animate();
function init() {
//defining the scene, camera, renderer...
//GUI
gui = new dat.GUI({hideable: false});
gui.add(params, 'Species', speciesList)
//controls, window resizer...
};
//Switch to load a different model.
//speciesCurrent is used by loader.
//No method to remove the previously loaded model yet, but I figure it should be able to load models on top of each other for now.
var speciesCurrent;
switch (speciesList) {
case 'models/solidago_rugosa.obj':
speciesCurrent = 'models/solidago_rugosa.obj';
break;
case 'models/kalmia_latifolia.obj':
speciesCurrent = 'models/kalmia_latifolia.obj';
break;
};
//Loader
var loader = new THREE.OBJLoader();
loader.load(
speciesCurrent,
function(object){
var material = new THREE.MeshLambertMaterial({color: 0x99a300});
object.traverse(function (child){
if (child instanceof THREE.Mesh){
child.material=material;
child.material.flatShading = 0;
}
});
scene.add(object);
},
function(xhr){
console.log((xhr.loaded / xhr.total * 100) + '% loaded');
},
function(error){
console.log('An error happened');
}
);
//Light sources...
//Game loop
function animate(){
requestAnimationFrame( animate );
render();
};
function render(){
renderer.render(scene,camera);
};
如何让我的加载器实际加载从下拉列表中选择的模型?谢谢。
更新:我的浏览器开发工具的网络选项卡显示我的索引文件列出了两次。标记为 "xhr" 的代码通过堆栈跟踪链接到索引文件的第 93 行,这是加载程序开始的地方 ("loader.load")。注释掉 switch 语句会删除额外的 html 文件。是什么导致我的加载程序将 switch 语句视为 html?
它正在工作。我告诉加载程序加载 params.Species(当前选择的 Species 文件)并废弃了 switch 语句。我还添加了一个函数,该函数在 GUI 更改时触发,并且还会删除任何先前加载的模型。这是当前的工作代码:
var gui;
var camera, scene, renderer;
var species, params;
var loader, mesh
//3D models to choose from in dropdown list
var speciesList = {
'American Chestnut': 'models/castanea_dentata_dry.stl',
'Aquilapollenites': 'models/aquilapollenites_quadrilobus.stl',
'Big Bluestem': 'models/andropogon_gerardii.stl',
'Eastern Larch': 'models/larix_laricina.stl',
'Eastern White Pine': 'models/pinus_strobus.stl',
'Goldenrod': 'models/solidago_rugosa.stl',
'Japanese Barberry': 'models/berberis_thunbergii.stl',
'Mountain Laurel': 'models/kalmia_latifolia.stl',
'Princess Pine': 'models/lycopodium_obscurum.stl',
'Royal Fern': 'models/osmunda_regalis.stl',
'Sensitive Fern': 'models/onoclea_sensibilis.stl',
'Silver Maple': 'models/acer_saccharinum_fresh.stl',
};
//Model loaded by default
params = {
Species: 'models/solidago_rugosa.stl'
};
init();
animate();
function init() {
//Defining the scene, camera, renderer...
//GUI
gui = new dat.GUI({hideable: false});
gui.add(params, 'Species', speciesList)
.onChange(function(){
speciesLoad();
});
//Controls, window resizer...
};
//Function removes old model and loads new one when the dropdown selection changes.
function speciesLoad(){
if (mesh !== undefined) {
scene.remove(mesh);
};
loader = new THREE.STLLoader();
loader.load(
params.Species,
function(geometry){
var material = new THREE.MeshLambertMaterial({color: 0x99a300});
mesh = new THREE.Mesh(geometry, material)
scene.add(mesh);
},
function(xhr){
console.log((xhr.loaded / xhr.total * 100) + '% loaded');
},
function(error){
console.log('An error happened');
}
);};
//Light...
//Defining animate & render functions...
我有一个使用 Three.JS 的网络 3D 模型查看器。我正在尝试使用 dat.GUI 实现一种从下拉列表中选择不同模型的方法。我正在尝试使用 switch 语句来完成此操作,灵感来自 Three.JS 网站(materials/reflectivity 和 envmaps/hdr/nodes)上的一些示例。
当我只尝试加载一个模型时,我的加载器工作正常。但是当我尝试将它连接到 GUI 和 switch 语句时,模型没有出现(控制台日志显示 100% 加载,但我不知道这是真的还是我的负载报告器的错误)。控制台日志也 returns 这个错误:
Error: THREE.OBJLoader: Unexpected line: "<!DOCTYPE html>" OBJLoader.js:624:12
谷歌搜索错误 returns 建议 .obj 文件已损坏。我知道我的模型很好,因为我已经自己成功加载了它们。所以我只能假设问题是我正在加载加载程序的变量。我知道 OBJLoader 可以从变量加载,因为我尝试只定义一个变量作为模型(var model = 'my_model.obj',然后让加载器加载 "model"),这很有效。所以我将其缩小为 GUI 代码或 switch 语句的问题。
这是我的脚本,删除了一些不相关的部分。
var gui;
var camera, scene, renderer;
var species, params;
//3D models to choose from in dropdown list.
var speciesList = {
'Goldenrod': 'models/solidago_rugosa.obj',
'Mountain Laurel': 'models/kalmia_latifolia.obj',
};
//Model loaded by default
params = {
Species: 'models/solidago_rugosa.obj'
};
init();
animate();
function init() {
//defining the scene, camera, renderer...
//GUI
gui = new dat.GUI({hideable: false});
gui.add(params, 'Species', speciesList)
//controls, window resizer...
};
//Switch to load a different model.
//speciesCurrent is used by loader.
//No method to remove the previously loaded model yet, but I figure it should be able to load models on top of each other for now.
var speciesCurrent;
switch (speciesList) {
case 'models/solidago_rugosa.obj':
speciesCurrent = 'models/solidago_rugosa.obj';
break;
case 'models/kalmia_latifolia.obj':
speciesCurrent = 'models/kalmia_latifolia.obj';
break;
};
//Loader
var loader = new THREE.OBJLoader();
loader.load(
speciesCurrent,
function(object){
var material = new THREE.MeshLambertMaterial({color: 0x99a300});
object.traverse(function (child){
if (child instanceof THREE.Mesh){
child.material=material;
child.material.flatShading = 0;
}
});
scene.add(object);
},
function(xhr){
console.log((xhr.loaded / xhr.total * 100) + '% loaded');
},
function(error){
console.log('An error happened');
}
);
//Light sources...
//Game loop
function animate(){
requestAnimationFrame( animate );
render();
};
function render(){
renderer.render(scene,camera);
};
如何让我的加载器实际加载从下拉列表中选择的模型?谢谢。
更新:我的浏览器开发工具的网络选项卡显示我的索引文件列出了两次。标记为 "xhr" 的代码通过堆栈跟踪链接到索引文件的第 93 行,这是加载程序开始的地方 ("loader.load")。注释掉 switch 语句会删除额外的 html 文件。是什么导致我的加载程序将 switch 语句视为 html?
它正在工作。我告诉加载程序加载 params.Species(当前选择的 Species 文件)并废弃了 switch 语句。我还添加了一个函数,该函数在 GUI 更改时触发,并且还会删除任何先前加载的模型。这是当前的工作代码:
var gui;
var camera, scene, renderer;
var species, params;
var loader, mesh
//3D models to choose from in dropdown list
var speciesList = {
'American Chestnut': 'models/castanea_dentata_dry.stl',
'Aquilapollenites': 'models/aquilapollenites_quadrilobus.stl',
'Big Bluestem': 'models/andropogon_gerardii.stl',
'Eastern Larch': 'models/larix_laricina.stl',
'Eastern White Pine': 'models/pinus_strobus.stl',
'Goldenrod': 'models/solidago_rugosa.stl',
'Japanese Barberry': 'models/berberis_thunbergii.stl',
'Mountain Laurel': 'models/kalmia_latifolia.stl',
'Princess Pine': 'models/lycopodium_obscurum.stl',
'Royal Fern': 'models/osmunda_regalis.stl',
'Sensitive Fern': 'models/onoclea_sensibilis.stl',
'Silver Maple': 'models/acer_saccharinum_fresh.stl',
};
//Model loaded by default
params = {
Species: 'models/solidago_rugosa.stl'
};
init();
animate();
function init() {
//Defining the scene, camera, renderer...
//GUI
gui = new dat.GUI({hideable: false});
gui.add(params, 'Species', speciesList)
.onChange(function(){
speciesLoad();
});
//Controls, window resizer...
};
//Function removes old model and loads new one when the dropdown selection changes.
function speciesLoad(){
if (mesh !== undefined) {
scene.remove(mesh);
};
loader = new THREE.STLLoader();
loader.load(
params.Species,
function(geometry){
var material = new THREE.MeshLambertMaterial({color: 0x99a300});
mesh = new THREE.Mesh(geometry, material)
scene.add(mesh);
},
function(xhr){
console.log((xhr.loaded / xhr.total * 100) + '% loaded');
},
function(error){
console.log('An error happened');
}
);};
//Light...
//Defining animate & render functions...