# 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. # from direct.directbase import DirectStart from direct.showbase.DirectObject import DirectObject from direct.gui.DirectGui import * from direct.interval.IntervalGlobal import * from direct.task.Task import Task from panda3d.core import lookAt from panda3d.core import PerspectiveLens from panda3d.core import CardMaker from panda3d.core import Fog from panda3d.core import Light, Spotlight, DirectionalLight, AmbientLight, PointLight from panda3d.core import TextNode from panda3d.core import Geom, GeomTriangles, GeomVertexWriter from panda3d.core import GeomVertexFormat, GeomVertexData from panda3d.core import Vec3, Vec4, Point3,BitMask32 from panda3d.core import Texture, GeomNode from panda3d.core import CollisionTraverser,CollisionNode from panda3d.core import CollisionHandlerQueue,CollisionRay import sys, os, time from blocks import Cube import terrain import octree #base.disableMouse() base.camera.setPos(0, -30, 0) title = OnscreenText(text="Panda 3d Cube world demo", style=1, fg=(1,1,1,1), pos=(0.5,-0.95), scale = .07) escapeEvent = OnscreenText( text="2: Turn on light", style=1, fg=(1,1,1,1), pos=(-1.3, 0.95), align=TextNode.ALeft, scale = .05) spaceEvent = OnscreenText( text="d: Toggle Delete mode", style=1, fg=(1,1,1,1), pos=(-1.3, 0.90), align=TextNode.ALeft, scale = .05) upDownEvent = OnscreenText( text="Mouse1: Delete cube", style=1, fg=(1,1,1,1), pos=(-1.3, 0.85), align=TextNode.ALeft, scale = .05) upDownEvent = OnscreenText( text="f: Toggle Fog", style=1, fg=(1,1,1,1), pos=(-1.3, 0.80), align=TextNode.ALeft, scale = .05) #cube = Cube(0,0,0,'grass') #cube2 = Cube(0,0,1,'grass') #ube3 = Cube(0,0,2,'grass') #ube4 = Cube(0,0,3,'metal') #cubes.append(cube) #cubes.append(cube2) class MyTapper(DirectObject): def __init__(self): self.gs = 32 self.buttons = {'zoom':0} self.testTexture=loader.loadTexture("maps/envir-reeds.png") #self.accept("1", self.toggleTex) self.accept("2", self.toggleLights) self.accept("d", self.delnode) self.accept("f", self.toggleFog) self.fog = False self.myfog = Fog("mainfog") self.myfog.setColor(.8,.8,.8) self.myfog.setExpDensity(.05) self.deltoggle = False self.accept("+", self.setKey, ['zoom',1]) self.accept("+-up", self.setKey, ['zoom',0]) self.accept("-", self.setKey, ['zoom',-1]) self.accept("--up", self.setKey, ['zoom',0]) self.accept("mouse1", self.deletehighlighted) self.LightsOn=False self.dlight = PointLight('dlight') self.dlight.setColor(Vec4(.8,.8,.5,1)) #self.dlight.setShadowCaster(True, self.gs,self.gs) self.dlnp = render.attachNewNode(self.dlight) #self.dlnp.setHpr(-60,-60,0) self.dlnp.setPos(0,100,100) ambientLight = AmbientLight( "ambientLight" ) ambientLight.setColor( Vec4(.4, .4, .4, 1) ) render.setLight(render.attachNewNode(ambientLight)) self.gameTask = taskMgr.add(self.gameLoop, "gameloop") self.gameTask.last = 0 #mouse stuff #any other collision detection system with a traverser and a handler self.picker = CollisionTraverser() #Make a traverser self.pq = CollisionHandlerQueue() #Make a handler #Make a collision node for our picker ray self.pickerNode = CollisionNode('mouseRay') #Attach that node to the camera since the ray will need to be positioned #relative to it self.pickerNP = camera.attachNewNode(self.pickerNode) #Everything to be picked will use bit 1. This way if we were doing other #collision we could seperate it self.pickerNode.setFromCollideMask(BitMask32.bit(1)) self.pickerRay = CollisionRay() #Make our ray self.pickerNode.addSolid(self.pickerRay) #Add it to the collision node #Register the ray as something that can cause collisions self.picker.addCollider(self.pickerNP, self.pq) #self.picker.showCollisions(render) self.highlighted = None self.mouseTask = taskMgr.add(self.mouseTask, 'mouseTask') print "Generating Terrain..." ter = terrain.gen(self.gs,self.gs,32) self.cubes = [] i = 0 l = len(ter) treesize = self.gs*self.gs*32 self.otree = octree.Octree(treesize) for blk in ter: print "\r %.2f%% done making blocks" % (1.0*i/l), i+= 1 c = Cube(*blk) c.settree(self.otree) self.otree.insert(c.position,c) self.cubes.append(c) self.cubeRoot = render.attachNewNode("cubeRoot") i = 0 for c in self.cubes: print "\r %.2f%% done riticulating splines" % (1.0*i/l), i+= 1 result = c.checkneighbors() if result: c.show(self.cubeRoot) def delnode(self): self.deltoggle = not self.deltoggle def setKey(self,key,val): self.buttons[key] = val def zoom(self,time,mult=10): if self.buttons['zoom']: delta = (0,self.buttons['zoom']*time*mult,0) base.camera.setPos(base.camera.getPos() + delta) def toggleLights(self): self.LightsOn=not(self.LightsOn) if self.LightsOn: #render.setShaderAuto() render.setLight(self.dlnp) else: render.setLightOff(self.dlnp) def toggleFog(self): self.fog = not(self.fog) if self.fog: render.setFog(self.myfog) else: render.clearFog() def gameLoop(self,task): dt = task.time - task.last task.last = task.time self.zoom(dt) return task.cont def mouseTask(self,task): if base.mouseWatcherNode.hasMouse(): mpos = base.mouseWatcherNode.getMouse() self.pickerRay.setFromLens(base.camNode, mpos.getX(),mpos.getY()) self.picker.traverse(self.cubeRoot) if self.pq.getNumEntries() > 0: self.pq.sortEntries() entry = self.pq.getEntry(0) #print dir(entry) #entry.getIntoNodePath().getParent().setColor(HIGHLIGHTCOLOR) (x,y,z) = entry.getIntoNodePath().getParent().getPos() c = self.otree.search((x, y, z)) if c: if self.highlighted != c: if self.highlighted: self.highlighted.dehighlight() self.highlighted = c c.highlight() if self.deltoggle and self.highlighted: self.deletehighlighted() return task.cont def deletehighlighted(self): if self.highlighted: self.highlighted.dehighlight() self.highlighted.remove() self.highlighted = None t=MyTapper() run()