OnscreenImage.py 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. """OnscreenImage module: contains the OnscreenImage class.
  2. See the :ref:`onscreenimage` page in the programming manual for explanation of
  3. this class.
  4. """
  5. __all__ = ['OnscreenImage']
  6. from panda3d.core import *
  7. from direct.showbase.DirectObject import DirectObject
  8. import sys
  9. if sys.version_info >= (3, 0):
  10. stringType = str
  11. else:
  12. stringType = basestring
  13. class OnscreenImage(DirectObject, NodePath):
  14. def __init__(self, image = None,
  15. pos = None,
  16. hpr = None,
  17. scale = None,
  18. color = None,
  19. parent = None,
  20. sort = 0):
  21. """
  22. Make a image node from string or a `~panda3d.core.NodePath`, put
  23. it into the 2-D scene graph and set it up with all the indicated
  24. parameters.
  25. Parameters:
  26. image: the actual geometry to display or a file name.
  27. This may be omitted and specified later via setImage()
  28. if you don't have it available.
  29. pos: the x, y, z position of the geometry on the screen.
  30. This maybe a 3-tuple of floats or a vector.
  31. y should be zero
  32. hpr: the h, p, r of the geometry on the screen.
  33. This maybe a 3-tuple of floats or a vector.
  34. scale: the size of the geometry. This may either be a single
  35. float, a 3-tuple of floats, or a vector, specifying a
  36. different x, y, z scale. y should be 1
  37. color: the (r, g, b, a) color of the geometry. This is
  38. normally a 4-tuple of floats or ints.
  39. parent: the NodePath to parent the geometry to initially.
  40. """
  41. # We ARE a node path. Initially, we're an empty node path.
  42. NodePath.__init__(self)
  43. if parent is None:
  44. from direct.showbase import ShowBaseGlobal
  45. parent = ShowBaseGlobal.aspect2d
  46. self.setImage(image, parent = parent, sort = sort)
  47. # Adjust pose
  48. # Set pos
  49. if (isinstance(pos, tuple) or
  50. isinstance(pos, list)):
  51. self.setPos(*pos)
  52. elif isinstance(pos, VBase3):
  53. self.setPos(pos)
  54. # Hpr
  55. if (isinstance(hpr, tuple) or
  56. isinstance(hpr, list)):
  57. self.setHpr(*hpr)
  58. elif isinstance(hpr, VBase3):
  59. self.setHpr(hpr)
  60. # Scale
  61. if (isinstance(scale, tuple) or
  62. isinstance(scale, list)):
  63. self.setScale(*scale)
  64. elif isinstance(scale, VBase3):
  65. self.setScale(scale)
  66. elif (isinstance(scale, float) or
  67. isinstance(scale, int)):
  68. self.setScale(scale)
  69. # Set color
  70. if color:
  71. # Set color, if specified
  72. self.setColor(color[0], color[1], color[2], color[3])
  73. def setImage(self, image,
  74. parent = NodePath(),
  75. transform = None,
  76. sort = 0):
  77. # Get the original parent, transform, and sort, if any, so we can
  78. # preserve them across this call.
  79. if not self.isEmpty():
  80. parent = self.getParent()
  81. if transform == None:
  82. # If we're replacing a previous image, we throw away
  83. # the new image's transform in favor of the original
  84. # image's transform.
  85. transform = self.getTransform()
  86. sort = self.getSort()
  87. self.removeNode()
  88. # Assign geometry
  89. if isinstance(image, NodePath):
  90. self.assign(image.copyTo(parent, sort))
  91. elif isinstance(image, stringType) or \
  92. isinstance(image, Texture):
  93. if isinstance(image, Texture):
  94. # It's a Texture
  95. tex = image
  96. else:
  97. # It's a Texture file name
  98. tex = TexturePool.loadTexture(image)
  99. if not tex:
  100. raise IOError('Could not load texture: %s' % (image))
  101. cm = CardMaker('OnscreenImage')
  102. cm.setFrame(-1, 1, -1, 1)
  103. self.assign(parent.attachNewNode(cm.generate(), sort))
  104. self.setTexture(tex)
  105. elif type(image) == type(()):
  106. # Assume its a file+node name, extract texture from node
  107. model = loader.loadModel(image[0])
  108. if model:
  109. node = model.find(image[1])
  110. if node:
  111. self.assign(node.copyTo(parent, sort))
  112. else:
  113. print('OnscreenImage: node %s not found' % image[1])
  114. else:
  115. print('OnscreenImage: model %s not found' % image[0])
  116. if transform and not self.isEmpty():
  117. self.setTransform(transform)
  118. def getImage(self):
  119. return self
  120. def configure(self, option=None, **kw):
  121. for option, value in kw.items():
  122. # Use option string to access setter function
  123. try:
  124. setter = getattr(self, 'set' + option[0].upper() + option[1:])
  125. if (((setter == self.setPos) or
  126. (setter == self.setHpr) or
  127. (setter == self.setScale)) and
  128. (isinstance(value, tuple) or
  129. isinstance(value, list))):
  130. setter(*value)
  131. else:
  132. setter(value)
  133. except AttributeError:
  134. print('OnscreenImage.configure: invalid option: %s' % option)
  135. # Allow index style references
  136. def __setitem__(self, key, value):
  137. self.configure(*(), **{key: value})
  138. def cget(self, option):
  139. # Get current configuration setting.
  140. # This is for compatibility with DirectGui functions
  141. getter = getattr(self, 'get' + option[0].upper() + option[1:])
  142. return getter()
  143. # Allow index style refererences
  144. __getitem__ = cget
  145. def destroy(self):
  146. self.removeNode()