Pesquisa de site

angular - Three.js -> FileLoader(scope.manager) não é um construtor


Isso pode parecer uma pergunta duplicada, já que é muito semelhante a esta ou a muitas outras, mas nenhum dos posts que eu vi realmente me ajudou a descobrir onde está o problema (claro, sou eu ;) ...), por isso ouso postar aqui, já que isso está me deixando realmente louco.

Bem, estou trabalhando em um projeto em Angular2 gerado com Angular CLI (sem tarefa de backend ou qualquer tráfego, apenas arquivos HTML + CSS + JS no momento ... tudo atualizado e na versão mais recente). Eu importei Three.js e three-obj-loader através do npm e declarei isso no meu componente assim:

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

Posso desenhar qualquer forma, usar luzes e sombras, mas não consigo carregar malha de um arquivo .obj externo. Eu tentei muitas variações parecendo assim:

  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 );
   } );

Não consigo dizer por quê, mas quando tento carregar obj a partir do arquivo, recebo um erro no console:

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

e a tela está vazia. O erro está se referindo à linha 49 do módulo "three-obj-loader" que instalei daqui. A parte desse código de terceiros mencionada é:

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);
},

Não tenho certeza se isso pode estar relacionado, mas eu não instalei nem declarei nenhum tipo especial para esses módulos, usando apenas os arquivos fonte JS puros. Também não instalei nenhum carregador de arquivos.

NOTA: Eu tentei implementar o OBJLoader2 daqui, mas obtive o mesmo resultado.

Obrigado por qualquer conselho.

Melhor k

Resposta #1

OK! Graças ao @TheJimO1 e ao seu comentário, consegui resolver o problema. Eu usei um pacote NPM diferente de JordanDelcros, que fornece arquivos diferentes do pacote do MrDoob que eu estava usando anteriormente... então eu o importei para o meu componente assim:

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

O OBJloader carrega de um arquivo externo sem nenhum problema agora.

ATUALIZAÇÃO: Mais uma vez, graças a @TheJimO1, consegui fazer isso funcionar de uma maneira diferente com este pacote mais oficial que suporta a versão mais recente do Three.js e funciona com o three-obj-loader. Eu apenas o importei da seguinte forma:

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

Bem, isso significa que existem pelo menos duas soluções diferentes que funcionam:

[A] use o pacote npm único mencionado anteriormente por JordanDelcros, que suporta r77 com todos os complementos incluídos;

[B] use mais oficialmente os três pacotes mencionados acima em combinação com o pacote three-obj-loader (mencionado na pergunta original) que suporta r85