basic.py 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. #!/usr/bin/env python
  2. from panda3d.core import *
  3. import sys
  4. import os
  5. from direct.showbase.ShowBase import ShowBase
  6. from direct.interval.IntervalGlobal import *
  7. from direct.gui.DirectGui import OnscreenText
  8. from direct.showbase.DirectObject import DirectObject
  9. from direct.actor import Actor
  10. from random import *
  11. # Function to put instructions on the screen.
  12. def addInstructions(pos, msg):
  13. return OnscreenText(text=msg, style=1, fg=(1, 1, 1, 1), scale=.05,
  14. shadow=(0, 0, 0, 1), parent=base.a2dTopLeft,
  15. pos=(0.08, -pos - 0.04), align=TextNode.ALeft)
  16. # Function to put title on the screen.
  17. def addTitle(text):
  18. return OnscreenText(text=text, style=1, fg=(1, 1, 1, 1), scale=.07,
  19. parent=base.a2dBottomRight, align=TextNode.ARight,
  20. pos=(-0.1, 0.09), shadow=(0, 0, 0, 1))
  21. class World(DirectObject):
  22. def __init__(self):
  23. # Preliminary capabilities check.
  24. if not base.win.getGsg().getSupportsBasicShaders():
  25. self.t = addTitle(
  26. "Shadow Demo: Video driver reports that shaders are not supported.")
  27. return
  28. if not base.win.getGsg().getSupportsDepthTexture():
  29. self.t = addTitle(
  30. "Shadow Demo: Video driver reports that depth textures are not supported.")
  31. return
  32. self.inst_p = addInstructions(0.06, 'P : stop/start the Panda Rotation')
  33. self.inst_w = addInstructions(0.12, 'W : stop/start the Walk Cycle')
  34. self.inst_t = addInstructions(0.18, 'T : stop/start the Teapot')
  35. self.inst_l = addInstructions(0.24, 'L : move light source far or close')
  36. self.inst_v = addInstructions(0.30, 'V : View the Depth-Texture results')
  37. self.inst_u = addInstructions(0.36, 'U : toggle updating the shadow map')
  38. self.inst_x = addInstructions(0.42, 'Left/Right Arrow : switch camera angles')
  39. base.setBackgroundColor(0, 0, 0.2, 1)
  40. base.camLens.setNearFar(1.0, 10000)
  41. base.camLens.setFov(75)
  42. base.disableMouse()
  43. # Load the scene.
  44. floorTex = loader.loadTexture('maps/envir-ground.jpg')
  45. cm = CardMaker('')
  46. cm.setFrame(-2, 2, -2, 2)
  47. floor = render.attachNewNode(PandaNode("floor"))
  48. for y in range(12):
  49. for x in range(12):
  50. nn = floor.attachNewNode(cm.generate())
  51. nn.setP(-90)
  52. nn.setPos((x - 6) * 4, (y - 6) * 4, 0)
  53. floor.setTexture(floorTex)
  54. floor.flattenStrong()
  55. self.pandaAxis = render.attachNewNode('panda axis')
  56. self.pandaModel = Actor.Actor('panda-model', {'walk': 'panda-walk4'})
  57. self.pandaModel.reparentTo(self.pandaAxis)
  58. self.pandaModel.setPos(9, 0, 0)
  59. self.pandaModel.setScale(0.01)
  60. self.pandaWalk = self.pandaModel.actorInterval('walk', playRate=1.8)
  61. self.pandaWalk.loop()
  62. self.pandaMovement = self.pandaAxis.hprInterval(
  63. 20.0, LPoint3(-360, 0, 0), startHpr=LPoint3(0, 0, 0))
  64. self.pandaMovement.loop()
  65. self.teapot = loader.loadModel('teapot')
  66. self.teapot.reparentTo(render)
  67. self.teapot.setPos(0, -20, 10)
  68. self.teapotMovement = self.teapot.hprInterval(50, LPoint3(0, 360, 360))
  69. self.teapotMovement.loop()
  70. self.accept('escape', sys.exit)
  71. self.accept("arrow_left", self.incrementCameraPosition, [-1])
  72. self.accept("arrow_right", self.incrementCameraPosition, [1])
  73. self.accept("p", self.toggleInterval, [self.pandaMovement])
  74. self.accept("t", self.toggleInterval, [self.teapotMovement])
  75. self.accept("w", self.toggleInterval, [self.pandaWalk])
  76. self.accept("v", base.bufferViewer.toggleEnable)
  77. self.accept("u", self.toggleUpdateShadowMap)
  78. self.accept("l", self.incrementLightPosition, [1])
  79. self.accept("o", base.oobe)
  80. self.light = render.attachNewNode(Spotlight("Spot"))
  81. self.light.node().setScene(render)
  82. self.light.node().setShadowCaster(True)
  83. self.light.node().showFrustum()
  84. self.light.node().getLens().setFov(40)
  85. self.light.node().getLens().setNearFar(10, 100)
  86. render.setLight(self.light)
  87. self.alight = render.attachNewNode(AmbientLight("Ambient"))
  88. self.alight.node().setColor(LVector4(0.2, 0.2, 0.2, 1))
  89. render.setLight(self.alight)
  90. # Important! Enable the shader generator.
  91. render.setShaderAuto()
  92. # default values
  93. self.cameraSelection = 0
  94. self.lightSelection = 0
  95. self.incrementCameraPosition(0)
  96. self.incrementLightPosition(0)
  97. def toggleInterval(self, ival):
  98. if ival.isPlaying():
  99. ival.pause()
  100. else:
  101. ival.resume()
  102. def toggleUpdateShadowMap(self):
  103. buffer = self.light.node().getShadowBuffer(base.win.gsg)
  104. buffer.active = not buffer.active
  105. def incrementCameraPosition(self, n):
  106. self.cameraSelection = (self.cameraSelection + n) % 6
  107. if (self.cameraSelection == 0):
  108. base.cam.reparentTo(render)
  109. base.cam.setPos(30, -45, 26)
  110. base.cam.lookAt(0, 0, 0)
  111. self.light.node().hideFrustum()
  112. if (self.cameraSelection == 1):
  113. base.cam.reparentTo(self.pandaModel)
  114. base.cam.setPos(7, -3, 9)
  115. base.cam.lookAt(0, 0, 0)
  116. self.light.node().hideFrustum()
  117. if (self.cameraSelection == 2):
  118. base.cam.reparentTo(self.pandaModel)
  119. base.cam.setPos(-7, -3, 9)
  120. base.cam.lookAt(0, 0, 0)
  121. self.light.node().hideFrustum()
  122. if (self.cameraSelection == 3):
  123. base.cam.reparentTo(render)
  124. base.cam.setPos(7, -23, 12)
  125. base.cam.lookAt(self.teapot)
  126. self.light.node().hideFrustum()
  127. if (self.cameraSelection == 4):
  128. base.cam.reparentTo(render)
  129. base.cam.setPos(-7, -23, 12)
  130. base.cam.lookAt(self.teapot)
  131. self.light.node().hideFrustum()
  132. if (self.cameraSelection == 5):
  133. base.cam.reparentTo(render)
  134. base.cam.setPos(1000, 0, 195)
  135. base.cam.lookAt(0, 0, 0)
  136. self.light.node().showFrustum()
  137. def incrementLightPosition(self, n):
  138. self.lightSelection = (self.lightSelection + n) % 2
  139. if (self.lightSelection == 0):
  140. self.light.setPos(0, -40, 25)
  141. self.light.lookAt(0, -10, 0)
  142. self.light.node().getLens().setNearFar(10, 100)
  143. if (self.lightSelection == 1):
  144. self.light.setPos(0, -600, 200)
  145. self.light.lookAt(0, -10, 0)
  146. self.light.node().getLens().setNearFar(10, 1000)
  147. def shaderSupported(self):
  148. return base.win.getGsg().getSupportsBasicShaders() and \
  149. base.win.getGsg().getSupportsDepthTexture() and \
  150. base.win.getGsg().getSupportsShadowFilter()
  151. if __name__ == '__main__':
  152. base = ShowBase()
  153. w = World()
  154. base.run()