So hello, this is my first post on these forums! Anyway, my question is kind of specific… I am working on a project where the user can click on a geometry, and then that will be hovering and following the cursor until you let go of the mouse (like Amnesia kind of). This all works, and I added physics to the room, a player and the geometry.
The small box that you can pick up reacts to all forces, stays on the floor, and if you run into it, it will move. Its physics are great. However, here’s the catch. In the update I set the target.getControl(RigidBodyControl.class).setPhysicsLocation to the cursor, but when I then move the mouse to a wall, floor, or whatever, the box will simply ignore all the physics and fly straight through it, hovering in there. If I let go of it, it will react to gravity and become a normal object again. So, how would I make sure it collides with walls, etc? The walls are also all RigidBodyControls.
So you want to setPhysicsLocation but you also want the physics engine to set the location? You have to choose one, you can’t have both.
What you probably can do is to have an invisible kinematic “mouse” body that is attached to a spring joint (or some other joint), then you attach the other end of that joint to the “box” you want to move. In that way the physics engine will calculate the location of the box given the constraint of the joint.
When moving it, set a high dampening and maybee reduce gravity
calcualte the direction vector from currentposition to targetposition,
normalize();
scalie it with the hoverforce(to be determined by trail and error,w hat works fine)
apply that vector as centralForce
-> result the box will try to move always to the position of the cursor, the dampening should prevent it from occilating, and the force it can apply can be specified, to prevent strange reaction with other physic objects.
@jmaasing said:
So you want to setPhysicsLocation but you also want the physics engine to set the location? You have to choose one, you can't have both.
What you probably can do is to have an invisible kinematic “mouse” body that is attached to a spring joint (or some other joint), then you attach the other end of that joint to the “box” you want to move. In that way the physics engine will calculate the location of the box given the constraint of the joint.
So yeah, sorry for responding so long after the response, I was away on holidays, but I tried this and it doesn’t work. It still follows the mouse and everything, the joint is working, but if I move the mouse on the other side of a wall it will just go right through it. I did however use a normal HingeJoint… what was that springJoint you were talking about? I imagine that can solve the problem, or? But regardless, all I do is attach the object to the hookNode, set the hookNode physicslocation to the place of where the mouse “is” (set it to 3D by using player position and camera direction)… the joint is also added, and it just goes straight through all other physical objects! Any ideas?
Just be a bit smart about how you handle this and make special cases. I mean what do you expect the physics engine to to when you tell it “hey that object over there, I don’t care if theres a wall over here, I want it in the middle of it”.
But like Normen says, you are explicitly throwing all physics calculation away and forcibly set the object inside the wall with setPhysicsLocation. So maybe the simplest is to check if the mouse pointer is inside a wall and then just don’t set the location of the object. That might be one of those special cases.
@jmaasing said:
Sorry for confusing you about this, I forgot that the 6 DOF joint is not available in jBullet, (http://bulletphysics.org/mediawiki-1.5.8/index.php/Constraints), otherwise that might have been useful.
But like Normen says, you are explicitly throwing all physics calculation away and forcibly set the object inside the wall with setPhysicsLocation. So maybe the simplest is to check if the mouse pointer is inside a wall and then just don’t set the location of the object. That might be one of those special cases.
How would you check if it is inside a wall? I tried rootNode.collideWith(hookNode, results) where hookNode essentially is the mouse, just the thing that the joint is attached to, but that just throws an UnsupportedCollisionException… neither does it work to try to collide with the getControl() of it? I’m sorry for asking such (to you) basic questions, but this is something that is bugging me… every other aspect of my project is working great, but this keeps coming back!
OP - There are two different systems for checking collisions. rootNode.collideWith is from the Node class (Google Code Archive - Long-term storage for Google Code Project Hosting.), which uses the scene graph and does not know anything about the Bullet physics system which is the other one.
There are many different ways to do it, ghost controls, maybe ray casts, it all depends on what is easy in your specific use case. You will have to get creative, there is no ready made solution (that I know of).
Now, my ramblings about the joints is that you could probably use 6DoF and springs/motors to create a 3D version of a “mouse-joint” such as the one in dyn4j (which is 2D and has nothing to do with jME) Google Code Archive - Long-term storage for Google Code Project Hosting.
However, I suspect that is the hardest way of them all to get what you want.
OP - There are two different systems for checking collisions. rootNode.collideWith is from the Node class (Google Code Archive - Long-term storage for Google Code Project Hosting.), which uses the scene graph and does not know anything about the Bullet physics system which is the other one.
There are many different ways to do it, ghost controls, maybe ray casts, it all depends on what is easy in your specific use case. You will have to get creative, there is no ready made solution (that I know of).
Now, my ramblings about the joints is that you could probably use 6DoF and springs/motors to create a 3D version of a “mouse-joint” such as the one in dyn4j (which is 2D and has nothing to do with jME) Google Code Archive - Long-term storage for Google Code Project Hosting.
However, I suspect that is the hardest way of them all to get what you want.
Alright, the one with the ghost node actually seems to be working so far… but I ran into another problem. If I don’t move the cursor around, then after around 3 seconds or so the physics object following it (the object that you pick up) becomes unmovable and just hovers in air until it is affected by some sort of external force, at which point is zooms back to the mouse location! In debug mode it is usually purple, as it is a physics object, but then after those 3 seconds the wire changes colour from purple to blue … I’m guessing this is because the physics is turned off for objects if no forces act upon them for a specified amount of time? Is there any way to (temporarily or not) turn off this setting for specified objects or the entire app?
@SCOMS said:
Alright, the one with the ghost node actually seems to be working so far.. but I ran into another problem. If I don't move the cursor around, then after around 3 seconds or so the physics object following it (the object that you pick up) becomes unmovable and just hovers in air until it is affected by some sort of external force, at which point is zooms back to the mouse location! In debug mode it is usually purple, as it is a physics object, but then after those 3 seconds the wire changes colour from purple to blue ... I'm guessing this is because the physics is turned off for objects if no forces act upon them for a specified amount of time? Is there any way to (temporarily or not) turn off this setting for specified objects or the entire app?
Yes. Search for sleepingThreshold here: https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:advanced:physics