As far as separation of concern goes, you don't want to use Three's objects as data holders. It might seem like an easy way out, but will greatly reduce maintainability of your code. There is nothing preventing you from doing it today, though. Just consider, that you will have
scene.cube
scene.children[0] //same cube
scene.getObjectById(... cube id ...) //same cube
//... byName, ...byProperty etc. all pointing to the same cube
Remember, Scene
extends Object3D
with all its methods and properties, so, in the example scene below all objects are Object3D with each having children[]
property.
[scene]
+----^-----------------------------+
[chairGroup] [light]
+--^--+-----+-----+-----+------+
[leg] [leg] [leg] [leg] [back] [seat]
Doesn't each node above look similar to DOM's Element?
I would encourage you to think about your scene as a tree. In fact, any UI is an n-tree of elements: web, mobile, X11 etc., and every UI framework is a tool to manipulate such tree. All approaches you use to manipulate DOM tree effectively work here.
Hence, below are various ways you can organize your code, from simple to more complex:
- hello world rotating cube example is fine, 15-20 lines of code are ok as-is
- rendering context: move
scene
, camera
and renderer
into some context object you can pass around your layers. Think of it as an equivalent of document
in the browser.
- high-level "Shadow DOM": organize a tree of your own components that each handle a group of 3d objects, make them react to events - external from UI clicks etc., or from Three, like visitor pattern during rendering. You can either keep references to 3d objects on these components, or recursively pass your structure to a function to adjust scene's hierarchy. Examples of such components in your tree could be Chair, Building, Planet, Starship etc.
- data model: it might be tempting to store some data inside your components, but you should have a distinction between external data, usually a bit global, like numeberOfPlanets, timeOfDay etc., and internal data, like current rotation speed of a planet. Latter can be kept as part of your scene domain components.
- full MVC: as with any UI, model-view-controller is applicable here. E.g. you can follow this intro into three.js MVC.
- mediators, observers and usual workflows. See, e.g. my answer here.
- ... all the way to Redux-like immutable state management system
I hope, this answer will help people do some tactical architecture around Three.js that suits their project best.