Adding rigidbodies to physics space "late" causes problems

Hello,



I was refactoring some code a bit and some problems occured. I was making it so I could have one AppState for each level. I then figured I could move my BulletAppState creation out of my AppStates and into simpleInitApp(), so I could have just one BulletAppState for the game, and rather deal with what rigidbodies it controls at any given time.



Second thing I did was then to move the adding of the level-specific rigidbodies to the physics space to the .setEnable() override of each AppState, and make sure I also removed them when the AppState becomes disabled, otherwise they would linger on to other levels. Previously I’d just add them right after creating the RigidBodyControl and adding it to the Spatial, which was working fine.



The result of this refactoring was that the “player” (a dynamic rolling ball) became seemingly unaffected by physics. Debugging showed that the correct rigid bodies were indeed in the physics space (in the physicsNodes collection). I then checked if the RigidBody was being moved, and indeed it was! But not Spatial itself. I also checked to verify that the Spatial indeed has the control, as well as that the RigidBodyControl has the spatial.



So then why isn’t the RigidBodyControl updating its Spatials position anymore? How could this refactor have caused this? In fact the only difference is that I add the rigidbody to the physics space when the screen becomes active, rather than during the initialization of the AppState, when the RigidBodyControl (as well as the Spatial and the CollisionShape) is created.



PS: Using one AppState for each level was probably not a great idea. They all share being in an “ingame state” and should probably rather be abstracted separately from the AppState concept. But my questions still remain…

Do you call the super method of setEnabled and any other classes you override? Note its not really best practice to override the classes to “hook into” or “extend” them. Best only do that if you want the same functionality but a bit different.

Yes, I do call the super method throughout the hierarchy. Why?



I only use setEnabled to set the proper state upon enabling the AppState, and restoring the applications state upon disabling it again. Again, I’m not at all confident that it was a good design decision, it was more provisional than anything :slight_smile: But that’s really a discussion for another topic…



I’m certain the bullet appstate isn’t being messed with anywhere else, so unless something is happening behind the curtains, I remain confused as to why the RigidBodyControl is not moving the Spatial.

@xeethrax said:
Yes, I do call the super method throughout the hierarchy. Why?

Cause not doing that could cause issues like this.. I guess you are still looking for an answer whats wrong? :)

@xeethrax said:
I only use setEnabled to set the proper state upon enabling the AppState, and restoring the applications state upon disabling it again. Again, I'm not at all confident that it was a good design decision, it was more provisional than anything :) But that's really a discussion for another topic..

I'm certain the bullet appstate isn't being messed with anywhere else, so unless something is happening behind the curtains, I remain confused as to why the RigidBodyControl is not moving the Spatial.

No idea really, not attaching it or overriding update() without calling super() would be the only things that could cause that. Or another control that overwrites the position again, like two physics controls on one object.

There are only two controls on the Spatial, the RigidBodyControl and a PhysicalChaseCamera.



As far as the AppState goes, the baseclass AbstractAppStates .setEnabled only sets the boolean enabled, and its update() does nothing. AppStateManager would handle the updating of the bulletAppState I’d assume, and except for adding the AppStates initially, I don’t touch it :slight_smile:



I guess I’ll have another stab at refactoring it, just tripping over things like this leaves me unconfident about what the best / safest approach is… Suggestions?

Without knowing your code, not really, no :slight_smile: What we wrote in the wiki I guess :wink:

Well I moved the creation of the rigidbodies to the setEnabled as well and it now again actually controls the ball. Strange that separating those calls between the Initialize and setEnabled would cause this, but there you have it.

Actually for the matter of safes approach, i would create a new PhysicSpace(appState) for each level and throw the old one out.



This way if there are bugs in the clenaing up, or some other stuff, if the player mangages to reach the exit of the level, they will be gone in the next.



Also are you 100% sure you use setEnabled in the same thread?

How can you add the creation to setEnabled :? The physics control has to exist already so that it can be enabled?? SetEnabled removes the object from the physics space, read the javadoc.

@EmpirePhoenix said:
Actually for the matter of safes approach, i would create a new PhysicSpace(appState) for each level and throw the old one out.

This way if there are bugs in the clenaing up, or some other stuff, if the player mangages to reach the exit of the level, they will be gone in the next.

Also are you 100% sure you use setEnabled in the same thread?


I'm actually doing that now. I create the rigidbodies, the shapes, the bullet appstate all in the AbstractAppState.setEnabled override. Then just throw it away again when enabled is set to false. It's probably not the optimal way of doing things, but my priority is getting things working right now.

And as for your last question, that may very well be it. I swap enabled state on appstates via the methods called through nifty, and they are most probably called in a separate thread. Almost embarassing.. :) I'm rather stressed atm though, I'll blame it on that! Good catch.

@normen said:
How can you add the creation to setEnabled :? The physics control has to exist already so that it can be enabled?? SetEnabled removes the object from the physics space, read the javadoc.


The .setEnabled-override of the AbstractAppState, as I've been trying to explain. I'm sorry if I wasn't being clear enough.

Hm nope as far as i know niftysy event stuff is in the main thread.



Actually i assume most of your problems come from extending states, I suggest to think about adding a logic level above that that handles all meta states.



(Eg a ingame level has a physicstate logic state ect, its not 1to1 compatible with the appstate approach i guess)