Hi!
I have several nodes that represent some rooms. If an object overlaps 2 rooms, its node should be a child of 2 nodes. But how can I do to make it so that this object is drawn once by JME 2 if both rooms are visible?
You should take a look at SharedNode.
If you have a Node that is used in several places, you can create several SharedNode from the original node.
It will not solve your problem with drawing the nodes twice. You might want to rethink your approach and only add a Node once, besides can you add the same node twice or will the attach child call remove the node from its parent before adding it to a new Node?
I suggest you make something like a Portal Object, given at creation x nodes.
Now it checks i updateGeometricbla all moveable objects nearby, and reattaches them to the node next to it if needed.
those replies don't seen to fit on my understanding of his problem…
as i understood of the problem, one solution would be to make a new Node class that overrides the method Render, this would have a big IF right before everything like:
if(haveRenderedAlready()) return;
Good Luck!
Empire Phoenix said:
I suggest you make something like a Portal Object, given at creation x nodes.
Now it checks i updateGeometricbla all moveable objects nearby, and reattaches them to the node next to it if needed.
It is a plausible approach. I already have a Portal class to link one cell to another one.
Rasp said:
You should take a look at SharedNode.
If you have a Node that is used in several places, you can create several SharedNode from the original node.
It will not solve your problem with drawing the nodes twice. You might want to rethink your approach and only add a Node once, besides can you add the same node twice or will the attach child call remove the node from its parent before adding it to a new Node?
The problem is that an object can overlap several rooms, I have not found any other solution.
Guedez said:
those replies don't seen to fit on my understanding of his problem..
as i understood of the problem, one solution would be to make a new Node class that overrides the method Render, this would have a big IF right before everything like:this would interrupt the render method for the 2th, 3th, 4th tries to render, so you can have a Node attached to two Nodes and it will only be rendered once, THIS HAVE NOT BEEN TESTED! And i bet that it will cause some graphical glitches ;D
if(haveRenderedAlready()) return;
Good Luck!
It seems a bit naive but why not? I could add an internal flag to know whether a node has already been drawn and reset it later.
Edit.: I think that I will have to modify the Cell class so that its children will behave like the existing portals, my portals can have several parents and I have to treat the abstract data type of JME as a graph rather than a tree to mark already visited nodes to avoid drawing them several times. In the future, it would be interesting to adapt the structure of JME because trees are often too limited in my situation.
This is the solution I have implemented (Guedez's approach):
@Override
public void draw(Renderer r){
if(children != null)
{Spatial child;
List<Spatial> markedChildren=new ArrayList<Spatial>();
for(int i=0,cSize=children.size();i<cSize;i++)
{child=children.get(i);
if(child!=null&&!markedChildren.contains(child))
{markedChildren.add(child);
child.onDraw(r);
}
}
}
}
The method draw(Renderer r) of the class Network is overriden so that it cannot try to display several times the same node. All the children of the instances of the class Network are instances of the class Cell and such an instance represents a room.
I'm not sure it is enough. Using Rasp's suggestion with the solution above might work.
I have found another solution but it is more complicated:
@Override
public void draw(Renderer r){
if(children!=null)
{Cell child;
List<Spatial> cellChildren;
List<Spatial> markedChildren=new ArrayList<Spatial>();
List<Spatial> hiddenChildren=new ArrayList<Spatial>();
Node target;
for(int i=0,cSize=children.size();i<cSize;i++)
{child=(Cell)children.get(i);
if(child!=null&&child.getLocalCullHint().equals(CullHint.Never))
{cellChildren=child.getChildren();
if(cellChildren!=null)
{for(Spatial cellChild:cellChildren)
if(cellChild instanceof ReminderSharedNode)
{//several shared nodes may have the same target
target=((ReminderSharedNode)cellChild).getTarget();
if(markedChildren.contains(target))
{hiddenChildren.add(cellChild);
//hide the already drawn object
cellChild.setCullHint(CullHint.Always);
}
else
//mark this object to avoid further drawing
markedChildren.add(target);
}
}
child.onDraw(r);
if(cellChildren!=null)
{//show again hidden children
for(Spatial hiddenChild:hiddenChildren)
hiddenChild.setCullHint(CullHint.Inherit);
hiddenChildren.clear();
}
}
}
}
}
The more I use my cells-and-portals system, the more I realize how complicated it is to adapt this engine to work with this. The solution above is far from optimal as I should only check if an object is visible in several nodes by using the portals to watch only the neighbors cells, not all cells...