【问题标题】:Threejs: How can one export with GLTFExporter an indexed geometry with draw range?Threejs:如何使用 GLTFExporter 导出具有绘制范围的索引几何?
【发布时间】:2023-03-14 22:10:02
【问题描述】:

我有一个特定的问题,我想导出一个具有绘制范围的索引几何。 使用 GLTFExporter,在遇到 typescript 集成问题(显然是已知问题)之后,我很不幸地发现这在导出器中没有实现:

// @TODO Indexed buffer geometry with drawRange not supported yet

https://github.com/mrdoob/three.js/blob/master/examples/js/exporters/GLTFExporter.js 第 564 行

检查提交历史告诉我上次更新是在 3 个月前,我认为这不会很快到来。 我试图删除索引缓冲区并根据我的绘制范围重写我的位置缓冲区属性数组,但我必须做错事,因为它不起作用,它只是破坏了我的几何图形。 你们中的任何人都可以为我解决问题或对如何继续我的几何图形进行一些解释吗?

提前谢谢你。

编辑:

我目前的解决方法是“de-index”我的几何图形用于导出并保留drawRange,这种情况由导出器处理。这并不理想,它迫使我用新的 BufferAttributes 重新创建一个全新的几何体。但由于此操作仅用于导出,我什至可以让此过程以异步方式发生。我希望有更好的方法。

【问题讨论】:

  • "I don't think this is gonna come any time soon." — 请随时在 GitHub 上打开问题。尚未解决此问题的原因可能是尚未有人提出要求。 :)
  • 会的,我会开一个问题

标签: javascript typescript three.js gltf


【解决方案1】:

关于这两个变量,我将在下面的 PR 中解决这个问题,使其成为 WebGLUtils 的一部分并导入它。每个需要这些常量的人每次都需要重新定义它们是没有意义的。

【讨论】:

    【解决方案2】:

    正如我在编辑中提到的,我通过de-indexing我的几何体绕过了我的问题,这不是最好的解决方案,但由于我只需要它来进行导出,这就是我的处理方式:

    // original attributes
    const vertices  = geometryTmp.getAttribute("position");
    const normals  = geometryTmp.getAttribute("normal");
    const uv  = geometryTmp.getAttribute("uv");
    
    // new buffer arrays
    let verticesTmp = new Float32Array(3 * geometryTmp.index.array.length);
    let normalTmp = new Float32Array(3 * geometryTmp.index.array.length);
    let uvTmp = new Float32Array(2 * geometryTmp.index.array.length);
    
    
    let j = 0;
    for(let i = 0; i < verticesTmp.length; i += 3) {
        let index = geometryTmp.index.array[j];
        verticesTmp[i] = vertices.getX(index);
        verticesTmp[i+1] = vertices.getY(index);
        verticesTmp[i+2] = vertices.getZ(index);
    
        normalTmp[i] = normals.getX(index);
        normalTmp[i+1] = normals.getY(index);
        normalTmp[i+2] = normals.getZ(index);
        j++;
    
    }
    
    j = 0;
    for(let i = 0; i < uvTmp.length; i += 2) {
        let index = geometryTmp.index.array[j];
        uvTmp[i] = uv.getX(index);
        uvTmp[i+1] = uv.getY(index);
        j++;
    }
    
    let newGeomtry = new THREE.BufferGeometry();
    newGeomtry.addAttribute( 'position', new THREE.BufferAttribute( verticesTmp, 3 ) );
    newGeomtry.addAttribute( 'normal', new THREE.BufferAttribute( normalTmp, 3 ) );
    newGeomtry.addAttribute( 'uv', new THREE.BufferAttribute( uvTmp, 2 ) );
    
    newGeomtry.drawRange = geometryTmp.drawRange;
    mesh.geometry = newGeomtry;  
    
    // After I do that to all the meshes I need, them to a new THREE.Scene that will be given to the exporter with truncateDrawRange = true
    

    我希望它也能帮助别人。

    【讨论】:

      猜你喜欢
      • 2021-11-01
      • 2019-11-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-19
      • 1970-01-01
      • 1970-01-01
      • 2020-01-27
      相关资源
      最近更新 更多