3

This might seems as a duplicated question, since it is very similar to this one or many others, but none of the posts I have seen really helped me to figure out where the problem is ( sure, it's me ;) ...), hence I dare to post it here, since it makes me going really crazy.

Well, I am working on a project in Angular2 generated with Angular CLI (no backend task or any trafficking, just HTML + CSS + JS files at the moment ... all up to date and latest). I have imported Three.js and three-obj-loader through npm and declared it in my component like this:

import * as THREE from 'three';
declare var require: any;
const OBJLoader = require('three-obj-loader')(THREE);

I can draw any shape, use lights and shades, but cannot load mesh from external .obj file. I have tried many variations looking like this:

  const manager = new THREE.LoadingManager();
  const loader = new THREE.OBJLoader( manager );
  loader.load( './working/path/to/file.obj', function ( object ) {

       object.position.x = 0;
       object.position.y = 0;
       object.scale.x = 10;
       object.scale.y = 10;
       object.scale.z = 10;
       const texture = THREE.TextureLoader('./working/path/to/file.jpg');
       const material = new THREE.MeshLambertMaterial( { map: texture } );
       const mesh = new THREE.Mesh( object, material );
       scene.add( mesh );
   } );

I cannot tell why, but when I try to load obj from file, I receive console error:

TypeError: undefined is not a constructor (evaluating 'new THREE.FileLoader(scope.manager)')

and the canvas is empty.The error is referencing to line 49 of "three-obj-loader" module which I installed from here . The part of that third-party-code mentioned is:

THREE.OBJLoader.prototype = {

constructor: THREE.OBJLoader,

load: function load(url, onLoad, onProgress, onError) {

  var scope = this;

  var loader = new THREE.FileLoader(scope.manager);
  loader.setPath(this.path);
  loader.load(url, function (text) {

    onLoad(scope.parse(text));
  }, onProgress, onError);
},

Not sure if it might be related, but I did not installed or declared any special types for these modules, using just the plain JS source files. Also I have not installed any file loader.

NOTE: I have tried to implement OBJLoader2 from here but got the same result.

Thank you for any advice.

Best k

Community
  • 1
  • 1
  • OK, so I compared Three.js source files that you can get via NPM with current zip package (dev) at Github. It seems to me that NPM serves r77, but the dev is r85. There are significant differences. To name one striking is that NPM package is missing reference to FileLoader and there is no source file for FileLoader ... that sounds reasonable, given the error I receive ... well, I do not see deeply into the fabric of Three.js, hence it is bit difficult for me to rewrite that source in module I use or to make dev package working with my project ( my bad, I should learn that ... ). – Kristievnee May 04 '17 at 15:39
  • Just a note, I just pulled `three-js` from `npm` and got r79. It stil didn't contain `THREE.FileLoader` though, so there must be a miss-match between the version of `three-js`, and the version of `three-obj-loader` hosted in `npm`. – TheJim01 May 04 '17 at 16:09
  • Thanks for the note. It is interesting. What command did you use? When I do simple install without no flag, I receive r77 (v0.77.1) and when I try it with @latest or @^0.79.0 I receive: "npm ERR! notarget Valid install targets: npm ERR! notarget 0.0.1, 0.0.2, 0.1.0, 0.72.0, 0.73.0, 0.73.2, 0.77.0, 0.77.1" ... – Kristievnee May 04 '17 at 18:38
  • Perhaps you used this? https://github.com/JordanDelcros/npm-three-js ? That seems to be r79. I have just tried it, but I am not sure if I will be able to make it work, it has all the source files needed, but I fail to load them into my scope ... – Kristievnee May 04 '17 at 18:51

1 Answers1

1

OK! Thanks to @TheJimO1 and his comment I was able to solve the issue. I pulled out a different NPM package by JordanDelcros which serves different files than MrDoob's package I was using previously ... then I imported it into my component like this:

declare var require: any;
const OBJLoader = require('three-js/addons/OBJLoader');
const THREE = require('three-js')([OBJLoader]);

OBJloader loads from external file without any problem now.

UPDATE: Once again, thanks to @TheJimO1, I was able to make this work in a different way with this more official package supporting latest version of Three.js and working with three-obj-loader . I just imported is as follows:

declare var require: any;
const THREE = require('three');
const OBJLoader = require('three-obj-loader')(THREE);

Well that means there are at least two different working solutions:

[A] use previously mentioned single npm package by JordanDelcros which supports r77 with all addons included;

[B] use more official three package mentioned above in combination with three-obj-loader (mentioned in original question) packages which support r85

  • By the way, here's the package you actually want: https://www.npmjs.com/package/three The one you mention here is the same as the one I suggested, but is deprecated in favor of the official source. – TheJim01 May 04 '17 at 19:17
  • Hey, that is super! Super-confusing but also super clever ... this one you have posted support all the recent functionality, but requires external OBJloader ... works great with three-obj-loader ... Thanks!!! – Kristievnee May 04 '17 at 20:05