| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 |
- #!/usr/bin/env python
- # Author: Kwasi Mensah ([email protected])
- # Date: 8/02/2005
- #
- # This is meant to be a simple example of how to draw a cube
- # using Panda's new Geom Interface. Quads arent directly supported
- # since they get broken down to trianlges anyway.
- #
- from direct.showbase.ShowBase import ShowBase
- from direct.showbase.DirectObject import DirectObject
- from direct.gui.DirectGui import *
- from direct.interval.IntervalGlobal import *
- from panda3d.core import lookAt
- from panda3d.core import GeomVertexFormat, GeomVertexData
- from panda3d.core import Geom, GeomTriangles, GeomVertexWriter
- from panda3d.core import Texture, GeomNode
- from panda3d.core import PerspectiveLens
- from panda3d.core import Light, Spotlight
- from panda3d.core import TextNode
- from panda3d.core import LVector3
- import sys
- import os
- base = ShowBase()
- base.disableMouse()
- base.camera.setPos(0, -10, 0)
- title = OnscreenText(text="Panda3D: Tutorial - Making a Cube Procedurally",
- style=1, fg=(1, 1, 1, 1), pos=(-0.1, 0.1), scale=.07,
- parent=base.a2dBottomRight, align=TextNode.ARight)
- escapeEvent = OnscreenText(text="1: Set a Texture onto the Cube",
- style=1, fg=(1, 1, 1, 1), pos=(0.06, -0.08),
- align=TextNode.ALeft, scale=.05,
- parent=base.a2dTopLeft)
- spaceEvent = OnscreenText(text="2: Toggle Light from the front On/Off",
- style=1, fg=(1, 1, 1, 1), pos=(0.06, -0.14),
- align=TextNode.ALeft, scale=.05,
- parent=base.a2dTopLeft)
- upDownEvent = OnscreenText(text="3: Toggle Light from on top On/Off",
- style=1, fg=(1, 1, 1, 1), pos=(0.06, -0.20),
- align=TextNode.ALeft, scale=.05,
- parent=base.a2dTopLeft)
- # You can't normalize inline so this is a helper function
- def normalized(*args):
- myVec = LVector3(*args)
- myVec.normalize()
- return myVec
- # helper function to make a square given the Lower-Left-Hand and
- # Upper-Right-Hand corners
- def makeSquare(x1, y1, z1, x2, y2, z2):
- format = GeomVertexFormat.getV3n3cpt2()
- vdata = GeomVertexData('square', format, Geom.UHDynamic)
- vertex = GeomVertexWriter(vdata, 'vertex')
- normal = GeomVertexWriter(vdata, 'normal')
- color = GeomVertexWriter(vdata, 'color')
- texcoord = GeomVertexWriter(vdata, 'texcoord')
- # make sure we draw the sqaure in the right plane
- if x1 != x2:
- vertex.addData3(x1, y1, z1)
- vertex.addData3(x2, y1, z1)
- vertex.addData3(x2, y2, z2)
- vertex.addData3(x1, y2, z2)
- normal.addData3(normalized(2 * x1 - 1, 2 * y1 - 1, 2 * z1 - 1))
- normal.addData3(normalized(2 * x2 - 1, 2 * y1 - 1, 2 * z1 - 1))
- normal.addData3(normalized(2 * x2 - 1, 2 * y2 - 1, 2 * z2 - 1))
- normal.addData3(normalized(2 * x1 - 1, 2 * y2 - 1, 2 * z2 - 1))
- else:
- vertex.addData3(x1, y1, z1)
- vertex.addData3(x2, y2, z1)
- vertex.addData3(x2, y2, z2)
- vertex.addData3(x1, y1, z2)
- normal.addData3(normalized(2 * x1 - 1, 2 * y1 - 1, 2 * z1 - 1))
- normal.addData3(normalized(2 * x2 - 1, 2 * y2 - 1, 2 * z1 - 1))
- normal.addData3(normalized(2 * x2 - 1, 2 * y2 - 1, 2 * z2 - 1))
- normal.addData3(normalized(2 * x1 - 1, 2 * y1 - 1, 2 * z2 - 1))
- # adding different colors to the vertex for visibility
- color.addData4f(1.0, 0.0, 0.0, 1.0)
- color.addData4f(0.0, 1.0, 0.0, 1.0)
- color.addData4f(0.0, 0.0, 1.0, 1.0)
- color.addData4f(1.0, 0.0, 1.0, 1.0)
- texcoord.addData2f(0.0, 1.0)
- texcoord.addData2f(0.0, 0.0)
- texcoord.addData2f(1.0, 0.0)
- texcoord.addData2f(1.0, 1.0)
- # Quads aren't directly supported by the Geom interface
- # you might be interested in the CardMaker class if you are
- # interested in rectangle though
- tris = GeomTriangles(Geom.UHDynamic)
- tris.addVertices(0, 1, 3)
- tris.addVertices(1, 2, 3)
- square = Geom(vdata)
- square.addPrimitive(tris)
- return square
- # Note: it isn't particularly efficient to make every face as a separate Geom.
- # instead, it would be better to create one Geom holding all of the faces.
- square0 = makeSquare(-1, -1, -1, 1, -1, 1)
- square1 = makeSquare(-1, 1, -1, 1, 1, 1)
- square2 = makeSquare(-1, 1, 1, 1, -1, 1)
- square3 = makeSquare(-1, 1, -1, 1, -1, -1)
- square4 = makeSquare(-1, -1, -1, -1, 1, 1)
- square5 = makeSquare(1, -1, -1, 1, 1, 1)
- snode = GeomNode('square')
- snode.addGeom(square0)
- snode.addGeom(square1)
- snode.addGeom(square2)
- snode.addGeom(square3)
- snode.addGeom(square4)
- snode.addGeom(square5)
- cube = render.attachNewNode(snode)
- cube.hprInterval(1.5, (360, 360, 360)).loop()
- # OpenGl by default only draws "front faces" (polygons whose vertices are
- # specified CCW).
- cube.setTwoSided(True)
- class MyTapper(DirectObject):
- def __init__(self):
- self.testTexture = loader.loadTexture("maps/envir-reeds.png")
- self.accept("1", self.toggleTex)
- self.accept("2", self.toggleLightsSide)
- self.accept("3", self.toggleLightsUp)
- self.LightsOn = False
- self.LightsOn1 = False
- slight = Spotlight('slight')
- slight.setColor((1, 1, 1, 1))
- lens = PerspectiveLens()
- slight.setLens(lens)
- self.slnp = render.attachNewNode(slight)
- self.slnp1 = render.attachNewNode(slight)
- def toggleTex(self):
- global cube
- if cube.hasTexture():
- cube.setTextureOff(1)
- else:
- cube.setTexture(self.testTexture)
- def toggleLightsSide(self):
- global cube
- self.LightsOn = not self.LightsOn
- if self.LightsOn:
- render.setLight(self.slnp)
- self.slnp.setPos(cube, 10, -400, 0)
- self.slnp.lookAt(10, 0, 0)
- else:
- render.setLightOff(self.slnp)
- def toggleLightsUp(self):
- global cube
- self.LightsOn1 = not self.LightsOn1
- if self.LightsOn1:
- render.setLight(self.slnp1)
- self.slnp1.setPos(cube, 10, 0, 400)
- self.slnp1.lookAt(10, 0, 0)
- else:
- render.setLightOff(self.slnp1)
- t = MyTapper()
- base.run()
|