可以将场景对象实例存储为场景的属性吗?

时间:2019-03-11 23:07:58

标签: javascript three.js

这是关于javascript和three.js编码样式约定的问题。我更喜欢使用最新的ES协议。

我想知道是否不是像往常一样:

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名称空间下引用所有Three.js对象的想法,这使我以后更容易访问它们。我知道我可以将它与.name和.getObjectByName一起使用,但这需要更多代码,而且对我来说似乎更麻烦。

1 个答案:

答案 0 :(得分: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,移动,X11等,每个UI框架都是操纵此类树的工具。您用来操纵DOM树的所有方法在这里都有效。

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

  • 您好,世界旋转多维数据集示例很好,按原样可以15-20行代码
  • 渲染上下文:将scenecamerarenderer移到一些上下文对象中,您可以在各个图层之间传递它们。在浏览器中将其视为document的等效项。
  • 高级“阴影DOM”:组织一棵由您自己的组件组成的树,每个组件都处理一组3d对象,使它们对事件做出反应-来自UI单击等外部事件,或者来自于三个事件,例如渲染期间的访问者模式。您可以在这些组件上保留对3d对象的引用,也可以将结构递归传递给函数以调整场景的层次结构。您的树中此类组件的示例包括椅子,建筑物,行星,星际飞船等。
  • 数据模型:在组件内部存储一些数据可能很诱人,但是您应该对外部数据(通常是全局变量,例如numeberOfPlanets,timeOfDay等)和内部数据(例如,组件的当前旋转速度)进行区分。行星。可以将其保留为场景域组件的一部分。
  • 完整的MVC:与任何UI一样,此处适用model-view-controller。例如。您可以遵循此intro into three.js MVC
  • 调解员,观察员和通常的工作流程。参见例如my answer here
  • ...一直到类似Redux的不可变状态管理系统

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

相关问题