I am having trouble getting physics to work for my game. What’s supposed to happen is after a set amount of time, a food item is supposed to “spawn” on a shelf for you to eat. The app state that does this has it’s code below:
The food objects will move to the correct spots, but they’re frozen in mid air. When I activated debug mode, their wireframes turn pink so I know they’re active, but they aren’t moving. I initialized their collision shapes like this:
Node candy = (Node) assetManager.loadModel("Models/candy.j3o");
Material candyMat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
candyMat.setTexture("ColorMap", assetManager.loadTexture("Textures/candy.png"));
candy.setMaterial(candyMat);
root.attachChild(candy);
main.getGameState().getFoods().add(candy);
candy.setLocalTranslation(-100, -100, -100);
BoxCollisionShape shape = new BoxCollisionShape(new Vector3f(.5f, .25f, .25f));
RigidBodyControl RBG = new RigidBodyControl(shape, 0);
candy.addControl(RBG);
main.getBullet().getPhysicsSpace().add(RBG);
I feel like there’s something I’m doing wrong here, can anyone help me out?
I seemed to have fixed it. Apparently setting the mass from 0 to not zero breaks things. I didn’t see this before because they were being placed to the same spot every frame. Is there a way to change objects from static to dynamic on the fly?
What exactly do you mean with “breaks”?, it throws an exception?, it has a different behavior?, or it just can’t be set back to a dynamic mode?. If so, this might be a bug (looking at the code at PhysicsRigidBody, when setMass is used, it changes the staticity calling a native code. Here, however, maybe others with more native-knowledge can help.
Is it working the other way?, set it as dynamic (mass > 0) at start and change it to static (mass = 0)?.
If this is really a bug a simple test-case would help.
(Anyway, why do you need this behavior?, can’t you just set the mass > 0 at first and disable the physics?, then enable them when needed?)
Because foods that aren’t actively in use are sent far off camera away from the scene for performance reasons. Then when they’re needed they are sent to the spawning points in the map. I want them to be static when not in use so they aren’t endlessly falling into an abyss which I don’t know what would happen if they were to fall too far but I don’t intend to find out. The enable / disable thing works perfectly!
I’m not sure, it’s late so I’m too tired to test that right now but later I can.
I wouldn’t do this. There are plenty of things that can go wrong with this approach, as I think you’re discovering. Why not create them when you want to spawn food into the scene?
I do this because loading in the models stalls the game for a brief moment as the data is being read from the hard drive. I have everything loaded in ahead of time so the game doesn’t stall like that. And the food models are placed in and out the scene so often that loading them every time would eat up memory. The method I’m currently using works well
Yes, reading them off of disk when needed will cause major hiccups unless done in a background thread. I do think that your approach of loading them once and keeping them in memory is the best approach, but I’d suggest loading them once and storing the references in the control/appstate that places them in the scenegraph. That way you can attach/unattach them from the scenegraph and (if needed) clone them. The scenegraph should be used to manage the scene - if something’s not “in the scene” but it’s still in the scenegraph it’s likely an invitation for trouble. It’s also cleaner - no need to mess with changing physics state. This problem (and likely others that you may or may not have already encountered and solved) just go away.
But won’t leaving assets used only by spatials that have been garbage collected in the asset manager’s cache run some risk that they’ll be purged from the cache and have to be fetched from disk again?
Yes, it could happen. One has to consider whether this is ok. It means that memory is so clobbered that things are being evicted from the cache… and maybe you’d rather be using that memory for something else… versus the small one-time cost of reloading it on demand from time to time.
Else, it’s easy to just keep a live field referencing it somewhere just to keep it from getting evicted. Nice thing is that the other code loading it doesn’t need to care about that “optimization”.
Either way, I hope we can agree that leaving it hanging around in the scene graph is very wasteful.
Makes sense - most would call a cache that never evicts a memory leak. That’s why I suggested he keep a reference to the loaded spatial unattached and then attach/clone as needed.
He does not need to clone it. Simply keeping the reference around will keep it from getting evicted and makes the using code independent of this possible spurious optimization.