[Closed] Multiple parents in scenegraph



In the three.js scene graph nodes can only have one parent. A single node cannot appear multiple times in the graph. What would need to change in the three.js code organization and scene graph to make it possible to reference a single node from multiple locations ? This would avoid cloning or using low level concepts like instanced geometries and attributes. How would one start to address such an idea ?


Which transformation would you apply to the node? What are you trying to achieve your question makes little sense?


I don’t understand this argumentation. Right now, it’s already possible in three.js to share geometries and materials across entities like meshes. Basically, this would allow the engine to implement auto-instancing. There is no need for multiple parents in the scene graph.


Thanks for responding. Other scene graphs such as VRML allow multiple parents. They are used to avoid duplication and to encourage sharing of resources but shift responsibility to the engine/player/browser. Please be careful in this forum, aimed at open and friendly discussion.


You are right, the essentials can already be shared. I suppose the idea is to think about sharing geometries/materials or any other entity (object3d’s themselves, cameras …) more generally and perhaps on a somewhat higher level. Let’s call it a speculative question about a potential fork or new layer since there is no need for three.js to change in such a way.


Are you entirely sure about this? Is it still a scene graph if you do connections like this? A few things to consider:

  1. Keep in mind that VRML is from the mid 90s things could have possibly changed since then.
  2. Engines and libraries have their own opinions. Three could have one, VRML another babylon.js yet another. It would be totally reasonable if you found a screne graph engine that could have multiple parents and use that instead.

To build arbitrary data structures and graphs, javascript actually imposes very few limitations.

A simple approach:

const parentA = new Object3D()

const parentB = new Object3D()

//three uses .children you can make .myChildren
parentA.myChildren = []
parentB.myChildren = []

const child = new THREE.Object3D()

//three uses .parent you can make an array .myParents
child.myParents = []

Just add and remove nodes where and when they should be and you’re golden.


This is still extremely confusing. You can always share geometries and materials. How would you share nodes?

Lets say we have a RED CUBE and it’s in the bathroom. You make another RED CUBE and put it in the kitchen. They share the material (RED) they share the geometry (CUBE) but what else do you want to share, and why?


OpenSceneGraph also allows multiple parents. It is an established concept.

Your suggestion to construct and then manage an ad-hoc graph structure on top or perhaps in parallel of the three scene graph may be how experienced three.js experts would approach such re-use. Perhaps there would be a way to integrate a .parents array property into three.js so it is available generally and does not have to be rediscovered.

The idea is to have a single RED CUBE but use it multiple times, once in each room. The advantage is that is more concise and better represents the intent. Instead of making a new object and assign it a shared material and geometry, you share the object itself. It is up to the engine how to take advantage of this sharing for an optimal rendering process.


To use THREE.InstancedBufferGeometry() is not the rocket science.


Yes, and there are other, dedicated and efficient ways to re-use materials/geometries. But the question was given allowing multiple parents as a requirement, how to best approach a solution provided the existing three scene graph machinery.
To put it another way, the VRML loader (probably) currently clones a child if it has multiple parents in VRML. This works but decouples the children. So if subsequently one child gets a different material or animation, its clone does not. What could be a good solution ? Maintain a list and sync clones ?


Well… So far, all the discussion (exclusively from my point of view) looks like this:

You: - Guys, I’ve seen that VRML can have multiple parents for one node, let’s do the same in Three.js!
People: - We’re fine with what we have now. Why do you want it in the framework?
You: - Because it’s cool and has some profits!
People: - But why and what for?
You: - OpenSceneGraph has it, so we can have it too.

In the time of the USSR, when I was a pioneer kid, there was a rule in our class room:
Interfere, if you disagree. Offer something, when you interfere. Then do what you offer.

Just out of curiousity, have you tried to understand how and why the framework works? Did you conduct any research of how that multi-parenting could be done in the framework? Or do you have any working examples of the concept with Three.js?


Wow, tough crowd. Ok. I was hoping for constructive feedback and help on exactly the questions you raise.
Let me apologize if I came across as interfering but I thought multi-parenting may be an appropriate topic for exploratory discussion in the discussion section. I will mark this thread as closed since it does not go anywhere, at least not where it could be productive.


How would you solve this?

const myRedCube = new Mesh( sharedCube, redMaterial)


myRedCube.position.copy( CENTER_OF_KITCHEN )


//myRedCube.position.copy( CORNER_OF_BATHROOM ) // <-- ????


If you help us understand your problem or get on the same page as us on what is the problem id consider this thread productive :slight_smile:


Something like this In pseudo code:

const myRedCube = new Mesh( sharedCube, redMaterial )

myRedCubeGroupWrapper.position.copy( OFFSET_TO_CENTER_OF_KITCHEN )

myRedCubeGroupWrapper.add( myRedCube_reference )


myRedCubeGroupWrapper2.position.copy( OFFSET_TO_CENTER_OF_BATHROOM )

myRedCubeGroupWrapper2.add( myRedCube_reference )


I think Group is now preferred over Object3d.
The _reference signifies that myRedCube could have multiple parents, eg. is only referred to by the parent.


Why does the red cube then need to be a mesh? Why can’t you have your wrapper wrap geometry


I am not sure I understand the question. The wrapper is necessary since different offsets are needed. But the cube does not need to be a mesh. It could be another group, say a table.


Just a note that https://github.com/mrdoob/three.js/pull/11134 seems relevant.


I see now, the table could hold chairs and each in turn have a geometry. I’m not sure how to best solve this. You could edit one “scene” consisting of table->chairs and have it update in both rooms, the layout, not so much the geom/materials.


Some discussions on traversing: