【发布时间】:2023-03-15 20:27:02
【问题描述】:
我有一个使用 Three.JS 的网络 3D 模型查看器。我正在尝试使用 dat.GUI 实现一种从下拉列表中选择不同模型的方法。我正在尝试使用 switch 语句来完成此操作,这受到了 Three.JS 网站上的一些示例(材料/反射率和 envmaps/hdr/nodes)的启发。
当我试图加载一个模型时,我的加载器工作正常。但是当我尝试将它连接到 GUI 和 switch 语句时,模型没有出现(控制台日志显示 100% 加载,但我不知道这是真的还是我的负载报告器的错误)。控制台日志也返回此错误:
Error: THREE.OBJLoader: Unexpected line: "<!DOCTYPE html>" OBJLoader.js:624:12
谷歌搜索错误会返回 .obj 文件已损坏的建议。我知道我的模型很好,因为我自己已经成功加载了它们。所以我只能假设问题是我正在加载加载程序的变量。我知道 OBJLoader 可以从变量加载,因为我尝试将一个变量定义为模型(var model = 'my_model.obj',然后让加载器加载“模型”),这很有效。所以我把它缩小到 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?
【问题讨论】:
-
如果出现上述错误,则表示您正在尝试使用
OBJLoader加载HTML 文件。请使用浏览器开发工具的网络选项卡确保您实际上从后端加载了正确的资源。 -
@Mugen87 我更新了 OP。看起来你是对的,但是当加载器从未被告知加载 html 文件时,是什么导致加载器感知 html?
-
可能是与 Web 服务器相关的问题。尝试使用
node.js和http-server 托管您的应用程序,看看它是否有效。 -
我希望 gui 选择上有一个
onChange事件侦听器,我在您的代码中没有看到。例如。 workshop.chromeexperiments.com/examples/gui/#7--Events -
将 switch 语句的参数从“speciesList”更改为“params.Species”消除了 doctype 错误。切换到 STL 加载器也有效。仍在努力将下拉选项链接到我告诉加载程序加载的变量,但我已经获得了一个 onChange 函数来在选择任何选项时加载默认模型。
标签: javascript arrays three.js dat.gui