DirectLights.py 3.8 KB

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