main.py 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. #!/usr/bin/env python
  2. # Author: Kwasi Mensah ([email protected])
  3. # Date: 8/02/2005
  4. #
  5. # This is meant to be a simple example of how to draw a cube
  6. # using Panda's new Geom Interface. Quads arent directly supported
  7. # since they get broken down to trianlges anyway.
  8. #
  9. from direct.showbase.ShowBase import ShowBase
  10. from direct.showbase.DirectObject import DirectObject
  11. from direct.gui.DirectGui import *
  12. from direct.interval.IntervalGlobal import *
  13. from panda3d.core import lookAt
  14. from panda3d.core import GeomVertexFormat, GeomVertexData
  15. from panda3d.core import Geom, GeomTriangles, GeomVertexWriter
  16. from panda3d.core import Texture, GeomNode
  17. from panda3d.core import PerspectiveLens
  18. from panda3d.core import Light, Spotlight
  19. from panda3d.core import TextNode
  20. from panda3d.core import LVector3
  21. import sys
  22. import os
  23. base = ShowBase()
  24. base.disableMouse()
  25. base.camera.setPos(0, -10, 0)
  26. title = OnscreenText(text="Panda3D: Tutorial - Making a Cube Procedurally",
  27. style=1, fg=(1, 1, 1, 1), pos=(-0.1, 0.1), scale=.07,
  28. parent=base.a2dBottomRight, align=TextNode.ARight)
  29. escapeEvent = OnscreenText(text="1: Set a Texture onto the Cube",
  30. style=1, fg=(1, 1, 1, 1), pos=(0.06, -0.08),
  31. align=TextNode.ALeft, scale=.05,
  32. parent=base.a2dTopLeft)
  33. spaceEvent = OnscreenText(text="2: Toggle Light from the front On/Off",
  34. style=1, fg=(1, 1, 1, 1), pos=(0.06, -0.14),
  35. align=TextNode.ALeft, scale=.05,
  36. parent=base.a2dTopLeft)
  37. upDownEvent = OnscreenText(text="3: Toggle Light from on top On/Off",
  38. style=1, fg=(1, 1, 1, 1), pos=(0.06, -0.20),
  39. align=TextNode.ALeft, scale=.05,
  40. parent=base.a2dTopLeft)
  41. # You can't normalize inline so this is a helper function
  42. def normalized(*args):
  43. myVec = LVector3(*args)
  44. myVec.normalize()
  45. return myVec
  46. # helper function to make a square given the Lower-Left-Hand and
  47. # Upper-Right-Hand corners
  48. def makeSquare(x1, y1, z1, x2, y2, z2):
  49. format = GeomVertexFormat.getV3n3cpt2()
  50. vdata = GeomVertexData('square', format, Geom.UHDynamic)
  51. vertex = GeomVertexWriter(vdata, 'vertex')
  52. normal = GeomVertexWriter(vdata, 'normal')
  53. color = GeomVertexWriter(vdata, 'color')
  54. texcoord = GeomVertexWriter(vdata, 'texcoord')
  55. # make sure we draw the sqaure in the right plane
  56. if x1 != x2:
  57. vertex.addData3(x1, y1, z1)
  58. vertex.addData3(x2, y1, z1)
  59. vertex.addData3(x2, y2, z2)
  60. vertex.addData3(x1, y2, z2)
  61. normal.addData3(normalized(2 * x1 - 1, 2 * y1 - 1, 2 * z1 - 1))
  62. normal.addData3(normalized(2 * x2 - 1, 2 * y1 - 1, 2 * z1 - 1))
  63. normal.addData3(normalized(2 * x2 - 1, 2 * y2 - 1, 2 * z2 - 1))
  64. normal.addData3(normalized(2 * x1 - 1, 2 * y2 - 1, 2 * z2 - 1))
  65. else:
  66. vertex.addData3(x1, y1, z1)
  67. vertex.addData3(x2, y2, z1)
  68. vertex.addData3(x2, y2, z2)
  69. vertex.addData3(x1, y1, z2)
  70. normal.addData3(normalized(2 * x1 - 1, 2 * y1 - 1, 2 * z1 - 1))
  71. normal.addData3(normalized(2 * x2 - 1, 2 * y2 - 1, 2 * z1 - 1))
  72. normal.addData3(normalized(2 * x2 - 1, 2 * y2 - 1, 2 * z2 - 1))
  73. normal.addData3(normalized(2 * x1 - 1, 2 * y1 - 1, 2 * z2 - 1))
  74. # adding different colors to the vertex for visibility
  75. color.addData4f(1.0, 0.0, 0.0, 1.0)
  76. color.addData4f(0.0, 1.0, 0.0, 1.0)
  77. color.addData4f(0.0, 0.0, 1.0, 1.0)
  78. color.addData4f(1.0, 0.0, 1.0, 1.0)
  79. texcoord.addData2f(0.0, 1.0)
  80. texcoord.addData2f(0.0, 0.0)
  81. texcoord.addData2f(1.0, 0.0)
  82. texcoord.addData2f(1.0, 1.0)
  83. # Quads aren't directly supported by the Geom interface
  84. # you might be interested in the CardMaker class if you are
  85. # interested in rectangle though
  86. tris = GeomTriangles(Geom.UHDynamic)
  87. tris.addVertices(0, 1, 3)
  88. tris.addVertices(1, 2, 3)
  89. square = Geom(vdata)
  90. square.addPrimitive(tris)
  91. return square
  92. # Note: it isn't particularly efficient to make every face as a separate Geom.
  93. # instead, it would be better to create one Geom holding all of the faces.
  94. square0 = makeSquare(-1, -1, -1, 1, -1, 1)
  95. square1 = makeSquare(-1, 1, -1, 1, 1, 1)
  96. square2 = makeSquare(-1, 1, 1, 1, -1, 1)
  97. square3 = makeSquare(-1, 1, -1, 1, -1, -1)
  98. square4 = makeSquare(-1, -1, -1, -1, 1, 1)
  99. square5 = makeSquare(1, -1, -1, 1, 1, 1)
  100. snode = GeomNode('square')
  101. snode.addGeom(square0)
  102. snode.addGeom(square1)
  103. snode.addGeom(square2)
  104. snode.addGeom(square3)
  105. snode.addGeom(square4)
  106. snode.addGeom(square5)
  107. cube = render.attachNewNode(snode)
  108. cube.hprInterval(1.5, (360, 360, 360)).loop()
  109. # OpenGl by default only draws "front faces" (polygons whose vertices are
  110. # specified CCW).
  111. cube.setTwoSided(True)
  112. class MyTapper(DirectObject):
  113. def __init__(self):
  114. self.testTexture = loader.loadTexture("maps/envir-reeds.png")
  115. self.accept("1", self.toggleTex)
  116. self.accept("2", self.toggleLightsSide)
  117. self.accept("3", self.toggleLightsUp)
  118. self.LightsOn = False
  119. self.LightsOn1 = False
  120. slight = Spotlight('slight')
  121. slight.setColor((1, 1, 1, 1))
  122. lens = PerspectiveLens()
  123. slight.setLens(lens)
  124. self.slnp = render.attachNewNode(slight)
  125. self.slnp1 = render.attachNewNode(slight)
  126. def toggleTex(self):
  127. global cube
  128. if cube.hasTexture():
  129. cube.setTextureOff(1)
  130. else:
  131. cube.setTexture(self.testTexture)
  132. def toggleLightsSide(self):
  133. global cube
  134. self.LightsOn = not self.LightsOn
  135. if self.LightsOn:
  136. render.setLight(self.slnp)
  137. self.slnp.setPos(cube, 10, -400, 0)
  138. self.slnp.lookAt(10, 0, 0)
  139. else:
  140. render.setLightOff(self.slnp)
  141. def toggleLightsUp(self):
  142. global cube
  143. self.LightsOn1 = not self.LightsOn1
  144. if self.LightsOn1:
  145. render.setLight(self.slnp1)
  146. self.slnp1.setPos(cube, 10, 0, 400)
  147. self.slnp1.lookAt(10, 0, 0)
  148. else:
  149. render.setLightOff(self.slnp1)
  150. t = MyTapper()
  151. base.run()