【问题标题】:three.js Cannot read property 'center' of undefined三.js无法读取未定义的属性“中心”
【发布时间】:2018-08-31 21:24:41
【问题描述】:

我正在尝试使用GLTFLoader 中的three.js 将立方体的3D 模型加载到3D Force Directed Graph 上。该项目是使用Angular 构建的。

模型已加载,显示GLTFLoader: 23.507080078125ms,但未显示对象。它进一步给出了一个错误显示,

ERROR TypeError: Cannot read property 'center' of undefined
at Sphere.copy (three.module.js:5347)
at Mesh.raycast (three.module.js:14240)
at intersectObject (three.js:42091)
at Raycaster.intersectObjects (three.js:42164)
at animate (3d-force-graph.module.js:386)
at ZoneDelegate.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:398)
at Object.onInvokeTask (core.es5.js:4136)
at ZoneDelegate.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:397)
at Zone.webpackJsonp.../../../../zone.js/dist/zone.js.Zone.runTask (zone.js:165)
at ZoneTask.invoke (zone.js:460)
at timer (zone.js:1732)

加载模型的代码如下:

    var manager = new THREE.LoadingManager();
    var loader = new GLTFLoader(manager);
    loader.load(
      // resource URL
      'assets/model/cube.gltf',
      // called when the resource is loaded
      function ( gltf ) {           
        gltf.scene.traverse( function ( child ) {
          if ( child.isMesh ) {
            child.material = gltf.materials;
          }
        } );               
        var cube = gltf.scene; // Object        
        self.showGraph(gData,cube,themeNum);
        console.log("graph drawn");
      },
      // called when loading is in progresses
      function ( xhr ) {    
        console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );    
      },
      // called when loading has errors
      function ( error ) {    
        console.log( 'An error happened -- ' + error );    
      }
    );
    
// function to draw the graph -- to be executed on 3D model load
showGraph(gData:any, cube:any, themeNum: any){
    const Graph = ForceGraph3D()
      (document.getElementById('3d-graph'))
      .nodeThreeObject(({ group }) => new THREE.Mesh(
        [
          new THREE.BoxGeometry(Math.random() * 20, Math.random() * 20, Math.random() * 20),          
          cube,
          new THREE.CylinderGeometry(Math.random() * 10, Math.random() * 10, Math.random() * 20),
          new THREE.DodecahedronGeometry(Math.random() * 10),
          new THREE.SphereGeometry(Math.random() * 10),
          new THREE.TorusGeometry(Math.random() * 10, Math.random() * 2),
          new THREE.TorusKnotGeometry(Math.random() * 10, Math.random() * 2)
        ][group],
        new THREE.MeshLambertMaterial({
          color: this.themes[themeNum][group],
          transparent: true,
          opacity: 0.75
        })
      ))
        .nodeAutoColorBy('group')  
        .onNodeClick(node => {    
          this.attach3DNodeClickEvent(node);
        })      
        .graphData(gData); 
  }

从Blender导出的cube.gltf文件如下:

{
    "accessors" : [{
        "bufferView" : 0, 
        "componentType" : 5121, 
        "count" : 36, 
        "max" : [23], 
        "min" : [0], 
        "type" : "SCALAR"
    }, {
        "bufferView" : 1, 
        "componentType" : 5126, 
        "count" : 24, 
        "max" : [1, 1, 1], 
        "min" : [-1, -1, -1], 
        "type" : "VEC3"
    }, {
        "bufferView" : 2, 
        "componentType" : 5126, 
        "count" : 24, 
        "max" : [1, 1, 1], 
        "min" : [-1, -1, -1], 
        "type" : "VEC3"
    }], 
    "asset" : {
        "generator" : "Khronos Blender glTF 2.0 exporter", 
        "version" : "2.0"
    }, 
    "bufferViews" : [{
        "buffer" : 0, 
        "byteLength" : 36, 
        "byteOffset" : 0, 
        "target" : 34963
    }, {
        "buffer" : 0, 
        "byteLength" : 288, 
        "byteOffset" : 36, 
        "target" : 34962
    }, {
        "buffer" : 0, 
        "byteLength" : 288, 
        "byteOffset" : 324, 
        "target" : 34962
    }], 
    "buffers" : [{
        "byteLength" : 612, 
        "uri" : "cube.bin"
    }], 
    "materials" : [{
        "name" : "Material", 
        "pbrMetallicRoughness" : {
            "baseColorFactor" : [0.114473, 0.362915, 0.64, 1], 
            "metallicFactor" : 0
        }
    }], 
    "meshes" : [{
        "name" : "Cube", 
        "primitives" : [{
            "attributes" : {
                "NORMAL" : 2, 
                "POSITION" : 1
            }, 
            "indices" : 0, 
            "material" : 0
        }]
    }], 
    "nodes" : [{
        "name" : "Camera", 
        "rotation" : [0.483536, 0.336872, -0.208704, 0.780483], 
        "translation" : [7.48113, 5.34367, 6.50764]
    }, {
        "mesh" : 0, 
        "name" : "Cube"
    }, {
        "name" : "Lamp", 
        "rotation" : [0.169076, 0.75588, -0.272171, 0.570948], 
        "scale" : [1, 1, 1], 
        "translation" : [4.07625, 5.90386, -1.00545]
    }], 
    "scene" : 0, 
    "scenes" : [{
        "name" : "Scene", 
        "nodes" : [1, 2, 0]
    }]
}

我在这里做错了什么? three.js docs 上的示例似乎是相同的。

非常感谢任何帮助。

【问题讨论】:

  • 请包含完整的错误。它应该准确地告诉您问题发生的位置和原因。
  • 您可以在以下glTF 查看器中加载多维数据集吗? gltf-viewer.donmccurdy.com
  • @Mugen87 可以在glTF 查看器中加载,但必须同时提供Blender 生成的gltfbin 文件。
  • @TheJim01 我已经用完整的错误更新了这个问题。但是,它并没有提供太多关于错误发生位置的信息。
  • @fleur 没关系。您的 glTF 资产由这两个文件组成。如果你把.gltf.bin放在同一个文件夹下,应该可以通过GLTFLoader加载文件。

标签: javascript three.js 3d-model gltf


【解决方案1】:

根据错误,您正在 animate 函数中执行光线投射,这是发生错误的地方。具体来说,当光线投射过程试图复制对象的边界球体时会发生错误。

// three.js r91, Mesh.js, line 237
sphere.copy( geometry.boundingSphere );

它在geometry.boundingSphere 上找不到属性center,因为geometry.boundingSphere 未定义。

除非GLTFLoader 自动计算边界球,否则不会自动填充此信息。在对对象调用 raycast 之前,您需要调用 geometry.computeBoundingSphere()。如果GLTFLoader 没有做这项工作,那么您可能需要在整个场景中都这样做。

在加载数据之后(以及在启动 animate 之前)运行此代码将填充所有对象的边界球体:

scene.traverse(function(node){
    if(node.geometry){
        node.geometry.computeBoundingSphere();
    }
});

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-06-04
  • 2016-01-12
  • 2021-04-29
  • 2023-01-16
  • 2015-11-09
  • 2018-04-06
  • 2021-07-12
相关资源
最近更新 更多