Geometry.cpp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. /**
  2. * Copyright (c) 2006-2013 LOVE Development Team
  3. *
  4. * This software is provided 'as-is', without any express or implied
  5. * warranty. In no event will the authors be held liable for any damages
  6. * arising from the use of this software.
  7. *
  8. * Permission is granted to anyone to use this software for any purpose,
  9. * including commercial applications, and to alter it and redistribute it
  10. * freely, subject to the following restrictions:
  11. *
  12. * 1. The origin of this software must not be misrepresented; you must not
  13. * claim that you wrote the original software. If you use this software
  14. * in a product, an acknowledgment in the product documentation would be
  15. * appreciated but is not required.
  16. * 2. Altered source versions must be plainly marked as such, and must not be
  17. * misrepresented as being the original software.
  18. * 3. This notice may not be removed or altered from any source distribution.
  19. **/
  20. #include "Geometry.h"
  21. #include "common/Exception.h"
  22. #include "common/Vector.h"
  23. #include "modules/math/MathModule.h"
  24. using love::math::Math;
  25. // STD
  26. #include <limits>
  27. #include <algorithm> // for std::swap()
  28. #include <cstring> // For memcpy
  29. namespace love
  30. {
  31. namespace graphics
  32. {
  33. Geometry::Geometry(const std::vector<vertex> &polygon, const std::vector<uint16> &elements, Geometry::DrawMode mode)
  34. : vertexArray(NULL)
  35. , vertexCount(polygon.size())
  36. , elementArray(NULL)
  37. , elementCount(elements.size())
  38. , x_min(std::numeric_limits<float>::max())
  39. , x_max(std::numeric_limits<float>::min())
  40. , y_min(std::numeric_limits<float>::max())
  41. , y_max(std::numeric_limits<float>::min())
  42. , vertexColors(false)
  43. , drawMode(mode)
  44. {
  45. for (size_t i = 0; i < elementCount; i++)
  46. {
  47. // All values in the element array need to be a valid vertex index.
  48. if (elements[i] >= vertexCount)
  49. throw love::Exception("Invalid vertex map value");
  50. }
  51. vertexArray = new vertex[vertexCount];
  52. for (size_t i = 0; i < vertexCount; ++i)
  53. {
  54. const vertex &v = polygon[i];
  55. vertexArray[i] = v;
  56. x_min = v.x < x_min ? v.x : x_min;
  57. x_max = v.x > x_max ? v.x : x_max;
  58. y_min = v.y < y_min ? v.y : y_min;
  59. y_max = v.y > y_max ? v.y : y_max;
  60. }
  61. if (elementCount > 0)
  62. {
  63. elementArray = new uint16[elementCount];
  64. memcpy(elementArray, &elements[0], elementCount * sizeof(uint16));
  65. }
  66. }
  67. Geometry::Geometry(float x, float y, float w, float h, float sw, float sh)
  68. : vertexArray(NULL)
  69. , vertexCount(4)
  70. , elementArray(NULL)
  71. , elementCount(0)
  72. , x_min(0)
  73. , x_max(w)
  74. , y_min(0)
  75. , y_max(h)
  76. , vertexColors(false)
  77. , drawMode(DRAW_MODE_FAN)
  78. {
  79. vertexArray = new vertex[4];
  80. float s0 = x/sw, s1 = (x+w)/sw, t0 = y/sh, t1 = (y+h)/sh;
  81. vertexArray[0] = vertex(0,0, s0,t0);
  82. vertexArray[1] = vertex(w,0, s1,t0);
  83. vertexArray[2] = vertex(w,h, s1,t1);
  84. vertexArray[3] = vertex(0,h, s0,t1);
  85. }
  86. Geometry::Geometry(const Geometry &other)
  87. : vertexCount(other.vertexCount)
  88. , elementCount(other.elementCount)
  89. , x_min(other.x_min)
  90. , x_max(other.x_max)
  91. , y_min(other.y_min)
  92. , y_max(other.y_max)
  93. , vertexColors(other.vertexColors)
  94. , drawMode(other.drawMode)
  95. {
  96. vertexArray = new vertex[vertexCount];
  97. memcpy(vertexArray, other.vertexArray, vertexCount * sizeof(vertex));
  98. if (elementCount > 0)
  99. {
  100. elementArray = new uint16[elementCount];
  101. memcpy(elementArray, other.elementArray, elementCount * sizeof(uint16));
  102. }
  103. }
  104. Geometry &Geometry::operator=(const Geometry &other)
  105. {
  106. if (this != &other)
  107. {
  108. Geometry temp(other);
  109. std::swap(vertexArray, temp.vertexArray);
  110. std::swap(elementArray, temp.elementArray);
  111. vertexCount = temp.vertexCount;
  112. elementCount = temp.elementCount;
  113. x_min = temp.x_min;
  114. x_max = temp.x_max;
  115. y_min = temp.y_min;
  116. y_max = temp.y_max;
  117. vertexColors = other.vertexColors;
  118. drawMode = other.drawMode;
  119. }
  120. return *this;
  121. }
  122. Geometry::~Geometry()
  123. {
  124. delete[] vertexArray;
  125. delete[] elementArray;
  126. }
  127. const vertex &Geometry::getVertex(size_t i) const
  128. {
  129. if (i >= vertexCount)
  130. throw Exception("Invalid vertex index");
  131. return vertexArray[i];
  132. }
  133. void Geometry::setVertex(size_t i, const vertex &v)
  134. {
  135. if (i >= vertexCount)
  136. throw Exception("Invalid vertex index");
  137. if (vertexArray[i].x != v.x || vertexArray[i].y != v.y)
  138. {
  139. x_min = v.x < x_min ? v.x : x_min;
  140. x_max = v.x > x_max ? v.x : x_max;
  141. y_min = v.y < y_min ? v.y : y_min;
  142. y_max = v.y > y_max ? v.y : y_max;
  143. }
  144. vertexArray[i] = v;
  145. }
  146. void Geometry::flip(bool x, bool y)
  147. {
  148. for (size_t i = 0; i < vertexCount; ++i)
  149. {
  150. vertex &v = vertexArray[i];
  151. if (x) v.x = x_max + x_min - v.x;
  152. if (y) v.y = y_max + y_min - v.y;
  153. }
  154. }
  155. void Geometry::setElementArray(const uint16 *elements, size_t count)
  156. {
  157. if (count == 0 || elements == NULL)
  158. {
  159. delete[] elementArray;
  160. elementArray = NULL;
  161. elementCount = 0;
  162. return;
  163. }
  164. for (size_t i = 0; i < count; i++)
  165. {
  166. if (elements[i] >= vertexCount)
  167. throw love::Exception("Invalid vertex map value");
  168. }
  169. if (count > elementCount)
  170. {
  171. delete[] elementArray;
  172. elementArray = new uint16[count];
  173. }
  174. elementCount = count;
  175. memcpy(elementArray, elements, elementCount * sizeof(uint16));
  176. }
  177. void Geometry::setVertexColors(bool on)
  178. {
  179. vertexColors = on;
  180. }
  181. bool Geometry::getConstant(const char *in, Geometry::DrawMode &out)
  182. {
  183. return drawModes.find(in, out);
  184. }
  185. bool Geometry::getConstant(Geometry::DrawMode in, const char *&out)
  186. {
  187. return drawModes.find(in, out);
  188. }
  189. StringMap<Geometry::DrawMode, Geometry::DRAW_MODE_MAX_ENUM>::Entry Geometry::drawModeEntries[] =
  190. {
  191. {"fan", Geometry::DRAW_MODE_FAN},
  192. {"strip", Geometry::DRAW_MODE_STRIP},
  193. {"triangles", Geometry::DRAW_MODE_TRIANGLES}
  194. };
  195. StringMap<Geometry::DrawMode, Geometry::DRAW_MODE_MAX_ENUM> Geometry::drawModes(Geometry::drawModeEntries, sizeof(Geometry::drawModeEntries));
  196. } // graphics
  197. } // love