I have modified the ShadowDemo a little to match my needs, here is what i got:
from pandac.PandaModules import * from direct.task import Task sc = None class ShadowCaster: texXSize = 1024 texYSize = 1024 def __init__(self, lightPath, objectPath, filmX, filmY): self.lightPath = lightPath self.objectPath = objectPath self.groundPath = None # Create an offscreen buffer to render the view of the avatar # into a texture. self.buffer = base.win.makeTextureBuffer( 'shadowBuffer', self.texXSize, self.texYSize) # The background of this buffer--and the border of the # texture--is pure white. clearColor = VBase4(1, 1, 1, 1) self.buffer.setClearColor(clearColor) self.tex = self.buffer.getTexture() self.tex.setBorderColor(clearColor) self.tex.setWrapU(Texture.WMBorderColor) self.tex.setWrapV(Texture.WMBorderColor) # Set up a display region on this buffer, and create a camera. dr = self.buffer.makeDisplayRegion() self.camera = Camera('shadowCamera') self.cameraPath = self.lightPath.attachNewNode(self.camera) self.camera.setScene(self.objectPath) dr.setCamera(self.cameraPath) # Use a temporary NodePath to define the initial state for the # camera. The initial state will render everything in a # flat-shaded gray, as if it were a shadow. initial = NodePath('initial') initial.setColor(0.75, 0.75, 0.75, 1, 1) initial.setTextureOff(2) initial.setLightOff(2) self.camera.setInitialState(initial.getState()) # Use an orthographic lens for this camera instead of the # usual perspective lens. An orthographic lens is better to # simulate sunlight, which is (almost) orthographic. We set # the film size large enough to render a typical avatar (but # not so large that we lose detail in the texture). self.lens = OrthographicLens() self.lens.setFilmSize(filmX, filmY) self.camera.setLens(self.lens) # Finally, we'll need a unique TextureStage to apply this # shadow texture to the world. self.stage = TextureStage('shadow') # Make sure the shadowing object doesn't get its own shadow # applied to it. self.objectPath.setTextureOff(self.stage) def setGround(self, groundPath): """ Specifies the part of the world that is to be considered the ground: this is the part onto which the rendered texture will be applied. """ if self.groundPath: self.groundPath.clearProjectTexture(self.stage) self.groundPath = groundPath self.groundPath.projectTexture(self.stage, self.tex, self.cameraPath) def clear(self): """ Undoes the effect of the ShadowCaster. """ if self.groundPath: self.groundPath.clearProjectTexture(self.stage) self.groundPath = None if self.lightPath: self.lightPath.detachNode() self.lightPath = None if self.cameraPath: self.cameraPath.detachNode() self.cameraPath = None self.camera = None self.lens = None if self.buffer: base.graphicsEngine.removeWindow(self.buffer) self.tex = None self.buffer = None def arbitraryShadow(node, groundPath): # Turn off the existing drop shadow, if any if hasattr(node, "dropShadow"): # stash it so that when the game hides and shows it, it will still be gone node.dropShadow.stash() # Set up a new node to hold the "light": this is an abitrary point # somewhere above the node, looking down, as if from the sun. objectPath = node shadowCamera = objectPath.attachNewNode('shadowCamera') lightPath = shadowCamera.attachNewNode('lightPath') # We can change this position at will to change the angle of the # sun. lightPath.setPos(0, 0, 30) # We need a task to keep the shadowCamera rotated in the same # direction relative to render (otherwise, the shadow seems to # rotate when you rotate your avatar, which is strange). We can't # just use a compass effect, since that doesn't work on cameras. def shadowCameraRotate(task, shadowCamera = shadowCamera): shadowCamera.setHpr(render, 0, 0, 0) lightPath.lookAt(shadowCamera, 0, 0, 0) return Task.cont taskMgr.remove('shadowCamera') taskMgr.add(shadowCameraRotate, 'shadowCamera') global sc if sc != None: sc.clear() sc = ShadowCaster(lightPath, objectPath, 30, 30) # Naively, just apply the shadow to everything in the world. It # would probably be better to use a little restraint. sc.setGround(groundPath) return sc
My problem is that sc is overwritten each time i call arbitraryShadow(), meaning that only one model is able to cast a shadow at a time.
It may be a cheap question, but I simply can’t think of a way to change that behavior to add shadows to my other models. I have approximately 30 models that need shadowing.
I’d also like to stick with that simple kind of shadowing because something more sophisticated would simply be too much.
thanks in advance for any help supplied.