Model always on screen

Seems pretty basic, I just want to know how to make a model always appear on the camera, like a weapon in an FPS. Thanks.

Short answer:

model.reparentTo(base.camera)
model.setPos(0, 30, -5)  # or whatever position is appropriate

David

Thanks a ton

Hate to double post, but the model basically keeps clipping through the terrain and other objects. Is there any way to remove this?

Sure, there are lots of approaches. One easy (and hacky) thing to do is just make the model really tiny, but really close to your face, so it’s still the same size onscreen.

The next thing to do is to make the model render at the end, and turn off depth testing:

model.setBin('fixed', 0)
model.setDepthTest(False)

But this will only work well if the model is totally convex and has no self-occluding faces. This is unlikely for a gun model, so it will probably look weird if you turn off depth testing.

So, the next approach is to render the model in its own DisplayRegion, which is drawn on top of the normal 3-D screen. This means it will have its own camera too, and its own scene graph, instead of render. This is a bit more complicated, but it would look something like this:

self.gunRender = NodePath('gunRender')
self.gunCam = base.makeCamera(base.win, sort = 5, clearDepth = True)
self.gunCam.reparentTo(self.gunRender)
self.gunModel = loader.loadModel('gunModel.egg')
self.gunModel.reparentTo(self.gunCam)
self.gunModel.setPos(0, 30, -5)

Further documentation about DisplayRegions and such can be found in the manual.

David

Thanks! Sadly however, using the Display Region means the model is unaffected by lighting since its in a different scene graph :confused:

You can just apply the same lights to the gunRender scene graph. Or, you can keep it in the main scene graph (don’t reparent gunCam), but hide everything in the scene to that camera using per-camera show/hide.

David

Hide everything in the scene?

First, set a unique bit for each camera:

MainCamMask = BitMask32.bit(0)
GunCamMask = BitMask32.bit(1)
base.cam.node().setCameraMask(MainCamMask)
gunCamera.node().setCameraMask(GunCamMask)

Then you can hide and show things on a per-camera basis:

gunModel.hide(MainCamMask) # invisible to main camera
render.hide(GunCamMask) # invisible to gun camera
gunModel.showThrough(GunCamMask) # visible to gun camera in spite of above

With this, you can omit the gunCamera.reparentTo(gunRender), and just leave gunCamera in the main scene instead (parented to base.camera by default), and it will render only the gunModel, while the main camera will render everything else.

David

Great stuff man, it works great.

Ack, another doublepost.
Just have to ask, how do you enable shaders with the second camera? If I use CommonFilters, only the gun model is rendered on the screen, and the terrain disappears.