One node in multiple gamestates?

My current project, however ill-advised, currently has a PassManagerGameState (TestIsland.java in a GameState, basically) and a PhysicsGameState.



I created the terrain, water, skybox everything and put it in PassManagerGameState.  Then I put the terrain only into PhysicsGameState so that I can drop things onto it and watch them roll down the mountains.



Anyhow,  by adding the terrain (which is PassNode with multiple passes) to the PhysicsGameState,  the island turns into a crazy, psychadelic whirling maelstrom of color and light, instead of a nice island texture.  It looks really neat, but isn't what I'm going for.



So, problems:



1)  Adding the PassNode to both PhysicsGameState and PassManagerGameState causes it to draw funny. I only did this for the collisions, and don't really want PhysicsGameState to draw it at all.



2) Removing the call in PhysicsGameState to super.render() causes the island to stop drawing altogether.  The only code that this prevents from being executed is this:

public void render(float tpf) {

DisplaySystem.getDisplaySystem().getRenderer().draw(rootNode);

}



The island is not drawn at all.  The island still exists in the PassManagerGameState, but it isn't getting drawn for some reason. Why would it matter if PhysicsGameState draws anything and how would that effect PassManagerGameState? Shouldn't they be completely independent? They both have a reference to the same PassNode, but what's going on here? Can a PassNode tell if it has been drawn before?



Couldn't physics just update everything during its pass, and the PassManagerGameState could do the drawing if I am sure to add the objects to both states? Any advice on better ways to do this? Maybe I'll make a PassManagerPhysicsGameState :confused:



I am really hoping that the order in which I add GameStates to the GameStateManager doesn't matter.



Is there an easy way to make good copies of these objects so I'm not adding the same object to multiple gamestates? Can these be cloned somehow?



Sorry to ramble, sometimes just writing the post helps me figure out the problem, but not quite this time.


Oooooh… apparently a Node can't have more than one parent. By putting it into another GameState, I'm removing it from the other!



Any ideas on how to make this work?  Good techniques for cloning a Node?

I don't know much about the GameStates, but you could add the physics of the terrain to the PhysicsGameState and the visual of the terrain to the PassManagerGameState, couldn't you? So in PassManagerGameState terrain would be a plain Node and in PhysicsGameState it would be a StaticPhysicsNode. You could even do generateGeometry with the actual terrain attached to the physics node and then detach the visual and attach it to the plain Node in PassManagerGameState…

It seems we are not speaking about the exact same thing, yet. How do you create your physics representation of the terrain, currently? (after your question I suppose you do not generate the collision geometries)

I am just taking the terrain node from the PassManagerGameState and attaching it to the PhysicsGameState.   

Here is the method that I added to the PhysicsGameState for adding a static node. After looking at it, I assume you meant generatePhysicsGeometry rather than generateGeometry?



In this case, the node I am passing in is a PassNode.  PhysicsGameState is not equipped to handle the rendering of a PassNode. Since it resides in PassManagerGameState, it should do the rendering. I may have to merge the two. It's essentially just a call to PhysicsSpace.update(tpf*physicsSpeed) after everything has been added to the rootnode. It shouldn't be a huge deal to have that in my other game states. I may come up with a CompoundGameState so that I can keep those things separate, as I said before.



public void addStaticNode(Node nodeIn){
StaticPhysicsNode staticNode = getPhysicsSpace().createStaticNode();

// attach the node to the root node to have it updated each frame
rootNode.attachChild(staticNode);

//attach the incoming node
staticNode.attachChild(nodeIn);

// now we let jME Physics 2 generate the collision geometry for our box
staticNode.generatePhysicsGeometry();
}


Are you saying I can do generatePhysicsGeometry then take out the node that I used to generate it? That would work…

Thanks Irrisor, I got it to work by changing to this:


public void addStaticNode(Node nodeIn){
StaticPhysicsNode staticNode = getPhysicsSpace().createStaticNode();

// attach the node to the root node to have it updated each frame
rootNode.attachChild(staticNode);

//Remember this node's parent info so we can put it back when we're done
// we just want to generate physics geometry from it
Node tempParent = nodeIn.getParent();
int tempIndex = tempParent.getChildIndex(nodeIn);

//attach the incoming node
staticNode.attachChild(nodeIn);


// now we let jME Physics 2 generate the collision geometry for our box
staticNode.generatePhysicsGeometry();

// put child back
tempParent.attachChildAt(nodeIn, tempIndex);
}


I hope that doesn't have any unexpected sideffects.

Unless you move the terrain this should be fine (and was what I meant, yes). For dynamic physics nodes which need passes you need to come up with that combined state, I guess.