Three.js - 从文件输入加载 Collada 文件(和纹理)
Three.js - Load Collada file (and textures) from file inputs
目前,我有 2 个输入,一个用于几何 (.dae) 文件,一个用于纹理 (.png/.jpg)。我正在尝试使用文件输入中的那些纹理加载 Collada 文件。当文件输入更改时,我有 2 个函数被调用:
- loadCollada():当几何文件输入变化时使用THREE.ColladaLoader加载几何,并将几何存储在名为loadedCollada[=31=的全局变量中]
- loadTextures():当纹理文件输入改变时使用THREE.TextureLoader加载纹理,并将纹理存储在名为loadedTextures[=31=的全局变量中]
在调用这两个函数之后,将调用第三个函数 loadModel()。目前,我已经开始工作了;模型最终显示出来了,但是纹理应用不正确,如果模型的上轴不是 Y_UP,它显示的角度不对。这是我为 loadModel() 编写的代码的作用:
- 从 loadedCollada 中提取几何图形到名为 geometries
的数组中
- 使用 THREE.GeometryUtils.merge() 函数
将数组中的所有几何图形合并为一个几何图形 (THREE.Geometry)
- 从 loadedTextures
中的单个几何体和纹理创建最终网格
- 将模型放入场景中
任何帮助将不胜感激;我已经尝试弄清楚了很长一段时间。如果我不必从用户的机器加载 Collada 文件就好了,但我必须以某种方式让它从文件输入中工作。谢谢:)
我最近一直在用来自用户文件输入的 OBJ+MTL 文件做同样类型的事情。
对 three.js (r88) https://github.com/mrdoob/three.js/pull/11259 的添加允许您
覆盖资源 URL(将从文件上传中 select 编辑)。
我也看到了这个例子https://github.com/mrdoob/three.js/pull/12591 用来帮我解决加载OBJ+MTL
文件,它应该适用于大多数模型加载器,前提是它们使用 loadingManager。这也使得成为可能
仅使用一个文件输入并同时 select model/textures(因此它也可以支持拖放)。
因此我根据上面的 collada 格式示例制作了 fiddle:https://jsfiddle.net/Lhrvna7a/45/
相关部分是:
$('.inputfile').change(function (e) {
var files = e.currentTarget.files;
var dae_path;
var extraFiles = {}, file;
for (var i = 0; i < files.length; i++) {
file = files[i];
extraFiles[file.name] = file;
//Filename ends in .dae/.DAE
if (files[i].name.match(/\w*.dae\b/i)) {
dae_path = files[i].name;
}
}
const manager = new THREE.LoadingManager();
manager.setURLModifier(function (url, path) {
url = url.split('/');
url = url[url.length - 1];
if (extraFiles[url] !== undefined) {
var blobURL = URL.createObjectURL(extraFiles[url]);
console.log(blobURL); //Blob location created from files selected from file input
return blobURL;
}
return url;
});
var loader = new THREE.ColladaLoader(manager);
loader.load(dae_path, function (collada) {
console.log(collada);
var dae = collada.scene;
scene.add(dae);
});
});
}
加载模型后,我假设您提到的其他事情(例如合并)也可以执行相同的操作
就像他们正常加载模型时一样。
至于模型angle/orientation,该模型可能是在使用不同坐标的软件中创建的
系统到 three.js。我不确定是否有可能事先在 collada 中知道模型的旋转
(也许我错了),但在将模型添加到之前设置 dae.rotation.set(0, 0, 0);
可能就足够了
现场。
希望对您有所帮助。
目前,我有 2 个输入,一个用于几何 (.dae) 文件,一个用于纹理 (.png/.jpg)。我正在尝试使用文件输入中的那些纹理加载 Collada 文件。当文件输入更改时,我有 2 个函数被调用:
- loadCollada():当几何文件输入变化时使用THREE.ColladaLoader加载几何,并将几何存储在名为loadedCollada[=31=的全局变量中]
- loadTextures():当纹理文件输入改变时使用THREE.TextureLoader加载纹理,并将纹理存储在名为loadedTextures[=31=的全局变量中]
在调用这两个函数之后,将调用第三个函数 loadModel()。目前,我已经开始工作了;模型最终显示出来了,但是纹理应用不正确,如果模型的上轴不是 Y_UP,它显示的角度不对。这是我为 loadModel() 编写的代码的作用:
- 从 loadedCollada 中提取几何图形到名为 geometries 的数组中
- 使用 THREE.GeometryUtils.merge() 函数 将数组中的所有几何图形合并为一个几何图形 (THREE.Geometry)
- 从 loadedTextures 中的单个几何体和纹理创建最终网格
- 将模型放入场景中
任何帮助将不胜感激;我已经尝试弄清楚了很长一段时间。如果我不必从用户的机器加载 Collada 文件就好了,但我必须以某种方式让它从文件输入中工作。谢谢:)
我最近一直在用来自用户文件输入的 OBJ+MTL 文件做同样类型的事情。
对 three.js (r88) https://github.com/mrdoob/three.js/pull/11259 的添加允许您 覆盖资源 URL(将从文件上传中 select 编辑)。
我也看到了这个例子https://github.com/mrdoob/three.js/pull/12591 用来帮我解决加载OBJ+MTL 文件,它应该适用于大多数模型加载器,前提是它们使用 loadingManager。这也使得成为可能 仅使用一个文件输入并同时 select model/textures(因此它也可以支持拖放)。
因此我根据上面的 collada 格式示例制作了 fiddle:https://jsfiddle.net/Lhrvna7a/45/
相关部分是:
$('.inputfile').change(function (e) {
var files = e.currentTarget.files;
var dae_path;
var extraFiles = {}, file;
for (var i = 0; i < files.length; i++) {
file = files[i];
extraFiles[file.name] = file;
//Filename ends in .dae/.DAE
if (files[i].name.match(/\w*.dae\b/i)) {
dae_path = files[i].name;
}
}
const manager = new THREE.LoadingManager();
manager.setURLModifier(function (url, path) {
url = url.split('/');
url = url[url.length - 1];
if (extraFiles[url] !== undefined) {
var blobURL = URL.createObjectURL(extraFiles[url]);
console.log(blobURL); //Blob location created from files selected from file input
return blobURL;
}
return url;
});
var loader = new THREE.ColladaLoader(manager);
loader.load(dae_path, function (collada) {
console.log(collada);
var dae = collada.scene;
scene.add(dae);
});
});
}
加载模型后,我假设您提到的其他事情(例如合并)也可以执行相同的操作 就像他们正常加载模型时一样。
至于模型angle/orientation,该模型可能是在使用不同坐标的软件中创建的
系统到 three.js。我不确定是否有可能事先在 collada 中知道模型的旋转
(也许我错了),但在将模型添加到之前设置 dae.rotation.set(0, 0, 0);
可能就足够了
现场。
希望对您有所帮助。