|
|
|
Return to Panda Features in Development
by enn0x » Wed Aug 01, 2012 6:17 pm
Hovis wrote:I have spent a stupidly long time trying to figure out how to get collision events from bullet. ...
Is all of this still true?
If I'm understanding you correctly, I can turn on collision notification but I will get events published for each of your internally calculated contact points; potentially seeing many many notifications for each collision.
Getting some nice logical collision events would be super cool.
If you're busy working on other features, how can I help make this happen? I've got a project I'm currently working on and I need this functionality, faking it in my python will be far too slow.
Yes, this is still true. It has been temporarily been disabled, but it is enabled again. You might want to have a look at sample 08_Collisions (download links in the Bullet section of the manual).
I should mention that I do not compute anything myself. It is Bullet which generates the collision notifications. I just expose them to Panda3D/Python by creating an Panda3D event each time Bullet calls my callbacks.
Just out of curiousity: what would you consider "logical" events? I think the answer is tied to the game logic, and thus should not be hard coded in an underlying engine. But the engine should support being able to build logical events on top of what is provided.
-
enn0x
-
- Posts: 1278
- Joined: Wed Nov 08, 2006 1:39 am
- Location: Germany, Munich
by preusser » Thu Aug 02, 2012 2:52 am
enn0x wrote:Ok, so here is what I know: Constraints have some "location" where the two bodies are connected. This location does not have to be inside or on the surface of either of the two bodies. Depending on the type of constraint it could be a point (e.g. ball and socket), or a line (e. g. hinge or piston).
OK. I guess I made a wrong assumption that the connection point is always the position of the "base" body. Now the TransformStates given in the constructor are the transform to this connection point/line, given inside the local reference frames of each boy. Or looking at it the other way: when starting at the connection point/line they are the inverse transform to the two bodies.
Hm, you mean those are the transforms that would "move" the nodes to the connection point?
I'm not really sure why a rotation is needed.
Also there seems to be a "bug" for this constraint, the second node sometimes pans relative to itself. This is a terrible explanation, I'll try to make an example video.
-
preusser
-
- Posts: 516
- Joined: Sun Mar 27, 2011 10:07 am
by enn0x » Fri Aug 03, 2012 2:40 am
Maybe it is best to play around with the cone twist constraint yourself. Start with this setup:
- Code: Select all
# Box B shape = BulletBoxShape(Vec3(0.1, 0.1, 0.1)) bodyB = BulletRigidBodyNode('Box B') bodyNP = self.worldNP.attachNewNode(bodyB) bodyNP.node().addShape(shape) bodyNP.setPos(0, 0, 4) bodyNP.setHpr(0, 0, 0) self.world.attachRigidBody(bodyB)
# Box A shape = BulletBoxShape(Vec3(0.4, 0.2, 0.1)) bodyA = BulletRigidBodyNode('Box A') bodyNP = self.worldNP.attachNewNode(bodyA) bodyNP.node().addShape(shape) bodyNP.node().setMass(1.0) bodyNP.setPos(0, 0, 0) bodyNP.setHpr(0, 0, 0) self.world.attachRigidBody(bodyA)
self.world.doPhysics(0.2)
frameA = TransformState.makePosHpr(Point3(-2, 0, 0), Vec3(0, 0, 0)) frameB = TransformState.makePosHpr(Point3(0, 0, -1), Vec3(0, 0, 90)) cone = BulletConeTwistConstraint(bodyA, bodyB, frameA, frameB) cone.setDebugDrawSize(2.0) cone.setLimit(30, 30, 120, softness=1.0, bias=0.3, relaxation=1.0) self.world.attachConstraint(cone)
bodyB is static, e. g. the ceiling where the lamp is hanging, and it has no rotation, just an offset of +4 up. By the way: we don't need a shape on bodyB - it is just for cheap visualisation of bodyB's location/orientation.
frameB is the connection point in bodyB's reference frame. Translation is 1 down, and rotation is 90 deg on Z. The default cone opening is along the +X axis, so we need to rotate +90 around Z-axis to make it point down (we want the lamp to hang DOWN after all).
Now, we want the lamp (bodyA) offsetted from the connection point, a bit below the connection point. This is where frameA kick is. try moving it up/down. Then left/right (!!!). And try to add a rotation on frameA. If you feel comfortable try moving/rotation frameB.
-
enn0x
-
- Posts: 1278
- Joined: Wed Nov 08, 2006 1:39 am
- Location: Germany, Munich
by bytemage » Tue Aug 14, 2012 6:35 pm
enn0x wrote:Just out of curiousity: what would you consider "logical" events?
What I'm looking for is a way to process any collisions that occurred after the last doPhysics.
The bullet-contact-added method doesn't do "logic" collisions, but all possible collisions, so that's overkill.
And the contactTest(body).getContacts() wants a specific body to test against, but I've got a lot of bodies and want to process any collisions between them. Also doing lots of extra contactTest()s to recalculate the collisions looks like a huge resource drain, when a list of all collisions that happened in the last step should be easy for Bullet to store somewhere.
I think that's what he meant by "logical events". A "easy" way to get all the actual collisions that happened in the last doPhysics call.
At least that's what I'm looking for 
-
bytemage
-
- Posts: 3
- Joined: Tue Aug 14, 2012 6:18 pm
by enn0x » Wed Aug 15, 2012 4:14 pm
So your interpretation of "logical" collision is a list of all collisions which happened since the last frame? And it should be easy for Bullet (not the Bullet wrapper we provide?) to store thi slist somewhere? Hmm... this is easy. Actually it is so easy that I don't see a reason why we should do it on the Bullet wrapper level: just start with an empty list each frame, and append whatever info you need to this list for each bullet-contact-added event. At the end of the simulation step you have your "logical collision" list. It's really easy to do in Python. I doubt this is of any use to you.
Maybe I add my interpretation about what is meant with "logical collisions" by Hovis. But first we have to explain what a collision event created by Bullet is. Whenever two bodies touch each other at one point in space this is a collision. The problem is that two bodies can have multiple collision points. For example a box resting on a tringle mesh. Now, some games need to know as much information about each individual contact point, while other might just be interested in "do two bodies have at least one collision point". The second question is what I think has been meant with "logical collision". I put this term in quotation marks because I think it is a bad choice. For example such a "logical collision" does not have a location - it might be one point or several.
Again, I don't see a reason to provide such information on the Bullet wrapper level, since again it is easy to get the information by a very thin layer on top of our Bullet wrapper: just keep a dictionary in python which has tuples of bodies as keys. Now register for the bullet-contact-added/removed events and update the dictionary with each event. Easy. Another way would be to store the list of currently colliding bodies as a set on the RigidBodyNode itself (PandaNode allows to store python tags!), and update these lists with each bullet-contact-added/removed event. Again easy. Choose the way which suits YO?UR game logic best. Other games will have other requirements.
-
enn0x
-
- Posts: 1278
- Joined: Wed Nov 08, 2006 1:39 am
- Location: Germany, Munich
by bytemage » Wed Aug 15, 2012 4:38 pm
I put logic in quotation marks for the same reason. Maybe realistic would be more accurate, but it still deserves quotation marks
The technical collisions that trigger an bullet-contact-added/removed event are not actual collisions in a "realistic" way, but in a "hitboxes have contact" way. These events also get created a lot when two objects rest on each other (yeah, technically they are not quite at rest). This of course is very much correct, as these are "contact" events. But this means all of these contacts need to be checked for collisions on top of the physics engine, while the engine has to do these checks in its main loop anyway.
But I have been looking for solutions in various places and found nothing "easy". This should be addressed on the physics engine level, there is nothing that could be done on the wrapper level.
-
bytemage
-
- Posts: 3
- Joined: Tue Aug 14, 2012 6:18 pm
by enn0x » Wed Aug 15, 2012 6:44 pm
Can you be a bit more precise in what exactly should be done on the physics engine level? You say you found nothing "easy". This implies that you have found solutions to some problem.
Just for the record: Bullet uses the very same manifold points which get exposed by our wrapper, in order to compute the forces which result from the contact/interpenetration.
And what is - in your optinion - the difference between collision and contact? The bullet-contact-added events are not bounding box checks.
-
enn0x
-
- Posts: 1278
- Joined: Wed Nov 08, 2006 1:39 am
- Location: Germany, Munich
by bytemage » Thu Aug 16, 2012 1:29 pm
enn0x wrote:Just for the record: Bullet uses the very same manifold points which get exposed by our wrapper, in order to compute the forces which result from the contact/interpenetration.
The one solution already posted here and elsewhere is to go through all objects, get the contact data and recreate the collision information, but that's already done in the engine itself. Wouldn't it be better to have a log of collision data, than to go through some of the logic twice.
What I need, in the end, is a list of the collisions their 3d position and impact force data. Since this data must already exist inside the engine the easiest way to get it would be to have access to that data, not to recreate it.
-
bytemage
-
- Posts: 3
- Joined: Tue Aug 14, 2012 6:18 pm
by enn0x » Fri Aug 17, 2012 1:43 am
bytemage wrote:What I need, in the end, is a list of the collisions their 3d position and impact force data. Since this data must already exist inside the engine the easiest way to get it would be to have access to that data, not to recreate it.
You want to cycle through the list of all (persistent) manifold points each frame? No problem - get them with world.getManifolds(). This is exactly the list you are talking about. However, it is nothing "logical" or "high level". It is just a list of data structure which Bullet internally keeps and updates when new contact get detected or existing contact are broken (hence persistent manifold point, because the data structure is not created on the fly by one-shot collision detection queries).
-
enn0x
-
- Posts: 1278
- Joined: Wed Nov 08, 2006 1:39 am
- Location: Germany, Munich
by Hovis » Thu Sep 13, 2012 5:18 pm
enn0x:
Thank you for responding to me, I wish Gmail hadn't swallowed the notifications. You correctly interpreted what I meant by "logical" collisions. Your statement about not putting this game-logic oriented code in the Bullet wrapper is makes a lot of sense; I'm just afraid that managing it in python will be very slow. I was thinking that because the Bullet wrapper is already an intrinsic part of the engine, it could be used to generate these game logic events more efficiently. I'm afraid of the performance hit I might take while trying to manage big dicts or "touching" sets in python. Does that make sense?
Caveat: I don't know anything about python tagging, I'll be looking into that.
-
Hovis
-
- Posts: 5
- Joined: Mon Jul 23, 2012 10:00 am
by Gatou » Fri Sep 14, 2012 8:47 am
Hi ennox,
First thanks for the amazing bullet integration.
I have some questions (sorry for my bad english):
1) RESOLVED
2) When I change the scale of a RigidBodyNode, with the debug mode I can see that the shape is ok but the collisions are not good at all. Maybe it's a problem with the internal setLocalScale method?
3) I wonder if the default characterController will be updated or if we have to use the new characterController made by coppertop?
-
Gatou
-
- Posts: 19
- Joined: Fri Oct 14, 2011 12:14 pm
- Location: France
by enn0x » Mon Sep 17, 2012 6:52 am
Hovis wrote:enn0x:
Thank you for responding to me, I wish Gmail hadn't swallowed the notifications. You correctly interpreted what I meant by "logical" collisions. Your statement about not putting this game-logic oriented code in the Bullet wrapper is makes a lot of sense; I'm just afraid that managing it in python will be very slow. I was thinking that because the Bullet wrapper is already an intrinsic part of the engine, it could be used to generate these game logic events more efficiently. I'm afraid of the performance hit I might take while trying to manage big dicts or "touching" sets in python. Does that make sense?
Caveat: I don't know anything about python tagging, I'll be looking into that.
Well, it's not that intrinsic. Bullet is still (an will stay so) an add-on module for Panda3D, and Panda3D can be used and compiled without Bullet support. Otherwise it would be in panda3d.core, and not in panda3d.bullet.
Anyway, I agree that it might be faster if such bookkeeping is done in C++. However, the posts here in this thread and a few others did show that everybody seems to have a different opinion about what "logical" events should be.
My suggestion is to let users do their own implementations/bookeeping in Python, and once we have a couple of usable implementations sit back and analyze them, in oder to find out what the common sematic is. Then implement this is C++.
-
enn0x
-
- Posts: 1278
- Joined: Wed Nov 08, 2006 1:39 am
- Location: Germany, Munich
by enn0x » Mon Sep 17, 2012 6:58 am
Gatou wrote:2) When I change the scale of a RigidBodyNode, with the debug mode I can see that the shape is ok but the collisions are not good at all. Maybe it's a problem with the internal setLocalScale method?
Maybe. The (user-friendly) synchronisation between Panda3D scene grahp and Bullet is not the best idea I ever had - it eats much performance and still seems to have errors. I would need a simple script to reproduce this and find out what is going wrong. Can you provide one? Gatou wrote:3) I wonder if the default characterController will be updated or if we have to use the new characterController made by coppertop?
The controller by Coppertop is certainly the better choice, because it is functional. Sooner or later we will try to port it from Python to C++.
-
enn0x
-
- Posts: 1278
- Joined: Wed Nov 08, 2006 1:39 am
- Location: Germany, Munich
by Gatou » Mon Sep 17, 2012 8:07 am
I notice that there are no problems with scaled box shape, but collision problems occur when I scaled a capsule shape.
I don't check every kind of shape but the simple following example show you a falling capsule shape scaled :
- Code: Select all
import direct.directbase.DirectStart from panda3d.core import * from panda3d.bullet import * base.cam.setPos(0, -30, 0) #base.cam.lookAt(0, 0, 5) # World world = BulletWorld() world.setGravity(Vec3(0, 0, -9.81)) debugNode = BulletDebugNode('Debug') debugNode.showWireframe(True) debugNode.showConstraints(True) debugNode.showBoundingBoxes(False) debugNode.showNormals(False) debugNP = render.attachNewNode(debugNode) debugNP.show() world.setDebugNode(debugNP.node())
# Plane shape = BulletPlaneShape(Vec3(0, 0, 1), 1) node = BulletRigidBodyNode('Ground') node.addShape(shape) np = render.attachNewNode(node) np.setPos(0, 0, -2) world.attachRigidBody(node) # Boxes model = loader.loadModel('models/box.egg') model.setPos(-0.5, -0.5, -0.5) model.flattenLight() #shape = BulletBoxShape(Vec3(0.5, 0.5, 0.5)) shape = BulletCapsuleShape(0.5, 1, ZUp) node = BulletRigidBodyNode('Box') node.setMass(1.0) node.addShape(shape) np = render.attachNewNode(node) world.attachRigidBody(node) model.copyTo(np) np.setPos(0, 0, 10) np.setScale(3)
def update(task): world.doPhysics(globalClock.getDt()) return task.cont taskMgr.add(update, 'update') run()
-
Gatou
-
- Posts: 19
- Joined: Fri Oct 14, 2011 12:14 pm
- Location: France
by Hovis » Mon Sep 17, 2012 12:08 pm
enn0x: I think your plan to wait for the cream to rise to the top is a good one. I'll do my best to provide the cream.
A totally different question:
How do I apply a torque in a local reference frame?
Specifically: I'm trying to model a spaceship with one main forward-driving thruster, and also counter-balanced thrusters that JUST rotate the ship without adding any translational velocity. Expected behavior: Given that the ship is rolled 90deg about the Y axis (so that the ship's -X axis corresponds with the world's +Z axis), when the pilot pulls back on the stick to pitch up, then the thrusters will actually apply a torque around the world's Z axis (ship's X). (I'm not describing the direction of the torque vector, but the direction I expect the nose of the ship to go.)
I've looked at BulletRigidBodyNode.applyTorque(), and it only accepts a Vec3 in the world reference frame. I looked into the Bullet API itself, and it does the exact same thing.
How would you feel about modifying BRBN.applyTorque() to take an optional first position NodePath parameter that would be used for the reference frame? This is a standard Panda-y way of specifying frames of references for lots of other operations. (See NP.setHpr at http://www.panda3d.org/reference/1.8.0/ ... 2e9f1a6577)
Alternatively, can you give me some pointers on doing the math myself? I can't figure out how to make it work.  I found NP.getNetTransform(), but I'm just not sure how to use the returned TransformState to calculate my translated torque vector. I never got a chance to take a Linear Algebra course. 
-
Hovis
-
- Posts: 5
- Joined: Mon Jul 23, 2012 10:00 am
by enn0x » Mon Sep 17, 2012 3:56 pm
Gatou wrote:I notice that there are no problems with scaled box shape, but collision problems occur when I scaled a capsule shape. I don't check every kind of shape but the simple following example show you a falling capsule shape scaled : ...
Hmm... I didn't notice anything weired. I get a capsule which is properly scale (tried scales 1.0, 2.0 and 3.0) and positioned. The capsule is stopped at exactly the right position by the ground plane.
http://enn0x.p3dp.com/hovis.jpg
Do you get different results?
-
enn0x
-
- Posts: 1278
- Joined: Wed Nov 08, 2006 1:39 am
- Location: Germany, Munich
by enn0x » Mon Sep 17, 2012 4:21 pm
Hovis wrote:A totally different question: How do I apply a torque in a local reference frame? Specifically: I'm trying to model a spaceship with one main forward-driving thruster, and also counter-balanced thrusters that JUST rotate the ship without adding any translational velocity. Expected behavior: Given that the ship is rolled 90deg about the Y axis (so that the ship's -X axis corresponds with the world's +Z axis), when the pilot pulls back on the stick to pitch up, then the thrusters will actually apply a torque around the world's Z axis (ship's X). (I'm not describing the direction of the torque vector, but the direction I expect the nose of the ship to go.) I've looked at BulletRigidBodyNode.applyTorque(), and it only accepts a Vec3 in the world reference frame. I looked into the Bullet API itself, and it does the exact same thing. :| How would you feel about modifying BRBN.applyTorque() to take an optional first position NodePath parameter that would be used for the reference frame? This is a standard Panda-y way of specifying frames of references for lots of other operations. (See NP.setHpr at http://www.panda3d.org/reference/1.8.0/ ... 2e9f1a6577) Alternatively, can you give me some pointers on doing the math myself? I can't figure out how to make it work. :oops: I found NP.getNetTransform(), but I'm just not sure how to use the returned TransformState to calculate my translated torque vector. I never got a chance to take a Linear Algebra course. :(
Panda3D provides already all the math you need. In this case it is NodePath.getRelativeVector/Point.
Assuming that np is your rigid body node (of course this works with any PandaNode, not only BulletRigidBodyNodes)
- Code: Select all
v = Vec3(1, 0, 0) # local coordinates (reference frame: np): v = render.getRelativeVector(np, v) # global coordinates (reference frame: render)
http://www.panda3d.org/reference/devel/ ... ca851bc610
Convenience methods, like e. g. setHpr(other, hpr) which you mentioned, are usually found only in high-level facades. NodePath is such a facade. The underlying object (here: PandaNode) doesn't even have setPos or setHpr. It just has the generic setTransform(TransformState ts) method. All of the NodePath.setHpr etc. methods just call the PandaNode.setTransform method.
-
enn0x
-
- Posts: 1278
- Joined: Wed Nov 08, 2006 1:39 am
- Location: Germany, Munich
by Gatou » Tue Sep 18, 2012 12:06 pm
enn0x wrote:Hmm... I didn't notice anything weired. I get a capsule which is properly scale (tried scales 1.0, 2.0 and 3.0) and positioned. The capsule is stopped at exactly the right position by the ground plane. http://enn0x.p3dp.com/hovis.jpgDo you get different results?
That's really strange, you can see different results on this pic:
http://imageshack.us/photo/my-images/507/bulletl.png
Scale > 1: Capsule stop above the ground
Scale < 1: Capsule stop below the ground
My OS is Win7.
-
Gatou
-
- Posts: 19
- Joined: Fri Oct 14, 2011 12:14 pm
- Location: France
by enn0x » Tue Sep 18, 2012 3:13 pm
This is strange. I'm on Win7 too, but I use a self-compiled Panda3D SDK. My first guess would be that you have a version of the Panda3D SDK which is compiled against an old version of the Bullet lib, since there have been changes in Bullet concerning the collision margin, and it seems to be a problem of margin and not scale. However, if I remember right then rdb confirmed that all build machines use Bullet-2.80-rev2531 now. Have you tried a recent buildbot version of Panda3D SDK?
-
enn0x
-
- Posts: 1278
- Joined: Wed Nov 08, 2006 1:39 am
- Location: Germany, Munich
by croxis » Tue Sep 18, 2012 5:56 pm
I'm having an issue with Bullet that I posted here, but I am not sure if this is a python nuance I don't know about or a Bullet one, so I am cross posting 
David - Proud to be saving the world sense 1984
-
croxis
-
- Posts: 411
- Joined: Thu Feb 12, 2009 4:13 pm
- Location: Portland, OR
-
by Gatou » Fri Sep 21, 2012 10:17 am
enn0x wrote:This is strange. I'm on Win7 too, but I use a self-compiled Panda3D SDK. My first guess would be that you have a version of the Panda3D SDK which is compiled against an old version of the Bullet lib, since there have been changes in Bullet concerning the collision margin, and it seems to be a problem of margin and not scale. However, if I remember right then rdb confirmed that all build machines use Bullet-2.80-rev2531 now. Have you tried a recent buildbot version of Panda3D SDK?
I download the last buildbot (1.9.0) but I have always the margin problem. That's really strange and I guess it will be hard to fix if you can't reproduce the issue.
-
Gatou
-
- Posts: 19
- Joined: Fri Oct 14, 2011 12:14 pm
- Location: France
by croxis » Fri Sep 21, 2012 2:56 pm
I am currently getting the same error as reported here on arch linux 64 bit with panda 1.8.0
I am getting this error both by both by doing nodePath.setPos() and node.setLinearVelocity(). This is set before I've done any stepping with Bullet World.
Thank you again for your help, time, and work!
David - Proud to be saving the world sense 1984
-
croxis
-
- Posts: 411
- Joined: Thu Feb 12, 2009 4:13 pm
- Location: Portland, OR
-
by enn0x » Fri Sep 21, 2012 5:49 pm
Gatou wrote:I download the last buildbot (1.9.0) but I have always the margin problem. That's really strange and I guess it will be hard to fix if you can't reproduce the issue.
I will ask rdb about the Bullet versions on the buildbot machines. Maybe we are still using 2.78.
-
enn0x
-
- Posts: 1278
- Joined: Wed Nov 08, 2006 1:39 am
- Location: Germany, Munich
by croxis » Sun Sep 30, 2012 3:15 pm
I found out something interesting on "Overflow in AABB, object removed from simulation" when using setPos on a nodepath. It only happens when a debug node is set in BulletWorld. This happens in 1.8.0 and in the most recent 1.9 builds. Let me know if you need additional information.
David - Proud to be saving the world sense 1984
-
croxis
-
- Posts: 411
- Joined: Thu Feb 12, 2009 4:13 pm
- Location: Portland, OR
-
by enn0x » Thu Oct 04, 2012 11:36 am
croxis wrote:I found out something interesting on "Overflow in AABB, object removed from simulation" when using setPos on a nodepath. It only happens when a debug node is set in BulletWorld. This happens in 1.8.0 and in the most recent 1.9 builds. Let me know if you need additional information.
Can't make any sense of this. What NodePath (the debug renderer, a rigid body, ...)? What is the NodePath transform before you call setPos, and what values do you use in setPos? What are the config setting and how is the setup for the BulletWorld?
It might be best if you try to come up with some script which reproduces your issue. Until then I assume that you simply moved a rigid body beyond the world boundaries.
-
enn0x
-
- Posts: 1278
- Joined: Wed Nov 08, 2006 1:39 am
- Location: Germany, Munich
by teedee » Fri Nov 30, 2012 11:55 pm
I think I've found a bug in the collision filtering. If there is no collision mask applied when you attach a rigid body, then it it is not possible to change the collision mask afterwards. There is no error, it just has no effect. You can see what I mean by swapping the two commented lines in the code below. Is this a bug or some sort of optimization similar to not calling setMass to make a static body?
In the example here, the boxes should fall through the plane since their group flags are specifically set not to collide. They will collide unless the order of the two lines is changed. I am using a fairly recent version of the code from CVS. Would have to investigate a bit to find out exactly when.
- Code: Select all
from panda3d.core import Point3, Vec3, BitMask32, loadPrcFileData loadPrcFileData('', 'bullet-filter-algorithm groups-mask') from panda3d.bullet import BulletWorld, BulletPlaneShape, BulletBoxShape, \ BulletRigidBodyNode, BulletDebugNode from direct.showbase.ShowBase import ShowBase
class Game(ShowBase): def __init__(self): ShowBase.__init__(self) self.cam.setPos(0, -20, 4) self.cam.lookAt(0, 0, 0) self.world_np = self.render.attachNewNode('World') self.debug_np = self.world_np.attachNewNode(BulletDebugNode('Debug')) self.debug_np.show() self.world = BulletWorld() self.world.setGravity(Vec3(0, 0, -9.81)) self.world.setDebugNode(self.debug_np.node()) self.world.setGroupCollisionFlag(0, 1, False) self.add_ground() self.add_box(Point3(1, 0, 1)) self.add_box(Point3(3, 0, 1)) self.add_box(Point3(1.25, 0, 3)) self.taskMgr.add(self.update, 'updateWorld')
def add_ground(self): shape = BulletPlaneShape(Vec3(0, 0, 1), -1) nodepath = self.world_np.attachNewNode(BulletRigidBodyNode('Ground')) nodepath.node().addShape(shape) nodepath.setPos(0, 0, -1) nodepath.setCollideMask(BitMask32.bit(0)) self.world.attach(nodepath.node())
def add_box(self, pos): shape = BulletBoxShape(Vec3(0.5, 0.5, 0.5)) nodepath = self.world_np.attachNewNode(BulletRigidBodyNode('Box-1')) nodepath.node().setMass(1.0) nodepath.node().addShape(shape) nodepath.setPos(pos) ########## HERE ########### # swap the order of these two lines for different behaviour self.world.attach(nodepath.node()) nodepath.setCollideMask(BitMask32.bit(1)) ###########################
def update(self, task): self.world.doPhysics(globalClock.getDt()) return task.cont
Game().run()
-
teedee
-
- Posts: 784
- Joined: Tue May 12, 2009 11:33 pm
- Location: Kepler-22b
-
by enn0x » Sun Dec 02, 2012 4:12 pm
This is an interesting finding, teedee. I'm pretty sure Bullet did behave different before updating to 2.80. Anyway, I do have some kind of explanation what is going on:
When adding a body to a world Bullet checks a first time if this body overlaps with other bodies. Since in your case you have an infinite plane as ground object (which has an infinite bounding box) Bullet marks the box/plane pairs for collision, if the mask has not yet been set (the initial mask is 32 bits ON). This means a persistent manifold point gets created, and it never gets dropped because the overlap in bounding boxes never ends.
So the "safe" way is to first set the mask, and then add the body to the world.
What makes me worried is that I am no longer sure that changes to the collision masks might or might not have an effect if done sometime during the simulation steps. I definitely have to dig deeper. Maybe there is a way to force a re-evaluation of the broadphase cache.
-
enn0x
-
- Posts: 1278
- Joined: Wed Nov 08, 2006 1:39 am
- Location: Germany, Munich
by teedee » Sun Dec 02, 2012 10:42 pm
What I've done as a workaround is set a zeroed "BitMask32()", and later change it as needed after attaching. This seems to work fine.
-
teedee
-
- Posts: 784
- Joined: Tue May 12, 2009 11:33 pm
- Location: Kepler-22b
-
by teedee » Mon Dec 10, 2012 11:02 pm
Just wanted to say thanks for integrating Bullet into Panda. We were using ODE since at the time the work on Bullet had not even started yet. We finally made the decision to switch to Bullet since we have been struggling with stability problems in ODE for a long time. A risky proposition with only about 2 months to go!
I found the API to be excellent and I was able to convert our physics code to Bullet in just 4 days, with the difficult part mostly being dealing with differences in constraints between ODE and Bullet. Our game is now running faster and more stable than ever.
Thanks!
-
teedee
-
- Posts: 784
- Joined: Tue May 12, 2009 11:33 pm
- Location: Kepler-22b
-
by Leonix » Mon Jan 21, 2013 10:19 am
Is there a way to get all nodes changed by the last doPhysics() call? Is it fast enough to do every frame?
I need this to synchronize world state over the network. Idea is to keep track of all nodes changed from previous network packet and send the updated values in the next packet. I can keep track of changes my own code makes, but not the Bullet. Alternative is to compare to the unmodified copy of everything that can possibly change, but this solution does not sound good at all.
Or maybe there are means to find all PandaNodes changed since the last redraw, or something. That would work, too.
-
Leonix
-
- Posts: 5
- Joined: Mon Jan 21, 2013 9:36 am
Return to Panda Features in Development
Who is online
Users browsing this forum: No registered users and 0 guests
| | |