mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 02:42:49 -04:00
144 lines
4.5 KiB
Python
144 lines
4.5 KiB
Python
from PandaObject import *
|
|
from DirectGeometry import *
|
|
from string import lower
|
|
import UsePgraph
|
|
|
|
class DirectLight(NodePath):
|
|
def __init__(self, light, parent):
|
|
# Initialize the superclass
|
|
NodePath.__init__(self)
|
|
# Record light and name
|
|
self.light = light
|
|
self.name = light.getName()
|
|
|
|
# Upcast the light object to its node base pointer
|
|
if isinstance(light, Spotlight):
|
|
node = light.upcastToLensNode()
|
|
else:
|
|
node = light.upcastToPandaNode()
|
|
|
|
# Attach node to self
|
|
if UsePgraph.use:
|
|
self.assign(parent.attachNewNode(node))
|
|
else:
|
|
# Old scene graph no longer has lights.
|
|
pass
|
|
|
|
def getName(self):
|
|
return self.name
|
|
def getLight(self):
|
|
return self.light
|
|
|
|
class DirectLights(NodePath):
|
|
def __init__(self, parent = None):
|
|
# Initialize the superclass
|
|
NodePath.__init__(self)
|
|
# Use direct.group as default parent
|
|
if parent == None:
|
|
parent = direct.group
|
|
# Create a node for the lights
|
|
self.assign(parent.attachNewNode('DIRECT Lights'))
|
|
# Create a light attrib
|
|
self.la = LightAttrib.makeAllOff()
|
|
# Create a list of all active lights
|
|
self.lightDict = {}
|
|
# Counts of the various types of lights
|
|
self.ambientCount = 0
|
|
self.directionalCount = 0
|
|
self.pointCount = 0
|
|
self.spotCount = 0
|
|
|
|
def __getitem__(self, name):
|
|
return self.lightDict.get(name, None)
|
|
|
|
def __len__(self):
|
|
return len(self.lightDict)
|
|
|
|
def delete(self, light):
|
|
del self.lightDict[light.getName()]
|
|
self.setOff(light)
|
|
light.removeNode()
|
|
|
|
def deleteAll(self):
|
|
for light in self.asList():
|
|
self.delete(light)
|
|
|
|
def asList(self):
|
|
return map(lambda n, s=self: s[n], self.getNameList())
|
|
|
|
def getNameList(self):
|
|
# Return a sorted list of all lights in the light dict
|
|
nameList = map(lambda x: x.getName(), self.lightDict.values())
|
|
nameList.sort()
|
|
return nameList
|
|
|
|
def create(self, type):
|
|
type = type.lower()
|
|
if type == 'ambient':
|
|
self.ambientCount += 1
|
|
light = AmbientLight('ambient-' + `self.ambientCount`)
|
|
light.setColor(VBase4(.3,.3,.3,1))
|
|
elif type == 'directional':
|
|
self.directionalCount += 1
|
|
light = DirectionalLight('directional-' + `self.directionalCount`)
|
|
light.setColor(VBase4(1))
|
|
elif type == 'point':
|
|
self.pointCount += 1
|
|
light = PointLight('point-' + `self.pointCount`)
|
|
light.setColor(VBase4(1))
|
|
elif type == 'spot':
|
|
self.spotCount += 1
|
|
light = Spotlight('spot-' + `self.spotCount`)
|
|
light.setColor(VBase4(1))
|
|
else:
|
|
print 'Invalid light type'
|
|
return None
|
|
# Add the new light
|
|
directLight = DirectLight(light,self)
|
|
self.lightDict[directLight.getName()] = directLight
|
|
# Turn it on as a default
|
|
self.setOn(directLight)
|
|
# Send an event to all watching objects
|
|
messenger.send('DIRECT_addLight', [directLight])
|
|
# Return the new light
|
|
return directLight
|
|
|
|
def createDefaultLights(self):
|
|
self.create('ambient')
|
|
self.create('directional')
|
|
|
|
def allOn(self):
|
|
""" Turn on all DIRECT lights """
|
|
if UsePgraph.use:
|
|
# new-style scene graph
|
|
render.node().setAttrib(self.la)
|
|
# Make sure there is a default material
|
|
render.setMaterial(Material())
|
|
|
|
def allOff(self):
|
|
""" Turn off all DIRECT lights """
|
|
if UsePgraph.use:
|
|
# new-style scene graph
|
|
render.node().clearAttrib(LightAttrib.getClassType())
|
|
|
|
def toggle(self):
|
|
""" Toggles light attribute, but doesn't toggle individual lights """
|
|
if render.node().hasAttrib(LightAttrib.getClassType()):
|
|
self.allOff()
|
|
else:
|
|
self.allOn()
|
|
|
|
def setOn(self, directLight):
|
|
""" setOn(directLight) """
|
|
self.la = self.la.addLight(directLight.getLight())
|
|
if render.node().hasAttrib(LightAttrib.getClassType()):
|
|
render.node().setAttrib(self.la)
|
|
|
|
def setOff(self, directLight):
|
|
""" setOff(directLight)"""
|
|
self.la = self.la.removeLight(directLight.getLight())
|
|
if render.node().hasAttrib(LightAttrib.getClassType()):
|
|
render.node().setAttrib(self.la)
|
|
|
|
|