main.py 6.1 KB

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