ThreeJS模型加载器在类方法中使用时加载失败。

huangapple go评论102阅读模式
英文:

ThreeJS model loader failed to load when used inside a class method

问题

我正在尝试构建一个ThreeJS场景,并将其编码为一个类:

  1. export class RenderCanvas {
  2. #scene; // THREE.Scene()
  3. // 其他属性和方法
  4. loadGeometries() {
  5. /* 在调用loadGeometries之前,#scene已经被初始化 */
  6. var modelLoader = new FBXLoader();
  7. for (let path of listOfObjects) {
  8. modelLoader.load(path,
  9. function (obj) {
  10. obj.traverse(function (child) { /* 什么也没做 */ });
  11. this.#scene.add(obj);
  12. },
  13. function (xhr) {
  14. console.log((xhr.loaded / xhr.total * 100) + "% loaded")
  15. },
  16. function (err) {
  17. console.error("加载对象时出错")
  18. }
  19. )
  20. }
  21. }
  22. }

在另一个JS文件中,实例化了一个RenderCanvas类,并调用了loadGeometries()方法。

控制台显示模型加载到了100%,但随后触发了Error loading the object错误。

我注意到,如果我使用过程式的方式而不是面向对象编程,并将scene作为全局变量,那么模型加载器就能正常工作。所以我猜测问题可能与this.#scene.add(obj);缺少上下文有关,但我不确定是否确实是这种情况,也不知道如何修复。

出了什么问题,我该如何修复?

英文:

I'm trying to build a ThreeJS scene and have been coding it as a class:

  1. export class RenderCanvas {
  2. #scene; // THREE.Scene()
  3. // Other properties and methods
  4. loadGeometries() {
  5. /* #scene is initialized prior to loadGeometries being called */
  6. var modelLoader = new FBXLoader();
  7. for (let path of listOfObjects) {
  8. modelLoader.load(path,
  9. function (obj) {
  10. obj.traverse(function (child) { /* did nothing */ });
  11. this.#scene.add(obj);
  12. },
  13. function (xhr) {
  14. console.log((xhr.loaded / xhr.total * 100) + "% loaded")
  15. },
  16. function (err) {
  17. console.error("Error loading the object")
  18. }
  19. )
  20. }
  21. }

In another JS file, a RenderCanvas class is instantiated and has the loadGeometries() method called.

The console showed that the model is loaded to 100%, but then the Error loading the object is triggered.

I noticed that if I use the procedural way instead of OOP and have scene as a global variable, then the model loader would work. So I am assuming that it has something to do with this.#scene.add(obj); missing the context, but have no idea if this is indeed the case or how to fix that.

What went wrong and how may I fix it?

答案1

得分: 1

似乎this指向的引用不正确,因为你在onLoad()回调函数内部。尝试将this引用保存在一个scope变量中。类似这样:

  1. loadGeometries() {
  2. /* #scene在调用loadGeometries之前已经初始化 */
  3. var modelLoader = new FBXLoader();
  4. var scope = this;
  5. for (let path of listOfObjects) {
  6. modelLoader.load(path,
  7. function (obj) {
  8. obj.traverse(function (child) { /* 未做任何操作 */ });
  9. scope.#scene.add(obj);
  10. },
  11. function (xhr) {
  12. console.log((xhr.loaded / xhr.total * 100) + "% 已加载");
  13. },
  14. function (err) {
  15. console.error("加载对象时出错");
  16. }
  17. );
  18. }
  19. }

或者,使用箭头函数而不是普通函数,因为箭头函数保留了this引用。

英文:

It seems this does not point to the right reference since you are inside the onLoad() callback. Try to save the this reference in a scope variable. Something like:

  1. loadGeometries() {
  2. /* #scene is initialized prior to loadGeometries being called */
  3. var modelLoader = new FBXLoader();
  4. var scope = this;
  5. for (let path of listOfObjects) {
  6. modelLoader.load(path,
  7. function (obj) {
  8. obj.traverse(function (child) { /* did nothing */ });
  9. scope.#scene.add(obj);
  10. },
  11. function (xhr) {
  12. console.log((xhr.loaded / xhr.total * 100) + "% loaded")
  13. },
  14. function (err) {
  15. console.error("Error loading the object")
  16. }
  17. )
  18. }
  19. }

Alternatively, use an arrow function instead of normal one since the former one retains the this reference.

huangapple
  • 本文由 发表于 2023年8月9日 01:54:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/76862078.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定