Oh yes, it’s time for portals.
I thought I’d make a simple portal demo to figure out how to set it up and have something that could be used as an example for others.
Unfortunately I’m a bit stuck.
I’ve set up the cells and portals as described in this thread: [url]Occlusion, Portals etc...].
The single test model seems to be hiding and unhiding itself, although at the wrong position/angles. At other angles Panda (the program, not the model) will poof from existence.
Here is what I have so far: http://drop.io/pdw5qoc/asset/portals-zip (portals.zip).
I don’t have any code to select which cell the camera is in yet, so it just assumes that you are in cell “1” which is the exterior area.
WASD is used to move the camera and arrow keys to look around. F toggles wireframe, which is useful for seeing if the panda model is visible.
I have a couple questions regarding portals:
- Do I need to use the setOpen function somehow?
- Does the winding order of the points on the portal polygon matter (if we are seeing the front or back of the polygon)?
I’ll paste the code here, but it is also in the zip with the related egg files.
from pandac.PandaModules import loadPrcFileData
loadPrcFileData('', 'coordinate-system yup')
loadPrcFileData('', 'window-title Portal Demo')
loadPrcFileData('', 'allow-portal-cull 1')
#loadPrcFileData('', 'show-portal-debug 1')
import direct.directbase.DirectStart
from direct.showbase.DirectObject import DirectObject
from direct.actor.Actor import Actor
from pandac.PandaModules import BitMask32, Vec3, PerspectiveLens, NodePath
class Game(DirectObject):
def __init__(self):
# Setup controls
self.keys = {}
for key in ['a', 'd', 'w', 's', 'arrow_left', 'arrow_right', 'arrow_up', 'arrow_down']:
self.keys[key] = 0
self.accept(key, self.push_key, [key, 1])
self.accept('%s-up' % key, self.push_key, [key, 0])
self.accept('f', base.toggleWireframe)
self.accept('escape', __import__('sys').exit, [0])
base.disableMouse()
# Setup camera
lens = PerspectiveLens()
lens.setFov(60)
lens.setNear(0.01)
lens.setFar(1000.0)
base.cam.node().setLens(lens)
base.camera.setPos(-9, 1, -0.5)
self.heading = -95.0
self.pitch = 0.0
base.camera.setH(self.heading)
# Load geometry
level_model = loader.loadModel('level')
level_model.reparentTo(render)
# Load cells
self.cells = {}
self.cells_by_collider = {}
cell_model = loader.loadModel('cells')
for cell_node in cell_model.getChildren()[0].getChildren():
name = cell_node.getName()
if name.startswith('cell'):
cell_id = name[4:]
cell = Cell(cell_id, cell_node)
self.cells[cell_id] = cell
self.cells_by_collider[cell_node] = cell
# Load portals
portal_model = loader.loadModel('portals')
for portal_node in portal_model.getChildren()[0].getChildren():
name = portal_node.getName()
if name.startswith('portal_'):
cell_a, cell_b = name.split('_')[1].split('to')
cell_a, cell_b = self.cells[cell_a], self.cells[cell_b]
cell_a.add_portal(portal_node, cell_b)
cell_b.add_portal(portal_node, cell_a)
portal_model.removeNode()
# Put a test model in cell 2 (red hallway)
panda = loader.loadModel('panda')
panda.setScale(0.1)
panda.reparentTo(self.cells['2'].nodepath)
taskMgr.add(self.update, 'main loop')
def push_key(self, key, value):
self.keys[key] = value
def update(self, task):
# Update camera
dt = globalClock.getDt()
base.camera.setPos(base.camera, dt * 3 * -self.keys['a'] + dt * 3 * self.keys['d'], 0, dt * 3 * self.keys['s'] + dt * 3 * -self.keys['w'])
self.heading += dt * 90 * self.keys['arrow_left'] + dt * 90 * -self.keys['arrow_right']
self.pitch += dt * 90 * self.keys['arrow_up'] + dt * 90 * -self.keys['arrow_down']
base.camera.setHpr(self.heading, self.pitch, 0)
# Update cells
# this is where the cell the camera is currently in should be shown
# for now just set it to always show cell 1 (green exterior)
for cell in self.cells:
self.cells[cell].nodepath.hide()
self.cells['1'].nodepath.show()
return task.cont
class Cell(object):
def __init__(self, id, collider):
self.id = id
self.collider = collider
self.nodepath = NodePath('cell_%s_root' % id)
self.nodepath.reparentTo(render)
self.nodepath.hide()
def add_portal(self, portal, cell_out):
portal = portal.copyTo(self.nodepath)
portal.node().setCellIn(self.nodepath)
portal.node().setCellOut(cell_out.nodepath)
Game()
run()