4 Walls Projection Setup

Hi guys, I’m a student at the ETC Global (portugal program) and as some of you know, we’re building our own CAVE here, with 4 walls rather than 3…i’ve been looking around the code and I was wondering if someone could tell me if this is right. The goal is to project on 4 screens at once…I have 5 screens now, and one puppet, not sure about the coordinates though! Any ideas? Thanks, António Gomes

# are we in the cave
INCAVE = 0      # 0 = no, 1 = yes
# window PRCfile data   - index 0 is not in cave, 1 is in cave
PRC_ORIGIN = [["win-origin 0 50", "win-origin 400 50", "win-origin 800 50", "win-origin 800 400", "win-origin 1200 400"],
              ["win-origin -1024 -768", "win-origin 0 -768", "win-origin 1024 -768", "win-origin 100 100","win-origin 0 0"]]
PRC_SIZE = ["win-size 320 240", "win-size 1024 768"]
PRC_DEC = ["undecorated 0", "undecorated 1"]
import direct.directbase.DirectStart                                     
from direct.showbase.DirectObject import DirectObject
from pandac.PandaModules import *
from direct.gui.DirectGui import *
from direct.task import Task 
from direct.actor.Actor import Actor
from direct.interval.IntervalGlobal import * 
import math
import sys

from VARS import *

class World(DirectObject): 
    def __init__(self):
        # setup the cameras
        self.screenSet()
        
        # set the background color
        base.setBackgroundColor( .2, .2, .2 )
        
        # load enviro model
        self.terrain = loader.loadModel("models/environment.egg")
        self.terrain.reparentTo(render)
        
        # setup controls
        self.keys = {'w':False, 'a':False, 's':False, 'd':False, 'r':False, 'f':False, 
					'q':False, 'e':False, 't':False, 'g':False}
                
       
        # setup the left, center, and right cameras to render the desired node
        base.camList[0].node().setScene(render)       # puppet
        base.camList[1].node().setScene(render)       # left
        base.camList[2].node().setScene(render)       # center
        base.camList[3].node().setScene(render)       # right
        base.camList[4].node().setScene(render)       # back
        
        
        # adjust lens
        lens = PerspectiveLens()
        lens.setFov(VBase2(45, 30))
        lens.setNearFar(1.0, 100000.0)
        for i in range(0,4):
            base.camList[i].node().setLens(lens)

w = World()
run()

It’s probably better to open one big window that covers the entire desktop area, and use DisplayRegions to subdivide it into the different projector regions, instead of opening up multiple independent windows. In my experience, one window is more likely to give good performance than multiple windows. However, this is very driver dependent, and maybe you will get good performance with multiple windows.

But if you do want to open multiple windows, it’s probably easier to use WindowProperties to specify the position of each one, rather than trying to load a different prc file. Loading all of these prc files internally is going to be troublesome, because they all accumulate (you never release any of them after you have loaded them). Instead of doing this, just call the appropriate elements of WindowProperties, e.g. self.wp.setOrigin(400, 50), before calling openWindow().

Also, I wouldn’t recommend calling setScene() after you create a camera. There’s usually no need to call setScene(render) since the camera will automatically draw whatever scene graph it is parented under, which is almost always render anyway.

I don’t see any other obvious problems. Is there something in particular you wanted to ask about?

David

Hi David, thank you so much for your answer…

Basically that’s the demo code for the cave at the ETC, the difference is that here we’re using one more screen…my question is, jsut to be sure on which materials I should start studying now, what’s the most efficient to have 4 different screens WITH interaction:

  • do like a posted
  • do a really big one and subdivide in 1024x768 screens…i would need 4096+ x 768

The idea is to have 4 buttons, one for each screen. On screen there will be musical notes (for now) and every time they tap I have to analyze if it was at the right time, give some feedback if so, other feedback if it was wrong…a little bit like a rudimentar version of guitar hero!

If anyone could point me to look at some examples that would be great…or even what i should focus on!

i.e, to use display regions would it be like:

self.drLeft = self.window.makeDisplayRegion(constants.display_region_left.getX(),constants.display_region_left.getY(),constants.display_region_left.getZ(),constants.display_region_left.getW()) 

self.drLeft.setCamera(self.orbitCamera1.getCameraNodePath()) 

self.drRight =
self.window.makeDisplayRegion(constants.display_region_right.getX(),constants.display_region_right.getY(),constants.display_region_right.getZ(),constants.display_region_right.getW()) 

self.drRight.setCamera(self.orbitCamera1.getCameraNodePath())

self.drFront =
self.window.makeDisplayRegion(constants.display_region_front.getX(),constants.display_region_frontt.getY(),constants.display_region_front.getZ(),constants.display_region_front.getW()) 

self.drFront.setCamera(self.orbitCamera1.getCameraNodePath())

self.drBack =
self.window.makeDisplayRegion(constants.display_region_back.getX(),constants.display_region_frontt.getY(),constants.display_region_back.getZ(),constants.display_region_back.getW()) 

self.drBack.setCamera(self.orbitCamera1.getCameraNodePath())

or am i doing this all wrong? :slight_smile:

an example pic:

Best,

António

As I’ve said, in my personal experience, one enormous window with several DisplayRegions is more likely to be faster than several windows. But I have no idea which is going to be better on your hardware. You could try both and see which one you like better.

I don’t have any sample code sitting around, sorry. But it does appear that you’re on the right track.

David

hi again! I have a specific question this time, that i’m guessing it’s pretty easy to solve but i’m having some trouble…i did some progress today and i have some textures and objects on the center screen, but i need each color to match one screen so I’m guessing i’m doing something wrong with the cameras…anyone has any idea?

Thanks!

       self.bluebackground=self.loadegg(BACKGROUND[0],(0,20,0),(0,0,0),(20,0,15))
        self.bluecircle=self.loadegg(CIRCLE,(7,15,0),(0,0,0),(3,0,3),('circle','blue'))
        self.bluedrums=self.loadegg(DRUMS[0],(0,10,0),(0,0,0),(2,0,1.6),('drums','blue'))
        self.blueSeq=Sequence()
        print self.bluedrums
        self.blueSeq.append(self.bluedrums.posInterval(1,Point3(10,10,0),startPos=Point3(-13,10,0)))
        self.blueSeq.append(self.bluedrums.posInterval(2,Point3(10,10,0),startPos=Point3(-13,10,0)))
        self.blueSeq.loop()
        
        #red background
        self.redbackground=self.loadegg(BACKGROUND[1],(0,20,0),(0,0,0),(20,0,15))
        self.redcircle=self.loadegg(CIRCLE,(7,15,0),(0,0,0),(3,0,3),('circle','red'))
        self.reddrums=self.loadegg(DRUMS[1],(0,10,0),(0,0,0),(2,0,1.6),('drums','red'))
        self.redSeq=Sequence()
        print self.reddrums
        self.redSeq.append(self.reddrums.posInterval(1,Point3(10,10,0),startPos=Point3(-13,10,0)))
        self.redSeq.append(self.reddrums.posInterval(2,Point3(10,10,0),startPos=Point3(-13,10,0)))
        self.redSeq.loop()
        
        #green background
        self.greenbackground=self.loadegg(BACKGROUND[2],(0,20,0),(0,0,0),(20,0,15))
        self.greencircle=self.loadegg(CIRCLE,(7,15,0),(0,0,0),(3,0,3),('circle','green'))
        self.greendrums=self.loadegg(DRUMS[2],(0,10,0),(0,0,0),(2,0,1.6),('drums','green'))
        self.greenSeq=Sequence()
        print self.greendrums
        self.greenSeq.append(self.greendrums.posInterval(1,Point3(10,10,0),startPos=Point3(-13,10,0)))
        self.greenSeq.append(self.greendrums.posInterval(2,Point3(10,10,0),startPos=Point3(-13,10,0)))
        self.greenSeq.loop()
        
        #yellow background
        self.yellowbackground=self.loadegg(BACKGROUND[3],(0,20,0),(0,0,0),(20,0,15))
        self.yellowcircle=self.loadegg(CIRCLE,(7,15,0),(0,0,0),(3,0,3),('circle','yellow'))
        self.yellowdrums=self.loadegg(DRUMS[3],(0,10,0),(0,0,0),(2,0,1.6),('drums','yellow'))
        self.yellowSeq=Sequence()
        print self.yellowdrums
        self.yellowSeq.append(self.yellowdrums.posInterval(1,Point3(10,10,0),startPos=Point3(-13,10,0)))
        self.yellowSeq.append(self.yellowdrums.posInterval(2,Point3(10,10,0),startPos=Point3(-13,10,0)))
        self.yellowSeq.loop()
    
   

Fixed!

I did the translation wrong :wink:
[/code]

No, sorry, I don’t understand what you’re asking. What’s the problem, exactly? You need each screen to be the same color? What color is it coming out now, and what color do you expect it to be instead?

Posting the code isn’t actually very useful, because I can’t run the code (without your models, and without your projection environment) to see what you see, and I can’t just look at a hundred lines of code and say “oh, you’ve made a mistake here at line 37.”

But if you can narrow it down to a particular question like “why doesn’t base.setBackgroundColor() change the background color of all of my screens to the same color,” or “why does my model seem darker on the left screen than it is on the front screen,” I might be able to help you find where to look for the problem.

David

you’re right, i had no idea how to fix it (the problem was that everything was being loaded to the same screen) but it turns out i did the translation wrong…fix:

self.bluebackground=self.loadegg(BACKGROUND[0],(0,20,0),(0,0,0),(20,0,15))
        self.bluecircle=self.loadegg(CIRCLE,(7,15,0),(0,0,0),(3,0,3),('circle','blue'))
        self.bluedrums=self.loadegg(DRUMS[0],(0,10,0),(0,0,0),(2,0,1.6),('drums','blue'))
...
self.redbackground=self.loadegg(BACKGROUND[1],(20,0,0),(-90,0,0),(20,0,15))
        self.redcircle=self.loadegg(CIRCLE,(15,-7,0),(-90,0,0),(3,0,3),('circle','red'))
        self.reddrums=self.loadegg(DRUMS[1],(0,10,0),(0,0,0),(2,0,1.6),('drums','red'))
        self.redSeq=Sequence()
...
self.greenbackground=self.loadegg(BACKGROUND[2],(-20,0,0),(90, 0, 0),(20,0,15))
        self.greencircle=self.loadegg(CIRCLE,(7,15,0),(0,0,0),(3,0,3),('circle','green'))
        self.greendrums=self.loadegg(DRUMS[2],(0,10,0),(0,0,0),(2,0,1.6),('drums','green'))
...
self.yellowbackground=self.loadegg(BACKGROUND[3],(0,-20,0),(180, 0, 0),(20,0,15))
        self.yellowcircle=self.loadegg(CIRCLE,(7,15,0),(0,0,0),(3,0,3),('circle','yellow'))
        self.yellowdrums=self.loadegg(DRUMS[3],(0,10,0),(0,0,0),(2,0,1.6),('drums','yellow'))
        self.yellowSeq=Sequence()

8)