如何在TypeScript中使用three.js加载OBJ模型

5
我正在使用 TypeScript 和从definitely typed下载的three.d.ts。我在使用THREE.JSONLoader时没有问题,但是如何在TypeScript项目中使用这里OBJLoader呢?我可能需要创建一个OBJLoader.d.ts文件,但我不知道该怎么做,也不知道如何使用所创建的定义。我试图简单地复制THREE.JSONLoader的定义并将其重命名为OBJLoader,但这行不通。
3个回答

9

最新的Three.js现在已经有了examples/文件夹中所有类的ES模块版本,还有类型声明文件。因此,现在您可以:

import {OBJLoader} from 'three/examples/jsm/loaders/OBJLoader'

按预期,它将以TypeScript键入(在VS Code中将其悬停以查看工具提示)。


非常感谢。这比添加单独的npm包或其他建议的解决方案要容易得多! - tomfroehle

1
这个回答在发布时是正确的,但现在已经过时了(2019年)。请查看@trusktr的下面的回答,以获得更好的解决方案。
查看OBJLoader的源代码here后,结合three.d.ts,一个简单的objloader.d.ts文件可能如下所示:
/// <reference path="three.d.ts" />

export class OBJLoader extends EventDispatcher {
        constructor();
        load(url: string, callback?: (response:any) => any): void;
        parse(data:any):any; // Not sure if the return value can be typed. Seems to be a group but I can't find a definition for that in three.d.ts?
}

注意:这只是快速拼凑而成,未经测试,但可能会帮助您入门。

然后,您将以与当前使用three.d.ts相同的方式引用您的objloader.d.ts。不要忘记在您的html页面中同时包含three.jsOBJLoader.js文件,或者如果您正在使用外部模块,则导入它们。


谢谢。我最初认为 OBJLoader 应该继承自 Loader 而不是 EventDispatcher。现在我可以看到,load 和 parse 函数确实被调用了。唯一的问题是回调函数。原始代码使用 loader.addEventListener,但我可以在 Firebug 中看到 addEventListener 未定义。但是例如 THREE.ImageLoader,它也继承自 EventDispatcher,确实定义了 addEventListener。我还尝试像这样调用 OBJLoader:loader.load("myObject.obj", (response) => { // 永远不会到达 }); - Eiver
进一步调试显示,在OBJLoader.js的第25行:scope.dispatchEvent({type:'load',content:response});中,dispatchEvent未定义,代码在此处停止。然而,在原始示例中,一切都正常工作,我没有修改OBJLoader.js文件... - Eiver
1
你之前在问一个定义文件的问题。现在我觉得你正在开始使用objloader。对于这个我实在不了解。 - Jude Fisher
根据定义,load() 接受一个字符串和回调函数作为输入。由于某种原因,在 OBJLoader 完成其工作后,回调函数没有被调用。这只发生在 TypeScript 中,因为纯 JS 示例运行良好。所以要么定义不正确,要么我使用的方式不正确。无论如何,我将问题标记为已解决,因为答案让我更接近解决方案。 - Eiver

0

如果你正在使用angular2 cli,请将库添加到你的index.html或angular-cli.json中:

$ cat angular-cli.json
{
  "project": {
    "version": "1.0.0-beta.16",
    "name": "ssp"
  },
  "apps": [
    {
      "root": "src",
      "outDir": "dist",
      "assets": "assets",
      "index": "index.html",
      "main": "main.ts",
      "test": "test.ts",
      "tsconfig": "tsconfig.json",
      "prefix": "app",
      "mobile": false,
      "styles": [
        "styles.css"
      ],
      "scripts": [
        "../node_modules/three/build/three.js",
        "../node_modules/three/examples/js/controls/VRControls.js",
        "../node_modules/three/examples/js/effects/VREffect.js",
        "../node_modules/webvr-boilerplate/build/webvr-manager.js",
        "../node_modules/dat-gui/vendor/dat.gui.js",
        "../node_modules/stats-js/build/stats.min.js",
        "../node_modules/three/examples/js/controls/OrbitControls.js",
        "../node_modules/three/examples/js/loaders/OBJLoader.js", <-- add
        "../node_modules/three/examples/js/loaders/MTLLoader.js" <-- add
        ],
      "environments": {
        "source": "environments/environment.ts",
        "dev": "environments/environment.ts",
        "prod": "environments/environment.prod.ts"
      }
    }
  ],

然后像这样引用库 "var mtlLoader = new (THREE as any).MTLLoader( );":

var mtlLoader = new (THREE as any).MTLLoader( );
mtlLoader.setPath( '../../assets/models' );
mtlLoader.load( 'myProject.mtl', function( materials ) {
  materials.preload();
  var loader = new (THREE as any).OBJLoader();
  loader.setMaterials(materials);
  loader.load( '../../assets/models/myProject.obj', function(object) {
... do stuff

虽然你不会得到类型检查,但这是一个快速入门的方法,直到有人在definitely typed中添加装载器的条目。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接