Light.cpp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. #include "Base.h"
  2. #include "Light.h"
  3. #include "Node.h"
  4. namespace gameplay
  5. {
  6. Light::Light(Light::Type type, const Vector3& color) :
  7. _type(type), _node(NULL)
  8. {
  9. _directional = new Directional(color);
  10. }
  11. Light::Light(Light::Type type, const Vector3& color, float range) :
  12. _type(type), _node(NULL)
  13. {
  14. _point = new Point(color, range);
  15. }
  16. Light::Light(Light::Type type, const Vector3& color, float range, float innerAngle, float outerAngle) :
  17. _type(type), _node(NULL)
  18. {
  19. _spot = new Spot(color, range, innerAngle, outerAngle);
  20. }
  21. Light::~Light()
  22. {
  23. switch (_type)
  24. {
  25. case DIRECTIONAL:
  26. SAFE_DELETE(_directional);
  27. break;
  28. case POINT:
  29. SAFE_DELETE(_point);
  30. break;
  31. case SPOT:
  32. SAFE_DELETE(_spot);
  33. break;
  34. default:
  35. GP_ERROR("Invalid light type (%d).", _type);
  36. break;
  37. }
  38. }
  39. Light* Light::createDirectional(const Vector3& color)
  40. {
  41. return new Light(DIRECTIONAL, color);
  42. }
  43. Light* Light::createPoint(const Vector3& color, float range)
  44. {
  45. return new Light(POINT, color, range);
  46. }
  47. Light* Light::createSpot(const Vector3& color, float range, float innerAngle, float outerAngle)
  48. {
  49. return new Light(SPOT, color, range, innerAngle, outerAngle);
  50. }
  51. Light::Type Light::getLightType() const
  52. {
  53. return _type;
  54. }
  55. Node* Light::getNode() const
  56. {
  57. return _node;
  58. }
  59. void Light::setNode(Node* node)
  60. {
  61. // Connect the new node.
  62. _node = node;
  63. }
  64. const Vector3& Light::getColor() const
  65. {
  66. switch (_type)
  67. {
  68. case DIRECTIONAL:
  69. GP_ASSERT(_directional);
  70. return _directional->color;
  71. case POINT:
  72. GP_ASSERT(_point);
  73. return _point->color;
  74. case SPOT:
  75. GP_ASSERT(_spot);
  76. return _spot->color;
  77. default:
  78. GP_ERROR("Unsupported light type (%d).", _type);
  79. return Vector3::zero();
  80. }
  81. }
  82. void Light::setColor(const Vector3& color)
  83. {
  84. switch (_type)
  85. {
  86. case DIRECTIONAL:
  87. GP_ASSERT(_directional);
  88. _directional->color = color;
  89. break;
  90. case POINT:
  91. GP_ASSERT(_point);
  92. _point->color = color;
  93. break;
  94. case SPOT:
  95. GP_ASSERT(_spot);
  96. _spot->color = color;
  97. break;
  98. default:
  99. GP_ERROR("Unsupported light type (%d).", _type);
  100. break;
  101. }
  102. }
  103. float Light::getRange() const
  104. {
  105. GP_ASSERT(_type != DIRECTIONAL);
  106. switch (_type)
  107. {
  108. case POINT:
  109. GP_ASSERT(_point);
  110. return _point->range;
  111. case SPOT:
  112. GP_ASSERT(_spot);
  113. return _spot->range;
  114. default:
  115. GP_ERROR("Unsupported light type (%d).", _type);
  116. return 0.0f;
  117. }
  118. }
  119. void Light::setRange(float range)
  120. {
  121. GP_ASSERT(_type != DIRECTIONAL);
  122. switch (_type)
  123. {
  124. case POINT:
  125. GP_ASSERT(_point);
  126. GP_ASSERT(range);
  127. _point->range = range;
  128. _point->rangeInverse = 1.0f / range;
  129. break;
  130. case SPOT:
  131. GP_ASSERT(_spot);
  132. GP_ASSERT(range);
  133. _spot->range = range;
  134. _spot->rangeInverse = 1.0f / range;
  135. break;
  136. default:
  137. GP_ERROR("Unsupported light type (%d).", _type);
  138. break;
  139. }
  140. }
  141. float Light::getRangeInverse() const
  142. {
  143. GP_ASSERT(_type != DIRECTIONAL);
  144. switch (_type)
  145. {
  146. case POINT:
  147. GP_ASSERT(_point);
  148. return _point->rangeInverse;
  149. case SPOT:
  150. GP_ASSERT(_spot);
  151. return _spot->rangeInverse;
  152. default:
  153. GP_ERROR("Unsupported light type (%d).", _type);
  154. return 0.0f;
  155. }
  156. }
  157. float Light::getInnerAngle() const
  158. {
  159. GP_ASSERT(_type == SPOT);
  160. return _spot->innerAngle;
  161. }
  162. void Light::setInnerAngle(float innerAngle)
  163. {
  164. GP_ASSERT(_type == SPOT);
  165. _spot->innerAngle = innerAngle;
  166. _spot->innerAngleCos = cos(innerAngle);
  167. }
  168. float Light::getOuterAngle() const
  169. {
  170. GP_ASSERT(_type == SPOT);
  171. return _spot->outerAngle;
  172. }
  173. void Light::setOuterAngle(float outerAngle)
  174. {
  175. GP_ASSERT(_type == SPOT);
  176. _spot->outerAngle = outerAngle;
  177. _spot->outerAngleCos = cos(outerAngle);
  178. }
  179. float Light::getInnerAngleCos() const
  180. {
  181. GP_ASSERT(_type == SPOT);
  182. return _spot->innerAngleCos;
  183. }
  184. float Light::getOuterAngleCos() const
  185. {
  186. GP_ASSERT(_type == SPOT);
  187. return _spot->outerAngleCos;
  188. }
  189. Light* Light::clone(NodeCloneContext &context) const
  190. {
  191. Light* lightClone = NULL;
  192. switch (_type)
  193. {
  194. case DIRECTIONAL:
  195. lightClone = createDirectional(getColor());
  196. break;
  197. case POINT:
  198. lightClone = createPoint(getColor(), getRange());
  199. break;
  200. case SPOT:
  201. lightClone = createSpot(getColor(), getRange(), getInnerAngle(), getOuterAngle());
  202. break;
  203. default:
  204. GP_ERROR("Unsupported light type (%d).", _type);
  205. return NULL;
  206. }
  207. GP_ASSERT(lightClone);
  208. if (Node* node = context.findClonedNode(getNode()))
  209. {
  210. lightClone->setNode(node);
  211. }
  212. return lightClone;
  213. }
  214. Light::Directional::Directional(const Vector3& color)
  215. : color(color)
  216. {
  217. }
  218. Light::Point::Point(const Vector3& color, float range)
  219. : color(color), range(range)
  220. {
  221. GP_ASSERT(range);
  222. rangeInverse = 1.0f / range;
  223. }
  224. Light::Spot::Spot(const Vector3& color, float range, float innerAngle, float outerAngle)
  225. : color(color), range(range), innerAngle(innerAngle), outerAngle(outerAngle)
  226. {
  227. GP_ASSERT(range);
  228. rangeInverse = 1.0f / range;
  229. innerAngleCos = cos(innerAngle);
  230. outerAngleCos = cos(outerAngle);
  231. }
  232. }