【问题标题】:Ok to store scene object instances as properties of scene?可以将场景对象实例存储为场景的属性吗?
【发布时间】:2019-03-11 23:07:58
【问题描述】:

这是一个关于 javascript 和 three.js 编码风格约定的问题。我更喜欢使用最新的 ES-whatever 约定。

我想知道是否不照常做:

var scene = new THREE.Scene();
var cube = new THREE.Mesh(new THREE.BoxGeometry(1,1,1), new THREE.MeshBasicMaterial(0xffffff))
scene.add(cube)

可以将网格对象(和其他对象,可能是灯光甚至相机)存储为场景对象的属性:

const scene = new THREE.Scene(); // or var, but that's not my question
scene.cube = THREE.Mesh(new THREE.BoxGeometry(1,1,1), new THREE.MeshBasicMaterial(0xffffff))
scene.add(scene.cube)

我喜欢在scene 命名空间下引用所有三个.js 对象的想法——这让我以后更容易访问它们。我知道我可以将它与 .name 和 .getObjectByName 一起使用,但这需要更多代码并且对我来说似乎更混乱。

【问题讨论】:

  • 投票结束,因为它主要基于意见。也就是说,这是我的观点:这是不好的做法。它并没有真正使您的代码更清晰或更易于推理。事实上,它使事情变得更加复杂。另外,对由 3rd 方库创建/管理的对象的实例进行变异可能是不可预测的。如果您想将相关的数据引用存储在一起,请使用常规的旧对象:const sceneData = {scene, cube};
  • “见仁见智”对我来说是一个令人满意的答案。我只是想知道这是绝对错误、绝对正确还是介于两者之间。

标签: javascript three.js


【解决方案1】:

Object3D 派生对象上有一个名为 .userData 的字段,您可以存储应该保存/序列化的内容。但就直接在对象上存储道具而言..它可以工作..但如果您最终覆盖某些内容或稍后使用您的属性名称的三个版本可能会出现问题...

编辑:在阅读了这里的其他帖子之后,他们提出了一些好观点,我还想指出,您可以将内置的三个对象子类化并创建您自己的自定义类型来包含您的东西。那可能更整洁。

【讨论】:

    【解决方案2】:

    就关注点分离而言,您不想将 Three 的对象用作数据持有者。这似乎是一个简单的出路,但会大大降低代码的可维护性。不过,没有什么能阻止你今天这样做。考虑一下,你会有

    scene.cube
    scene.children[0] //same cube
    scene.getObjectById(... cube id ...) //same cube
    //... byName, ...byProperty etc. all pointing to the same cube
    

    请记住,Scene 扩展了 Object3D 及其所有方法和属性,因此,在下面的示例场景中,所有对象都是 Object3D,每个对象都具有 children[] 属性。

            [scene]
          +----^-----------------------------+
      [chairGroup]                        [light] 
      +--^--+-----+-----+-----+------+
    [leg] [leg] [leg] [leg] [back] [seat] 
    

    上面的每个节点是不是都和 DOM 的 Element 很像?

    我会鼓励你把你的场景想象成一棵树。事实上,任何 UI 都是元素的 n 树:web、mobile、X11 等,每个 UI 框架都是操作这种树的工具。您用来操作 DOM 树的所有方法都在这里有效地工作。

    因此,以下是组织代码的各种方法,从简单到复杂:

    • hello world 旋转立方体示例很好,15-20 行代码就可以了
    • 渲染上下文:将scenecamerarenderer 移动到可以在图层周围传递的一些上下文对象中。可以将其视为浏览器中的document 等价物。
    • 高级“Shadow DOM”:组织您自己的组件树,每个组件处理一组 3d 对象,使它们对事件做出反应 - 来自 UI 点击等外部事件,或来自三个,如渲染期间的访问者模式。您可以在这些组件上保留对 3d 对象的引用,也可以递归地将结构传递给函数以调整场景的层次结构。树中此类组件的示例可能是椅子、建筑物、行星、星舰等。
    • 数据模型:在组件中存储一些数据可能很诱人,但您应该区分外部数据(通常有点全局,如 numberOfPlanets、timeOfDay 等)和内部数据(如当前旋转速度)行星。后者可以作为场景域组件的一部分。
    • 完整的 MVC:与任何 UI 一样,模型-视图-控制器适用于此。例如。你可以关注这个intro into three.js MVC
    • 调解员、观察员和通常的工作流程。见,例如my answer here.
    • ...一直到类似 Redux 的不可变状态管理系统

    我希望,这个答案能帮助人们围绕 Three.js 做一些最适合他们项目的战术架构。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-11-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多