def test_computeAABBS_StaticPlane(self): """ Static planes are permissible collision shapes for a body if that is indeed the only collision shape for that body. Conversely, it is not allowed for a body to have multiple collision shapes if one of them is a StaticPlane. """ computeAABBs = azrael.leo_api.computeAABBs # One or more spheres are permissible. cs = {'cssphere': getCSSphere()} assert computeAABBs(cs).ok # A single plane is permissible. cs = {'csplane': getCSPlane()} assert computeAABBs(cs).ok # A plane in conjunction with any other object is not allowed... cs = {'csplane': getCSPlane(), 'cssphere': getCSSphere()} assert not computeAABBs(cs).ok # not even with another plane. cs = {'csplane': getCSPlane(), 'cssphere': getCSSphere()} assert not computeAABBs(cs).ok # The position and rotation of a plane is defined via the normal # vector and its offset. The position/rotation fields in the # CollShapeMeta structure are thus redundant and *must* be set to # defaults to avoid unintended side effects. cs = {'csplane': getCSPlane(pos=(0, 1, 2))} assert not computeAABBs(cs).ok cs = {'csplane': getCSPlane(rot=(1, 0, 0, 0))} assert not computeAABBs(cs).ok
def test_cshape_with_offset(self): """ Same as above except that the collision shape has a different position relative to the rigid body. This test is to establish that the relative positions of the collision shapes are correctly passed to Bullet and taken into account in a simulation. Setup: place a box above a plane and verify that after a long time the box will have come to rest on the infinitely large plane. """ aid_1, aid_2 = '1', '2' # Instantiate Bullet engine and activate gravity. sim = azrael.bullet_api.PyBulletDynamicsWorld(1) sim.setGravity((0, 0, -10)) # Create a box above a static plane. The ground plane is at z=-1. The # rigid body for the box is initially at z = 5, however, the collision # shape for that rigid body is actually z = 5 + ofs_z. ofs_z = 10 cs_plane = getCSPlane(normal=(0, 0, 1), ofs=-1) cs_box = getCSBox(pos=(0, 0, ofs_z)) b_plane = getRigidBody(imass=0, cshapes={'csplane': cs_plane}) b_box = getRigidBody(position=(0, 0, 5), cshapes={'csbox': cs_box}) assert b_box is not None assert b_plane is not None # Add the objects to the simulation and verify their positions. sim.setRigidBodyData(aid_1, b_plane) sim.setRigidBodyData(aid_2, b_box) ret_plane = sim.getRigidBodyData(aid_1) ret_box = sim.getRigidBodyData(aid_2) assert (ret_plane.ok is True) and (ret_box.ok is True) assert ret_plane.data.position[2] == 0 assert ret_box.data.position[2] == 5 # Step the simulation often enough for the box to fall down and come to # rest on the surface. dt, maxsteps = 1.0, 60 for ii in range(10): sim.compute([aid_1, aid_2], dt, maxsteps) # Verify that the plane has not moved (because it is static). If the # position of the box' collision shape were at the origin of the body, # then the body's position should be approximately zero. However, since # the collisions shape is at 'ofs_z' higher, the final resting position # of the body must be 'ofs_z' lower, ie rb_position + ofs_z must now be # approximately zero. ret_plane = sim.getRigidBodyData(aid_1) ret_box = sim.getRigidBodyData(aid_2) assert (ret_plane.ok is True) and (ret_box.ok is True) assert ret_plane.data.position[2] == 0 assert abs(ret_box.data.position[2] + ofs_z) < 1E-3
def test_box_on_plane(self): """ Create a simulation with gravity. Place a box above a plane and verify that after a long time the box will have come to rest on the infinitely large plane. """ aid_1, aid_2 = '1', '2' # Instantiate Bullet engine and activate gravity. sim = azrael.bullet_api.PyBulletDynamicsWorld(1) sim.setGravity((0, 0, -10)) # Create a box above a static plane. The ground plane is at z=-1. cs_plane = getCSPlane(normal=(0, 0, 1), ofs=-1) cs_box = getCSBox() b_plane = getRigidBody(imass=0, cshapes={'csplane': cs_plane}) b_box = getRigidBody(position=(0, 0, 5), cshapes={'csbox': cs_box}) assert b_box is not None assert b_plane is not None # Add the objects to the simulation and verify their positions. sim.setRigidBodyData(aid_1, b_plane) sim.setRigidBodyData(aid_2, b_box) ret_plane = sim.getRigidBodyData(aid_1) ret_box = sim.getRigidBodyData(aid_2) assert (ret_plane.ok is True) and (ret_box.ok is True) assert ret_plane.data.position[2] == 0 assert ret_box.data.position[2] == 5 # Step the simulation often enough for the box to fall down and come to # rest on the surface. dt, maxsteps = 1.0, 60 for ii in range(10): sim.compute([aid_1, aid_2], dt, maxsteps) # Verify that the plane has not moved (because it is static) and that # the box has come to rest atop. The position of the box rigid body # must be approximately zero, because the plane is at position z=-1, # and the half length of the box is 1 Meters. ret_plane = sim.getRigidBodyData(aid_1) ret_box = sim.getRigidBodyData(aid_2) assert (ret_plane.ok is True) and (ret_box.ok is True) assert ret_plane.data.position[2] == 0 assert abs(ret_box.data.position[2]) < 1E-5