material.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. from .. import constants, logger
  2. from . import base_classes, utilities, api
  3. class Material(base_classes.BaseNode):
  4. """Class that wraps material nodes"""
  5. def __init__(self, node, parent):
  6. logger.debug("Material().__init__(%s)", node)
  7. base_classes.BaseNode.__init__(self, node, parent,
  8. constants.MATERIAL)
  9. self._common_attributes()
  10. if self[constants.TYPE] == constants.THREE_PHONG:
  11. self._phong_attributes()
  12. textures = self.parent.options.get(constants.MAPS)
  13. if textures:
  14. self._update_maps()
  15. skinning = self.parent.options.get(constants.SKINNING)
  16. if skinning:
  17. self[constants.SKINNING] = True
  18. def _common_attributes(self):
  19. """Parse the common material attributes"""
  20. logger.debug('Material()._common_attributes()')
  21. dispatch = {
  22. constants.PHONG: constants.THREE_PHONG,
  23. constants.LAMBERT: constants.THREE_LAMBERT,
  24. constants.BASIC: constants.THREE_BASIC
  25. }
  26. shader_type = api.material.type(self.node)
  27. self[constants.TYPE] = dispatch[shader_type]
  28. diffuse = api.material.diffuse_color(self.node)
  29. self[constants.COLOR] = utilities.rgb2int(diffuse)
  30. if self[constants.TYPE] != constants.THREE_BASIC:
  31. emissive = api.material.emissive_color(self.node)
  32. self[constants.EMISSIVE] = utilities.rgb2int(emissive)
  33. vertex_color = api.material.use_vertex_colors(self.node)
  34. if vertex_color:
  35. self[constants.VERTEX_COLORS] = constants.VERTEX_COLORS_ON
  36. else:
  37. self[constants.VERTEX_COLORS] = constants.VERTEX_COLORS_OFF
  38. self[constants.BLENDING] = api.material.blending(self.node)
  39. if api.material.transparent(self.node):
  40. self[constants.TRANSPARENT] = True
  41. self[constants.OPACITY] = api.material.opacity(self.node)
  42. if api.material.double_sided(self.node):
  43. self[constants.SIDE] = constants.SIDE_DOUBLE
  44. self[constants.DEPTH_TEST] = api.material.depth_test(self.node)
  45. self[constants.DEPTH_WRITE] = api.material.depth_write(self.node)
  46. def _phong_attributes(self):
  47. """Parse phong specific attributes"""
  48. logger.debug("Material()._phong_attributes()")
  49. specular = api.material.specular_color(self.node)
  50. self[constants.SPECULAR] = utilities.rgb2int(specular)
  51. self[constants.SHININESS] = api.material.specular_coef(self.node)
  52. def _update_maps(self):
  53. """Parses maps/textures and updates the textures array
  54. with any new nodes found.
  55. """
  56. logger.debug("Material()._update_maps()")
  57. mapping = (
  58. (api.material.diffuse_map, constants.MAP),
  59. (api.material.specular_map, constants.SPECULAR_MAP),
  60. (api.material.light_map, constants.LIGHT_MAP)
  61. )
  62. for func, key in mapping:
  63. map_node = func(self.node)
  64. if map_node:
  65. logger.info('Found map node %s for %s', map_node, key)
  66. tex_inst = self.scene.texture(map_node.name)
  67. self[key] = tex_inst[constants.UUID]
  68. if self[constants.TYPE] == constants.THREE_PHONG:
  69. mapping = (
  70. (api.material.bump_map, constants.BUMP_MAP,
  71. constants.BUMP_SCALE, api.material.bump_scale),
  72. (api.material.normal_map, constants.NORMAL_MAP,
  73. constants.NORMAL_SCALE, api.material.normal_scale)
  74. )
  75. for func, map_key, scale_key, scale_func in mapping:
  76. map_node = func(self.node)
  77. if not map_node:
  78. continue
  79. logger.info("Found map node %s for %s", map_node, map_key)
  80. tex_inst = self.scene.texture(map_node.name)
  81. self[map_key] = tex_inst[constants.UUID]
  82. self[scale_key] = scale_func(self.node)