26_softbody_aero.py 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. #!/usr/bin/env python
  2. import random
  3. import sys
  4. from direct.showbase.ShowBase import ShowBase
  5. from direct.showbase.InputStateGlobal import inputState
  6. from panda3d.core import AmbientLight
  7. from panda3d.core import DirectionalLight
  8. from panda3d.core import LVector3
  9. from panda3d.core import LPoint3
  10. from panda3d.core import TransformState
  11. from panda3d.core import BitMask32
  12. from panda3d.core import GeomNode
  13. from panda3d.core import GeomVertexFormat
  14. from panda3d.bullet import BulletWorld
  15. from panda3d.bullet import BulletHelper
  16. from panda3d.bullet import BulletPlaneShape
  17. from panda3d.bullet import BulletBoxShape
  18. from panda3d.bullet import BulletRigidBodyNode
  19. from panda3d.bullet import BulletDebugNode
  20. from panda3d.bullet import BulletTriangleMesh
  21. from panda3d.bullet import BulletTriangleMeshShape
  22. from panda3d.bullet import BulletSoftBodyNode
  23. from panda3d.bullet import BulletSoftBodyConfig
  24. class Game(ShowBase):
  25. def __init__(self):
  26. ShowBase.__init__(self)
  27. base.set_background_color(0.1, 0.1, 0.8, 1)
  28. base.set_frame_rate_meter(True)
  29. base.cam.set_pos(0, -80, 40)
  30. base.cam.look_at(0, 0, 10)
  31. # Light
  32. alight = AmbientLight('ambientLight')
  33. alight.set_color((0.5, 0.5, 0.5, 1))
  34. alightNP = render.attach_new_node(alight)
  35. dlight = DirectionalLight('directionalLight')
  36. dlight.set_direction((0, 0, -1))
  37. dlight.set_color((0.7, 0.7, 0.7, 1))
  38. dlightNP = render.attach_new_node(dlight)
  39. render.clear_light()
  40. render.set_light(alightNP)
  41. render.set_light(dlightNP)
  42. # Input
  43. self.accept('escape', self.do_exit)
  44. self.accept('r', self.do_reset)
  45. self.accept('f1', base.toggle_wireframe)
  46. self.accept('f2', base.toggle_texture)
  47. self.accept('f3', self.toggle_debug)
  48. self.accept('f5', self.do_screenshot)
  49. # Task
  50. taskMgr.add(self.update, 'updateWorld')
  51. # Physics
  52. self.setup()
  53. def do_exit(self):
  54. self.cleanup()
  55. sys.exit(1)
  56. def do_reset(self):
  57. self.cleanup()
  58. self.setup()
  59. def toggle_debug(self):
  60. if self.debugNP.is_hidden():
  61. self.debugNP.show()
  62. else:
  63. self.debugNP.hide()
  64. def do_screenshot(self):
  65. base.screenshot('Bullet')
  66. def update(self, task):
  67. dt = globalClock.get_dt()
  68. self.world.do_physics(dt, 10, 0.008)
  69. return task.cont
  70. def cleanup(self):
  71. self.world = None
  72. self.worldNP.remove_node()
  73. @staticmethod
  74. def LVector3_rand():
  75. x = 2 * random.random() - 1
  76. y = 2 * random.random() - 1
  77. z = 2 * random.random() - 1
  78. return LVector3(x, y, z)
  79. def setup(self):
  80. self.worldNP = render.attach_new_node('World')
  81. # World
  82. self.debugNP = self.worldNP.attach_new_node(BulletDebugNode('Debug'))
  83. self.debugNP.show()
  84. self.world = BulletWorld()
  85. self.world.set_gravity((0, 0, -9.81))
  86. self.world.set_debug_node(self.debugNP.node())
  87. # Ground
  88. p0 = LPoint3(-20, -20, 0)
  89. p1 = LPoint3(-20, 20, 0)
  90. p2 = LPoint3(20, -20, 0)
  91. p3 = LPoint3(20, 20, 0)
  92. mesh = BulletTriangleMesh()
  93. mesh.add_triangle(p0, p1, p2)
  94. mesh.add_triangle(p1, p2, p3)
  95. shape = BulletTriangleMeshShape(mesh, dynamic=False)
  96. np = self.worldNP.attach_new_node(BulletRigidBodyNode('Mesh'))
  97. np.node().add_shape(shape)
  98. np.set_pos(0, 0, -2)
  99. np.set_collide_mask(BitMask32.all_on())
  100. self.world.attach(np.node())
  101. # Soft body world information
  102. info = self.world.get_world_info()
  103. info.set_air_density(1.2)
  104. info.set_water_density(0)
  105. info.set_water_offset(0)
  106. info.set_water_normal((0, 0, 0))
  107. # Softbody
  108. for i in range(50):
  109. p00 = LPoint3(-2, -2, 0)
  110. p10 = LPoint3( 2, -2, 0)
  111. p01 = LPoint3(-2, 2, 0)
  112. p11 = LPoint3( 2, 2, 0)
  113. node = BulletSoftBodyNode.make_patch(
  114. info, p00, p10, p01, p11, 6, 6, 0, True)
  115. node.generate_bending_constraints(2)
  116. node.get_cfg().set_lift_coefficient(0.004)
  117. node.get_cfg().set_dynamic_friction_coefficient(0.0003)
  118. node.get_cfg().set_aero_model(
  119. BulletSoftBodyConfig.AM_vertex_two_sided)
  120. node.set_total_mass(0.1)
  121. node.add_force((0, 2, 0), 0)
  122. np = self.worldNP.attach_new_node(node)
  123. np.set_pos(self.LVector3_rand() * 10 + LVector3(0, 0, 20))
  124. np.set_hpr(self.LVector3_rand() * 16)
  125. self.world.attach(node)
  126. fmt = GeomVertexFormat.get_v3n3t2()
  127. geom = BulletHelper.make_geom_from_faces(node, fmt, True)
  128. node.link_geom(geom)
  129. nodeV = GeomNode('')
  130. nodeV.add_geom(geom)
  131. npV = np.attach_new_node(nodeV)
  132. tex = loader.load_texture('models/panda.jpg')
  133. npV.set_texture(tex)
  134. BulletHelper.make_texcoords_for_patch(geom, 6, 6)
  135. game = Game()
  136. game.run()