I was butchering the Procedural-Cube tutorial and cant figure out how I broke the normal for the bottom face of my cube. I altered the code to make the whole cube one Geom of 6 GeomTristrip primitives (vs the 6 Geoms of 2 GeomTriangle primitives).
Please take a look at the following code and let me know where it went wrong. Also feel free to criticize my code in general, I am self taught and always looking to improve.
# Author: Kwasi Mensah (kmensah@andrew.cmu.edu)
# 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.
#
# Modified by: Daniel DePauw
# Date: 11/18/2010
#
# Changed it to create one geom per cube with 6 GeomTristrip primitives
# also modified it to take the top left corner and bottom right as arguments
from direct.directbase import DirectStart
from direct.showbase.DirectObject import DirectObject
from direct.gui.DirectGui import *
from direct.interval.IntervalGlobal import *
from panda3d.core import *
import sys, os, time
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.5,-0.95), scale = .07)
escapeEvent = OnscreenText(
text="1: Set a Texture onto the Cube",
style=1, fg=(1,1,1,1), pos=(-1.3, 0.95),
align=TextNode.ALeft, scale = .05)
spaceEvent = OnscreenText(
text="2: Toggle Light from the front On/Off",
style=1, fg=(1,1,1,1), pos=(-1.3, 0.90),
align=TextNode.ALeft, scale = .05)
upDownEvent = OnscreenText(
text="3: Toggle Light from on top On/Off",
style=1, fg=(1,1,1,1), pos=(-1.3, 0.85),
align=TextNode.ALeft, scale = .05)
class ProceduralCube(DirectObject):
def __init__(self):
# set up some lights, textures and toggle switches
self.tapperInit()
# Procedural Geometry stuff.
format=GeomVertexFormat.getV3n3cpt2()
self.vdata=GeomVertexData('square', format, Geom.UHDynamic)
self.square=Geom(self.vdata)
self.vertex=GeomVertexWriter(self.vdata, 'vertex')
self.normal=GeomVertexWriter(self.vdata, 'normal')
self.color=GeomVertexWriter(self.vdata, 'color')
self.texcoord=GeomVertexWriter(self.vdata, 'texcoord')
self.tri1=GeomTristrips(Geom.UHDynamic)
self.makeSquare(-1,-1, 1, 1,-1,-1)
self.makeSquare( 1, 1, 1, -1, 1,-1)
self.makeSquare(-1, 1, 1, -1,-1,-1)
self.makeSquare( 1,-1, 1, 1, 1,-1)
self.makeSquare(-1,-1,-1, 1, 1,-1) # issue here :( Normal is backwards.
self.makeSquare( 1, 1, 1, -1,-1, 1)
self.square.addPrimitive(self.tri1)
snode=GeomNode('square')
snode.addGeom(self.square)
self.cube=render.attachNewNode(snode)
self.cube.hprInterval(1.5,Point3(360,360,360)).loop()
#helper function to make a square given the Top-Left-Hand and Lower-Right-Hand corners
def makeSquare(self, x1,y1,z1, x2,y2,z2):
if z1!=z2:
self.vertex.addData3f(x1, y1, z1)
self.vertex.addData3f(x1, y1, z2)
self.vertex.addData3f(x2, y2, z1)
self.vertex.addData3f(x2, y2, z2)
self.normal.addData3f(self.myNormalize(Vec3(2*x1-1, 2*y1-1, 2*z1-1)))
self.normal.addData3f(self.myNormalize(Vec3(2*x1-1, 2*y1-1, 2*z2-1)))
self.normal.addData3f(self.myNormalize(Vec3(2*x2-1, 2*y2-1, 2*z1-1)))
self.normal.addData3f(self.myNormalize(Vec3(2*x2-1, 2*y2-1, 2*z2-1)))
else:
self.vertex.addData3f(x1, y1, z1)
self.vertex.addData3f(x2, y1, z1)
self.vertex.addData3f(x1, y2, z2)
self.vertex.addData3f(x2, y2, z2)
self.normal.addData3f(self.myNormalize(Vec3(2*x1-1, 2*y1-1, 2*z1-1)))
self.normal.addData3f(self.myNormalize(Vec3(2*x2-1, 2*y1-1, 2*z1-1)))
self.normal.addData3f(self.myNormalize(Vec3(2*x1-1, 2*y2-1, 2*z2-1)))
self.normal.addData3f(self.myNormalize(Vec3(2*x2-1, 2*y2-1, 2*z2-1)))
#adding different colors to the vertex for visibility
self.color.addData4f(1.0,0.0,0.0,1.0)
self.color.addData4f(0.0,1.0,0.0,1.0)
self.color.addData4f(0.0,0.0,1.0,1.0)
self.color.addData4f(1.0,0.0,1.0,1.0)
self.texcoord.addData2f(0.0, 1.0)
self.texcoord.addData2f(0.0, 0.0)
self.texcoord.addData2f(1.0, 0.0)
self.texcoord.addData2f(1.0, 1.0)
self.tri1.addNextVertices(4)
self.tri1.closePrimitive()
#you cant normalize in-place so this is a helper function
def myNormalize(self, myVec):
myVec.normalize()
return myVec
def tapperInit(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(Vec4(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 self.cube.hasTexture():
self.cube.setTextureOff(1)
else:
self.cube.setTexture(self.testTexture)
def toggleLightsSide(self):
self.LightsOn=not(self.LightsOn)
if self.LightsOn:
render.setLight(self.slnp)
self.slnp.setPos(self.cube, 10,-400,0)
self.slnp.lookAt(Point3(10, 0, 0))
else:
render.setLightOff(self.slnp)
def toggleLightsUp(self):
self.LightsOn1=not(self.LightsOn1)
if self.LightsOn1:
render.setLight(self.slnp1)
self.slnp1.setPos(self.cube, 10,0,400)
self.slnp1.lookAt(Point3(10, 0, 0))
else:
render.setLightOff(self.slnp1)
pCube=ProceduralCube()
run()
Thanks in advance for your help,
Daniel.