|
@@ -20,6 +20,7 @@
|
|
|
|
|
|
#include "Geometry.h"
|
|
#include "Geometry.h"
|
|
#include "common/Exception.h"
|
|
#include "common/Exception.h"
|
|
|
|
+#include "common/Vector.h"
|
|
#include "modules/math/MathModule.h"
|
|
#include "modules/math/MathModule.h"
|
|
|
|
|
|
using love::math::Math;
|
|
using love::math::Math;
|
|
@@ -34,49 +35,49 @@ namespace love
|
|
namespace graphics
|
|
namespace graphics
|
|
{
|
|
{
|
|
|
|
|
|
-
|
|
|
|
-Geometry::Geometry(const std::vector<vertex> &p)
|
|
|
|
- : polygon(p)
|
|
|
|
- , vertexArray(NULL)
|
|
|
|
|
|
+Geometry::Geometry(const std::vector<vertex> &polygon)
|
|
|
|
+ : vertexArray(NULL)
|
|
, x_min(std::numeric_limits<float>::max())
|
|
, x_min(std::numeric_limits<float>::max())
|
|
, x_max(std::numeric_limits<float>::min())
|
|
, x_max(std::numeric_limits<float>::min())
|
|
, y_min(std::numeric_limits<float>::max())
|
|
, y_min(std::numeric_limits<float>::max())
|
|
, y_max(std::numeric_limits<float>::min())
|
|
, y_max(std::numeric_limits<float>::min())
|
|
, vertexColors(false)
|
|
, vertexColors(false)
|
|
{
|
|
{
|
|
- for (size_t i = 0; i < polygon.size(); ++i)
|
|
|
|
|
|
+ if (!Math::instance.isConvex(polygon))
|
|
|
|
+ throw love::Exception("Geometry must be convex");
|
|
|
|
+
|
|
|
|
+ vertexCount = polygon.size();
|
|
|
|
+ vertexArray = new vertex[vertexCount];
|
|
|
|
+ for (size_t i = 0; i < vertexCount; ++i)
|
|
{
|
|
{
|
|
const vertex &v = polygon[i];
|
|
const vertex &v = polygon[i];
|
|
|
|
+ vertexArray[i] = v;
|
|
x_min = v.x < x_min ? v.x : x_min;
|
|
x_min = v.x < x_min ? v.x : x_min;
|
|
x_max = v.x > x_max ? v.x : x_max;
|
|
x_max = v.x > x_max ? v.x : x_max;
|
|
y_min = v.y < y_min ? v.y : y_min;
|
|
y_min = v.y < y_min ? v.y : y_min;
|
|
y_max = v.y > y_max ? v.y : y_max;
|
|
y_max = v.y > y_max ? v.y : y_max;
|
|
}
|
|
}
|
|
-
|
|
|
|
- triangulate();
|
|
|
|
}
|
|
}
|
|
|
|
|
|
Geometry::Geometry(float x, float y, float w, float h, float sw, float sh)
|
|
Geometry::Geometry(float x, float y, float w, float h, float sw, float sh)
|
|
: vertexArray(NULL)
|
|
: vertexArray(NULL)
|
|
|
|
+ , vertexCount(4)
|
|
, x_min(x)
|
|
, x_min(x)
|
|
, x_max(x+w)
|
|
, x_max(x+w)
|
|
, y_min(y)
|
|
, y_min(y)
|
|
, y_max(y+h)
|
|
, y_max(y+h)
|
|
, vertexColors(false)
|
|
, vertexColors(false)
|
|
{
|
|
{
|
|
|
|
+ vertexArray = new vertex[4];
|
|
float s0 = x/sw, s1 = (x+w)/sw, t0 = y/sh, t1 = (y+h)/sh;
|
|
float s0 = x/sw, s1 = (x+w)/sw, t0 = y/sh, t1 = (y+h)/sh;
|
|
- polygon.resize(4);
|
|
|
|
- polygon[0] = vertex(0,0, s0,t0);
|
|
|
|
- polygon[1] = vertex(w,0, s1,t0);
|
|
|
|
- polygon[2] = vertex(w,h, s1,t1);
|
|
|
|
- polygon[3] = vertex(0,h, s0,t1);
|
|
|
|
-
|
|
|
|
- triangulate();
|
|
|
|
|
|
+ vertexArray[0] = vertex(0,0, s0,t0);
|
|
|
|
+ vertexArray[1] = vertex(w,0, s1,t0);
|
|
|
|
+ vertexArray[2] = vertex(w,h, s1,t1);
|
|
|
|
+ vertexArray[3] = vertex(0,h, s0,t1);
|
|
}
|
|
}
|
|
|
|
|
|
Geometry::Geometry(const Geometry &other)
|
|
Geometry::Geometry(const Geometry &other)
|
|
- : polygon(other.polygon)
|
|
|
|
- , vertexCount(other.vertexCount)
|
|
|
|
|
|
+ : vertexCount(other.vertexCount)
|
|
, x_min(other.x_min)
|
|
, x_min(other.x_min)
|
|
, x_max(other.x_max)
|
|
, x_max(other.x_max)
|
|
, y_min(other.y_min)
|
|
, y_min(other.y_min)
|
|
@@ -92,7 +93,6 @@ Geometry &Geometry::operator=(const Geometry &other)
|
|
if (this != &other)
|
|
if (this != &other)
|
|
{
|
|
{
|
|
Geometry temp(other);
|
|
Geometry temp(other);
|
|
- std::swap(polygon, temp.polygon);
|
|
|
|
std::swap(vertexArray, temp.vertexArray);
|
|
std::swap(vertexArray, temp.vertexArray);
|
|
|
|
|
|
vertexCount = temp.vertexCount;
|
|
vertexCount = temp.vertexCount;
|
|
@@ -117,41 +117,41 @@ Geometry::~Geometry()
|
|
|
|
|
|
const vertex &Geometry::getVertex(size_t i) const
|
|
const vertex &Geometry::getVertex(size_t i) const
|
|
{
|
|
{
|
|
- if (i >= polygon.size())
|
|
|
|
|
|
+ if (i >= vertexCount)
|
|
throw Exception("Invalid vertex index");
|
|
throw Exception("Invalid vertex index");
|
|
- return polygon[i];
|
|
|
|
|
|
+ return vertexArray[i];
|
|
}
|
|
}
|
|
|
|
|
|
void Geometry::setVertex(size_t i, const vertex &v)
|
|
void Geometry::setVertex(size_t i, const vertex &v)
|
|
{
|
|
{
|
|
- if (i >= polygon.size())
|
|
|
|
|
|
+ if (i >= vertexCount)
|
|
throw Exception("Invalid vertex index");
|
|
throw Exception("Invalid vertex index");
|
|
|
|
|
|
- float oldx = polygon[i].x;
|
|
|
|
- float oldy = polygon[i].y;
|
|
|
|
|
|
+ love::Vector p(vertexArray[i].x, vertexArray[i].y);
|
|
|
|
|
|
- polygon[i] = v;
|
|
|
|
-
|
|
|
|
- if (oldx != v.x || oldy != v.y)
|
|
|
|
|
|
+ if (p.x != v.x || p.y != v.y)
|
|
{
|
|
{
|
|
|
|
+ size_t j = (i+1) % vertexCount, k = (i+2) % vertexCount;
|
|
|
|
+ Vector q(vertexArray[j].x, vertexArray[j].y);
|
|
|
|
+ Vector r(vertexArray[k].x, vertexArray[k].y);
|
|
|
|
+ Vector p_new(v.x, v.y);
|
|
|
|
+
|
|
|
|
+ float winding_old = (p-q) ^ (q-r);
|
|
|
|
+ float winding_new = (p_new-q) ^ (q-r);
|
|
|
|
+ if (winding_old * winding_new < 0)
|
|
|
|
+ throw Exception("Invalid vertex position: Makes geometry concave.");
|
|
|
|
+
|
|
x_min = v.x < x_min ? v.x : x_min;
|
|
x_min = v.x < x_min ? v.x : x_min;
|
|
x_max = v.x > x_max ? v.x : x_max;
|
|
x_max = v.x > x_max ? v.x : x_max;
|
|
y_min = v.y < y_min ? v.y : y_min;
|
|
y_min = v.y < y_min ? v.y : y_min;
|
|
y_max = v.y > y_max ? v.y : y_max;
|
|
y_max = v.y > y_max ? v.y : y_max;
|
|
-
|
|
|
|
- triangulate();
|
|
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ vertexArray[i] = v;
|
|
}
|
|
}
|
|
|
|
|
|
void Geometry::flip(bool x, bool y)
|
|
void Geometry::flip(bool x, bool y)
|
|
{
|
|
{
|
|
- for (size_t i = 0; i < polygon.size(); ++i)
|
|
|
|
- {
|
|
|
|
- vertex &v = polygon[i];
|
|
|
|
- if (x) v.x = x_max + x_min - v.x;
|
|
|
|
- if (y) v.y = y_max + y_min - v.y;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
for (size_t i = 0; i < vertexCount; ++i)
|
|
for (size_t i = 0; i < vertexCount; ++i)
|
|
{
|
|
{
|
|
vertex &v = vertexArray[i];
|
|
vertex &v = vertexArray[i];
|
|
@@ -165,24 +165,5 @@ void Geometry::setVertexColors(bool on)
|
|
vertexColors = on;
|
|
vertexColors = on;
|
|
}
|
|
}
|
|
|
|
|
|
-void Geometry::triangulate()
|
|
|
|
-{
|
|
|
|
- const std::vector<Triangle> triangles = Math::instance.triangulate(polygon);
|
|
|
|
-
|
|
|
|
- if (vertexArray)
|
|
|
|
- delete[] vertexArray;
|
|
|
|
-
|
|
|
|
- vertexCount = triangles.size() * 3;
|
|
|
|
- vertexArray = new vertex[vertexCount];
|
|
|
|
-
|
|
|
|
- for (size_t i = 0; i < triangles.size(); ++i)
|
|
|
|
- {
|
|
|
|
- const Triangle &t = triangles[i];
|
|
|
|
- vertexArray[i*3] = t.a;
|
|
|
|
- vertexArray[i*3+1] = t.b;
|
|
|
|
- vertexArray[i*3+2] = t.c;
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
} // graphics
|
|
} // graphics
|
|
} // love
|
|
} // love
|