5

I am using TypeScript and three.d.ts from definitely typed. I have no problems using THREE.JSONLoader, but how do I use an OBJLoader from here in a TypeScript project. I probably need to create an OBJLoader.d.ts file, but I have no idea how to do it and then how to use the created definition. I tried to simply copy the THREE.JSONLoader definition and rename it to OBJLoader, but that didn't work.

3 Answers 3

9

The latest Three.js now has ES Module versions of all the classes in the examples/ folder, along with type declaration files. So, now you can:

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

And it will be typed in TypeScript as expected (hover on it to see tooltips in VS Code).

1
  • Thanks a lot. That was so much easier than adding separate npm packages or the other suggested solutions!
    – tomfroehle
    Commented Sep 9, 2019 at 13:44
1

This answer was correct at the time of posting, but it's out of date now in 2019. See @trusktr's response below for a better solution today.

Having looked at the source of the OBJLoader here, (and with reference to three.d.ts) a simple objloader.d.ts file might look like this:

/// <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?
}

Caveat: this is quickly hacked together and not tested, but may help you to get started.

You would then reference your objloader.d.ts in the same way you are currently using three.d.ts. Don't forget to include both the three.js and OBJLoader.js files in your html page, or import them if you are working with external modules.

4
  • Thank you. I initially thought that OBJLoader should inherit from Loader and not EventDispatcher. I can now see, that the load and parse functions are actually called. The only problem is with the callback. The original code uses loader.addEventListener and I can see in Firebug, that addEventListener is undefined. But for example THREE.ImageLoader which also inherits from EventDispatcher does indeed have addEventListener defined. I also tried calling the OBJLoader like that: loader.load("myObject.obj", (response) => { //never reached });
    – Eiver
    Commented May 2, 2013 at 12:46
  • Further debugging shows that in OBJLoader.js in line 25: scope.dispatchEvent( { type: 'load', content: response } ); the dispatchEvent is undefined and the code halts there. In the original example however everything works fine, and I didn't modify the OBJLoader.js file...
    – Eiver
    Commented May 2, 2013 at 12:57
  • 1
    You were asking about a definition file. Now I think you're getting in to using objloader. I don't really know anything about that. Commented May 2, 2013 at 13:32
  • According to the definition load() takes a string and a callback function as an input. For some reason the callback doesn't get called after the OBJLoader has done its job. This happens only in typescript, as the pure JS example works just fine. So either the definition is not correct or I am using it in a wrong way. Anyway I am marking the question as answered because, the answer allowed me to get closer to the solution
    – Eiver
    Commented May 4, 2013 at 22:18
0

Add the libraries to your index.html or to your angular-cli.json if you're using angular2 cli:

$ 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"
      }
    }
  ],

Then reference the libraries like "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

You won't get type checking, but it's a quick way to get started until someone adds an entry for the loaders to definitely typed.

Not the answer you're looking for? Browse other questions tagged or ask your own question.