2
0

02_shapes.py 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. #!/usr/bin/env python
  2. #from panda3d.core import load_prc_file_data
  3. #load_prc_file_data('', 'bullet-enable-contact-events true')
  4. import sys
  5. from direct.showbase.ShowBase import ShowBase
  6. from direct.showbase.InputStateGlobal import inputState
  7. from panda3d.core import AmbientLight
  8. from panda3d.core import DirectionalLight
  9. from panda3d.core import LVector3
  10. from panda3d.core import LPoint3
  11. from panda3d.core import TransformState
  12. from panda3d.core import BitMask32
  13. from panda3d.bullet import BulletWorld
  14. from panda3d.bullet import BulletPlaneShape
  15. from panda3d.bullet import BulletBoxShape
  16. from panda3d.bullet import BulletRigidBodyNode
  17. from panda3d.bullet import BulletDebugNode
  18. from panda3d.bullet import BulletSphereShape
  19. from panda3d.bullet import BulletCapsuleShape
  20. from panda3d.bullet import BulletCylinderShape
  21. from panda3d.bullet import BulletConeShape
  22. from panda3d.bullet import BulletConvexHullShape
  23. from panda3d.bullet import BulletTriangleMesh
  24. from panda3d.bullet import BulletTriangleMeshShape
  25. from panda3d.bullet import BulletMultiSphereShape
  26. from panda3d.bullet import XUp
  27. from panda3d.bullet import YUp
  28. from panda3d.bullet import ZUp
  29. class Game(ShowBase):
  30. def __init__(self):
  31. ShowBase.__init__(self)
  32. base.set_background_color(0.1, 0.1, 0.8, 1)
  33. base.set_frame_rate_meter(True)
  34. base.cam.set_pos(0, -20, 4)
  35. base.cam.look_at(0, 0, 0)
  36. # Light
  37. alight = AmbientLight('ambientLight')
  38. alight.set_color((0.5, 0.5, 0.5, 1))
  39. alightNP = render.attach_new_node(alight)
  40. dlight = DirectionalLight('directionalLight')
  41. dlight.set_direction((1, 1, -1))
  42. dlight.set_color((0.7, 0.7, 0.7, 1))
  43. dlightNP = render.attach_new_node(dlight)
  44. render.clear_light()
  45. render.set_light(alightNP)
  46. render.set_light(dlightNP)
  47. # Input
  48. self.accept('escape', self.do_exit)
  49. self.accept('r', self.do_reset)
  50. self.accept('f1', base.toggle_wireframe)
  51. self.accept('f2', base.toggle_texture)
  52. self.accept('f3', self.toggle_debug)
  53. self.accept('f5', self.do_screenshot)
  54. inputState.watchWithModifiers('forward', 'w')
  55. inputState.watchWithModifiers('left', 'a')
  56. inputState.watchWithModifiers('reverse', 's')
  57. inputState.watchWithModifiers('right', 'd')
  58. inputState.watchWithModifiers('turnLeft', 'q')
  59. inputState.watchWithModifiers('turnRight', 'e')
  60. # Task
  61. taskMgr.add(self.update, 'updateWorld')
  62. # Physics
  63. self.setup()
  64. def do_exit(self):
  65. self.cleanup()
  66. sys.exit(1)
  67. def do_reset(self):
  68. self.cleanup()
  69. self.setup()
  70. def toggle_debug(self):
  71. if self.debugNP.is_hidden():
  72. self.debugNP.show()
  73. else:
  74. self.debugNP.hide()
  75. def do_screenshot(self):
  76. base.screenshot('Bullet')
  77. def process_input(self, dt):
  78. force = LVector3(0, 0, 0)
  79. torque = LVector3(0, 0, 0)
  80. if inputState.isSet('forward'): force.y = 1.0
  81. if inputState.isSet('reverse'): force.y = -1.0
  82. if inputState.isSet('left'): force.x = -1.0
  83. if inputState.isSet('right'): force.x = 1.0
  84. if inputState.isSet('turnLeft'): torque.z = 1.0
  85. if inputState.isSet('turnRight'): torque.z = -1.0
  86. force *= 30.0
  87. torque *= 10.0
  88. self.boxNP.node().set_active(True)
  89. self.boxNP.node().apply_central_force(force)
  90. self.boxNP.node().apply_torque(torque)
  91. def update(self, task):
  92. dt = globalClock.get_dt()
  93. self.process_input(dt)
  94. self.world.do_physics(dt)
  95. #pairs = [(mf.getNode0().getName(),
  96. # mf.getNode1().getName())
  97. # for mf in self.world.getManifolds() if mf.getNumManifoldPoints() > 0]
  98. #print pairs
  99. return task.cont
  100. def cleanup(self):
  101. self.world = None
  102. self.worldNP.remove_node()
  103. #def do_added(self, node1, node2):
  104. # print('added:', node1.getName(), node2.getName())
  105. #def do_destroyed(self, node1, node2):
  106. # print('destroyed:', node1.getName(), node2.getName())
  107. def setup(self):
  108. self.worldNP = render.attach_new_node('World')
  109. # World
  110. self.debugNP = self.worldNP.attach_new_node(BulletDebugNode('Debug'))
  111. self.debugNP.show()
  112. self.debugNP.node().show_wireframe(True)
  113. self.debugNP.node().show_constraints(True)
  114. self.debugNP.node().show_bounding_boxes(False)
  115. self.debugNP.node().show_normals(True)
  116. self.world = BulletWorld()
  117. self.world.set_gravity((0, 0, -9.81))
  118. self.world.set_debug_node(self.debugNP.node())
  119. # Plane (static)
  120. shape = BulletPlaneShape((0, 0, 1), 0)
  121. np = self.worldNP.attach_new_node(BulletRigidBodyNode('Ground'))
  122. np.node().add_shape(shape)
  123. np.set_pos(0, 0, -1)
  124. np.set_collide_mask(BitMask32.all_on())
  125. self.world.attach(np.node())
  126. # Box (dynamic)
  127. shape = BulletBoxShape((0.5, 0.5, 0.5))
  128. np = self.worldNP.attach_new_node(BulletRigidBodyNode('Box'))
  129. np.node().set_mass(1.0)
  130. np.node().add_shape(shape)
  131. np.set_pos(0, 0, 4)
  132. np.set_collide_mask(BitMask32.all_on())
  133. self.world.attach(np.node())
  134. self.boxNP = np # For applying force & torque
  135. #np.node().notifyCollisions(True)
  136. #self.accept('bullet-contact-added', self.do_added)
  137. #self.accept('bullet-contact-destroyed', self.do_destroyed)
  138. # Sphere (dynamic)
  139. shape = BulletSphereShape(0.6)
  140. np = self.worldNP.attach_new_node(BulletRigidBodyNode('Sphere'))
  141. np.node().set_mass(1.0)
  142. np.node().add_shape(shape)
  143. np.set_pos(-4, 0, 4)
  144. np.set_collide_mask(BitMask32.all_on())
  145. self.world.attach(np.node())
  146. # Cone (dynamic)
  147. shape = BulletConeShape(0.6, 1.2, ZUp)
  148. np = self.worldNP.attach_new_node(BulletRigidBodyNode('Cone'))
  149. np.node().set_mass(1.0)
  150. np.node().add_shape(shape)
  151. np.set_pos(4, 0, 4)
  152. np.set_collide_mask(BitMask32.all_on())
  153. self.world.attach(np.node())
  154. # Capsule (dynamic)
  155. shape = BulletCapsuleShape(0.5, 1.0, ZUp)
  156. np = self.worldNP.attach_new_node(BulletRigidBodyNode('Capsule'))
  157. np.node().set_mass(1.0)
  158. np.node().add_shape(shape)
  159. np.set_pos(0, 4, 4)
  160. np.set_collide_mask(BitMask32.all_on())
  161. self.world.attach(np.node())
  162. # Cyliner (dynamic)
  163. shape = BulletCylinderShape(0.7, 1.5, ZUp)
  164. np = self.worldNP.attach_new_node(BulletRigidBodyNode('Cylinder'))
  165. np.node().set_mass(1.0)
  166. np.node().add_shape(shape)
  167. np.set_pos(4, 4, 4)
  168. np.set_collide_mask(BitMask32.all_on())
  169. self.world.attach(np.node())
  170. # Convex (dynamic)
  171. shape = BulletConvexHullShape()
  172. shape.add_point(LPoint3(1, 1, 2))
  173. shape.add_point(LPoint3(0, 0, 0))
  174. shape.add_point(LPoint3(2, 0, 0))
  175. shape.add_point(LPoint3(0, 2, 0))
  176. shape.add_point(LPoint3(2, 2, 0))
  177. # Another way to create the convex hull shape:
  178. #shape = BulletConvexHullShape()
  179. #shape.add_array([
  180. # LPoint3(1, 1, 2),
  181. # LPoint3(0, 0, 0),
  182. # LPoint3(2, 0, 0),
  183. # LPoint3(0, 2, 0),
  184. # LPoint3(2, 2, 0),
  185. #])
  186. # Yet another way to create the convex hull shape:
  187. #geom = loader.load_model('models/box.egg')\
  188. # .find_all_matches('**/+GeomNode')\
  189. # .get_path(0)\
  190. # .node()\
  191. # .get_geom(0)
  192. #shape = BulletConvexHullShape()
  193. #shape.add_geom(geom)
  194. np = self.worldNP.attach_new_node(BulletRigidBodyNode('Convex'))
  195. np.node().set_mass(1.0)
  196. np.node().add_shape(shape)
  197. np.set_pos(-4, 4, 4)
  198. np.set_collide_mask(BitMask32.all_on())
  199. self.world.attach(np.node())
  200. # Mesh (static)
  201. p0 = LPoint3(-10, -10, 0)
  202. p1 = LPoint3(-10, 10, 0)
  203. p2 = LPoint3(10, -10, 0)
  204. p3 = LPoint3(10, 10, 0)
  205. mesh = BulletTriangleMesh()
  206. mesh.add_triangle(p0, p1, p2)
  207. mesh.add_triangle(p1, p2, p3)
  208. shape = BulletTriangleMeshShape(mesh, dynamic=False)
  209. # Another way to create the triangle mesh shape:
  210. #geom = loader.load_model('models/box.egg')\
  211. # .find_all_matches('**/+GeomNode')\
  212. # .get_path(0)\
  213. # .node()\
  214. # .get_geom(0)
  215. #mesh = BulletTriangleMesh()
  216. #mesh.add_geom(geom)
  217. #shape = BulletTriangleMeshShape(mesh, dynamic=False)
  218. np = self.worldNP.attach_new_node(BulletRigidBodyNode('Mesh'))
  219. np.node().add_shape(shape)
  220. np.set_pos(0, 0, 0.1)
  221. np.set_collide_mask(BitMask32.all_on())
  222. self.world.attach(np.node())
  223. # MultiSphere
  224. points = [LPoint3(-1, 0, 0), LPoint3(0, 0, 0), LPoint3(1, 0, 0)]
  225. radii = [.4, .8, .6]
  226. shape = BulletMultiSphereShape(points, radii)
  227. np = self.worldNP.attach_new_node(BulletRigidBodyNode('MultiSphere'))
  228. np.node().set_mass(1.0)
  229. np.node().add_shape(shape)
  230. np.set_pos(8, 0, 4)
  231. np.set_collide_mask(BitMask32.all_on())
  232. self.world.attach(np.node())
  233. game = Game()
  234. game.run()