代码之家  ›  专栏  ›  技术社区  ›  5rod

如何在three_js(Flutter)中设置缓冲区几何属性?

  •  0
  • 5rod  · 技术社区  · 6 月前

    我正在开发一个three_js项目,但它是Flutter包three_js,而不是JavaScript模块three.js。最近,我一直在使用three_js将一些JavaScript代码转换为Flutter,但我不知道如何设置缓冲区几何属性。这是JavaScript:

    const g = new THREE.BufferGeometry();
    
    g.setAttribute(
      'position',
      new THREE.BufferAttribute(new Float32Array(this.branches.verts), 3),
    );
    
    g.setAttribute(
      'normal',
      new THREE.BufferAttribute(new Float32Array(this.branches.normals), 3),
    );
    
    g.setAttribute(
      'uv',
      new THREE.BufferAttribute(new Float32Array(this.branches.uvs), 2),
    );
    
    g.setIndex(
      new THREE.BufferAttribute(new Uint16Array(this.branches.indices), 1),
    );
    

    首先让我感到惊讶的是函数参数的顺序,我查看了 source code 并找到了此函数语法: BufferGeometry setAttribute(Attribute type, dynamic attribute) ,与JavaScript版本相比,它切换参数。当然,在比较一种语言到另一种语言的端口时,我应该预料到代码会有一些变化,原因有很多,所以这并不奇怪。快速修复,我所要做的就是切换参数的顺序,对吧?不。我改变了顺序,然后意识到我有一个更大的问题。

    当我试图初始化类Attribute时,VS Code对我说:“生成枚举构造函数只能用作重定向的目标。”我不太确定这意味着什么,但我想我可能只需要使用BufferAttribute,然后进行类型转换就可以了。。。但BufferAttribute显然是一个抽象类,所以我选择了 Float32BufferAttribute (以及 Uint16BufferAttribute ),然后进行类型转换,如下所示:

    g.setAttribute(
      three.Float32BufferAttribute(three.Float32Array.fromList(normals), 3) as three.Attribute,
      'normal'
    );
    

    这使得错误消失了,但它也不起作用,因为当我运行它时,它没有正确地应用于屏幕。

    在这一点上,我正在寻找一个知道这一切意味着什么的人,以及 对的 函数的语法为 three_js 是three.js的移植版本,在开发人员社区中并不常见,因此我的问题没有那么多答案。

    注意:我意识到直接从JavaScript复制并不是一种优化或良好的做法,但为了回答问题,请忽略它。

    1 回复  |  直到 6 月前
        1
  •  0
  •   Abion47    6 月前

    documentation ,顺序似乎根本没有改变。你只是误解了 Attribute 第一个参数的类型。

    在这里, Attribute 是一个枚举,用于替换Three的魔术字符串。JS使用(如果使用Typescript定义,则使用联合类型)。所以,而不是 setAttribute('position', ...) 你会使用 setAttribute(Attribute.position, ...) 。然后,您将传递相应的 BufferAttribute object到第二个动态参数(这应该有更好的文档记录,但我想这取决于你查阅Three.JS文档并自己执行必要的转换)。

    Dart版本的:

    g.setAttribute(
      'position',
      new THREE.BufferAttribute(new Float32Array(this.branches.verts), 3),
    );
    

    应该是:

    g.setAttribute(
      Attribute.position,
      three.BufferAttribute(three.Float32Array.fromList(verts), 3),
    );
    // OR
    g.setAttribute(
      Attribute.position,
      three.Float32BufferAttribute.fromList(verts, 3),
    );
    

    或者,您可以使用 setAttributeFromString 为了获得与JS版本更相似的语法,但如果可能的话,我不建议这样做。