0

我正在尝试将立方体的 3D 模型加载到3D Force Directed Graphusing GLTFLoaderin 中three.js。该项目是使用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似乎是相同的。

任何帮助深表感谢。

4

1 回答 1

0

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

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

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

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

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

scene.traverse(function(node){
    if(node.geometry){
        node.geometry.computeBoundingSphere();
    }
});
于 2018-03-23T13:05:37.087 回答