DirectLights.py 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. from panda3d.core import *
  2. from string import lower
  3. class DirectLight(NodePath):
  4. def __init__(self, light, parent):
  5. # Initialize the superclass
  6. NodePath.__init__(self)
  7. # Record light and name
  8. self.light = light
  9. # Attach node to self
  10. self.assign(parent.attachNewNode(self.light))
  11. def getName(self):
  12. return self.light.getName()
  13. def getLight(self):
  14. return self.light
  15. class DirectLights(NodePath):
  16. def __init__(self, parent = render):
  17. # Initialize the superclass
  18. NodePath.__init__(self)
  19. # Create a node for the lights
  20. self.assign(parent.attachNewNode('DIRECT Lights'))
  21. # Create a list of all active lights
  22. self.lightDict = {}
  23. # Counts of the various types of lights
  24. self.ambientCount = 0
  25. self.directionalCount = 0
  26. self.pointCount = 0
  27. self.spotCount = 0
  28. def __getitem__(self, name):
  29. return self.lightDict.get(name, None)
  30. def __len__(self):
  31. return len(self.lightDict)
  32. def delete(self, light):
  33. del self.lightDict[light.getName()]
  34. self.setOff(light)
  35. light.removeNode()
  36. def deleteAll(self):
  37. for light in self:
  38. self.delete(light)
  39. def asList(self):
  40. return [self[n] for n in self.getNameList()]
  41. def getNameList(self):
  42. # Return a sorted list of all lights in the light dict
  43. nameList = [x.getName() for x in self.lightDict.values()]
  44. nameList.sort()
  45. return nameList
  46. def create(self, type):
  47. type = type.lower()
  48. if type == 'ambient':
  49. self.ambientCount += 1
  50. light = AmbientLight('ambient-' + repr(self.ambientCount))
  51. light.setColor(VBase4(.3, .3, .3, 1))
  52. elif type == 'directional':
  53. self.directionalCount += 1
  54. light = DirectionalLight('directional-' + repr(self.directionalCount))
  55. light.setColor(VBase4(1))
  56. elif type == 'point':
  57. self.pointCount += 1
  58. light = PointLight('point-' + repr(self.pointCount))
  59. light.setColor(VBase4(1))
  60. elif type == 'spot':
  61. self.spotCount += 1
  62. light = Spotlight('spot-' + repr(self.spotCount))
  63. light.setColor(VBase4(1))
  64. light.setLens(PerspectiveLens())
  65. else:
  66. print 'Invalid light type'
  67. return None
  68. # Add the new light
  69. directLight = DirectLight(light, self)
  70. self.lightDict[directLight.getName()] = directLight
  71. # Turn it on as a default
  72. self.setOn(directLight)
  73. # Send an event to all watching objects
  74. messenger.send('DIRECT_addLight', [directLight])
  75. # Return the new light
  76. return directLight
  77. def createDefaultLights(self):
  78. self.create('ambient')
  79. self.create('directional')
  80. def allOn(self):
  81. """
  82. Turn on all DIRECT lights
  83. """
  84. for light in self.lightDict.values():
  85. self.setOn(light)
  86. # Make sure there is a default material
  87. render.setMaterial(Material())
  88. def allOff(self):
  89. """
  90. Turn off all DIRECT lights
  91. """
  92. for light in self.lightDict.values():
  93. self.setOff(light)
  94. def toggle(self):
  95. """
  96. Toggles light attribute, but doesn't toggle individual lights
  97. """
  98. if render.node().hasAttrib(LightAttrib.getClassType()):
  99. self.allOff()
  100. else:
  101. self.allOn()
  102. def setOn(self, directLight):
  103. """
  104. Turn on the given directLight
  105. """
  106. render.setLight(directLight)
  107. def setOff(self, directLight):
  108. """
  109. Turn off the given directLight
  110. """
  111. render.clearLight(directLight)