cameraMask and setColorScale

Hi again,

I was trying to get an object in the world that is viewed by two cameras to be only rendered by one. Looking in the reference, I found the Camera.setCameraMask() function, but I could not find a way to tell the node to be of this mask…

Basically I would like two cameras: one renders everything, and another renders everything except for one or two things…

Please Help, and thanks!

nodePath.hide(mask) will hide the node from any cameras with the specified mask. There is also nodePath.show(mask) and nodePath.isHidden(mask).

David

Thanks, drwr.

Also, (although completely unrelated), how do you do a nodepath.setColorScale that is not relative to the parent’s?

If you set a higher override on the colorScale node, it will replace its parent’s color scale, rather than multiplying it. Something like:

nodePath.setColorScale(r, g, b, a, 1)

David

Sorry, but I can’t get the nodepath.show(mask) to work…
here’s a simple version:

import direct.directbase.DirectStart
from pandac.PandaModules import *

def createSprite():
   vdata = GeomVertexData('', GeomVertexFormat.getV3t2(), Geom.UHStatic)
   vertex = GeomVertexWriter(vdata, 'vertex')
   uv = GeomVertexWriter(vdata, 'texcoord')
   prim = GeomTriangles(Geom.UHStatic)
   
   vertex.addData3f(0, 0, 1)
   vertex.addData3f(0, 0, 0)
   vertex.addData3f(1, 0, 0)
   vertex.addData3f(1, 0, 1)
   uv.addData2f(0,1)
   uv.addData2f(0,0)
   uv.addData2f(1,0)
   uv.addData2f(1,1)
   
   prim.addVertices(3,2,0)
   prim.addVertices(1,0,2)
   prim.closePrimitive()
   
   geom = Geom(vdata)
   geom.addPrimitive(prim)
   nodepath = NodePath(GeomNode('gnode'))
   nodepath.node().addGeom(geom)

   return nodepath


buffer = base.win.makeTextureBuffer('Camera', 256, 256)
buffer.setClearColor(Vec4(0,0,0,1))

camera = base.makeCamera(buffer)
camera.reparentTo(render)

pic = createSprite()
pic.setScale(.5,1,.5)
pic.reparentTo(aspect2d)
pic.setPos(-1.33,0,.5)
pic.setTexture(buffer.getTexture())

m = base.cam.node().getCameraMask()
m.clearBit(7)
camera.node().setCameraMask(m)

smiley = loader.loadModel('smiley')
smiley.setPos(0,10,0)
smiley.reparentTo(render)
smiley.show(BitMask32.bit(7))   #putting smiley.hide() right before causes neither camera to render smiley??? is this doing anything?

run()

You missed a couple of small points.

(1) You should assign just one bit, a different bit, to each camera. Right now you have all bits on for base.cam, and all bits except one for your new camera. That’s confusing.

(2) nodePath.hide() is an overall operation. It always hides things from all cameras, regardless of their bitmasks. This is different from nodePath.hide(mask), which only hides things from the named camera. Note that nodePath.show(mask) does not counteract the effect of nodePath.hide()! The only thing that undoes an overall hide() is an overall show() (or an overall showThrough(), if you must).

Try code something more like this:

baseCamMask = BitMask32.bit(0)
newCamMask = BitMask32.bit(1)

base.cam.node().setCameraMask(baseCamMask)
camera.node().setCameraMask(newCamMask)

smiley = loader.loadModel('smiley.egg')
smiley.setPos(0,10,0)
smiley.reparentTo(render)
smiley.hide(baseCamMask)

Don’t call smiley.hide(). You can make smiley visible or invisible in each camera by calling smiley.hide(baseCamMask)/smiley.show(baseCamMask) or smiley.hide(newCamMask)/smiley.show(newCamMask).

If you really want to hide smiley for all cameras at once, and then show him one at a time in each camera, you could do smiley.hide(BitMask32.allOn()). This means “hide smiley for all camera bits” which is a different thing than “hide smiley overall”, because a later smiley.show(camMask) will then show smiley again for that camera.

David

Thanks, David (sorry about that…).

Is there any reason why a call to Nodepath.hide() is different from Nodepath.hide(Bitmask32.allOn())? This just seems confusing, as they do the same thing, but if you want to utilize camera masks halfway through a project you have to go back and change all the hides/shows…

not a big deal now that I know, but maybe a manual page on hiding/showing or as part of some other page (maybe in the camera stuff?)

They don’t really do the same thing. hide() is meant to hide an object globally. Presumably, you do this when you want to take the object out of the scene or something. It always does this, whether or not you are using camera masks.

On the other hand, hide(mask) hides an object only from the named camera, but not globally. Not the same thing at all.

It’s true if you’ve already written a program with no intention of using camera masks, and then you go back and decide to use camera masks, you have to retrofit. But you’d have to do that anyway, and decide on a per-call basis whether each hide() is meant to hide the object globally, or only for a certain set of cameras.

A manual page all about this topic would be a welcome addition.

David

added it to the hide/show part of the common state changes page.