summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--EdgeProvider.h2
-rw-r--r--LevelEdge.h10
-rw-r--r--LevelObject.h4
-rw-r--r--LevelVertex.h8
-rw-r--r--Portal.h22
-rw-r--r--Renderer.cpp14
-rw-r--r--Renderer.h1
-rw-r--r--Room.cpp22
-rw-r--r--Room.h23
-rw-r--r--ToolAddPolygon.h2
-rw-r--r--ToolRotate.cpp41
-rw-r--r--ToolRotate.h13
-rw-r--r--VertexProvider.h2
13 files changed, 96 insertions, 68 deletions
diff --git a/EdgeProvider.h b/EdgeProvider.h
index 3a08829..1cbdde7 100644
--- a/EdgeProvider.h
+++ b/EdgeProvider.h
@@ -12,7 +12,7 @@ class EdgeProvider {
virtual size_t getEdgeCount() const = 0;
virtual void moveEdge(size_t id, float x, float y) {}
- virtual void rotateEdge(size_t id, float a) {}
+ virtual void rotateEdge(size_t id, Vertex m, float a) {}
};
#endif /*EDGEPROVIDER_H_*/
diff --git a/LevelEdge.h b/LevelEdge.h
index 7fb4e1a..f5f9bfd 100644
--- a/LevelEdge.h
+++ b/LevelEdge.h
@@ -51,14 +51,8 @@ class LevelEdge : public LevelObject {
provider->moveEdge(id, x, y);
}
- virtual void rotate(float a) {
- provider->rotateEdge(id, a);
- }
-
- virtual Vertex getCenter() const {
- Line l = provider->getEdge(id)->toLine();
-
- return (l.getVertex1()+l.getVertex2()) / 2;
+ virtual void rotate(Vertex m, float a) {
+ provider->rotateEdge(id, m, a);
}
const Edge* operator->() const {return provider->getEdge(id);}
diff --git a/LevelObject.h b/LevelObject.h
index 005b3a9..f3360e1 100644
--- a/LevelObject.h
+++ b/LevelObject.h
@@ -27,9 +27,7 @@ class LevelObject : public Object {
virtual int getPriority() const {return 0;}
virtual void move(float x, float y) {}
- virtual void rotate(float a) {}
-
- virtual Vertex getCenter() const {return Vertex();}
+ virtual void rotate(Vertex m, float a) {}
};
#endif /*LEVELOBJECT_H_*/
diff --git a/LevelVertex.h b/LevelVertex.h
index 448d021..4834c06 100644
--- a/LevelVertex.h
+++ b/LevelVertex.h
@@ -30,12 +30,8 @@ class LevelVertex : public LevelObject {
provider->moveVertex(id, x, y);
}
- virtual void rotate(float a) {
- provider->rotateVertex(id, a);
- }
-
- virtual Vertex getCenter() const {
- return *provider->getVertex(id);
+ virtual void rotate(Vertex m, float a) {
+ provider->rotateVertex(id, m, a);
}
const Vertex* operator->() const {return provider->getVertex(id);}
diff --git a/Portal.h b/Portal.h
index 858caf8..6acd1f3 100644
--- a/Portal.h
+++ b/Portal.h
@@ -88,15 +88,19 @@ class Portal : public LevelObject, public VertexProvider {
updateVertices();
}
- virtual void rotate(float a) {
+ virtual void rotate(Vertex m, float a) {
orient = fmodf(orient+a, 2*M_PI);
+
+ s = sinf(a);
+ c = cosf(a);
+
+ pos -= m;
+ pos.setLocation(c*pos.getX() - s*pos.getY(), c*pos.getY() + s*pos.getX());
+ pos += m;
+
updateOrient();
}
- virtual Vertex getCenter() const {
- return pos;
- }
-
virtual const Vertex* getVertex(size_t id) const {
return &vertices[id];
}
@@ -109,12 +113,8 @@ class Portal : public LevelObject, public VertexProvider {
move(x, y);
}
- virtual void rotateVertex(size_t id, float a) {
- pos = vertices[id];
- rotate(a);
- pos = vertices[(id+2)%4];
-
- updateVertices();
+ virtual void rotateVertex(size_t id, Vertex m, float a) {
+ rotate(m, a);
}
};
diff --git a/Renderer.cpp b/Renderer.cpp
index 0a4f403..c95779a 100644
--- a/Renderer.cpp
+++ b/Renderer.cpp
@@ -69,6 +69,20 @@ void Renderer::drawCircle(const Vertex &m, float r, int n) {
glEnd();
}
+void Renderer::drawCircleDotted(const Vertex &m, float r, int n, int d, float rot) {
+ glBegin(GL_LINES);
+
+ for(int i = 0; i < n; i++) {
+ if(2*d*(i%(n/d)) >= n)
+ continue;
+
+ glVertex2f(m.getX()+r*cosf(rot+2*M_PI*i/n), m.getY()+r*sinf(rot+2*M_PI*i/n));
+ glVertex2f(m.getX()+r*cosf(rot+2*M_PI*(i+1)/n), m.getY()+r*sinf(rot+2*M_PI*(i+1)/n));
+ }
+
+ glEnd();
+}
+
void Renderer::fillCircle(const Vertex &m, float r, int n) {
glBegin(GL_POLYGON);
diff --git a/Renderer.h b/Renderer.h
index 8ae6bd1..0432fe5 100644
--- a/Renderer.h
+++ b/Renderer.h
@@ -22,6 +22,7 @@ class Renderer {
void drawPolygon(const Polygon &polygon, bool close = true);
void fillCircle(const Vertex &m, float r, int n = 64);
void drawCircle(const Vertex &m, float r, int n = 64);
+ void drawCircleDotted(const Vertex &m, float r, int n = 64, int d = 8, float rot = 0);
void drawCross(const Vertex &m, float r);
void renderObject(const LevelObject &object, bool selected, bool highlighted, float scale);
diff --git a/Room.cpp b/Room.cpp
index 1980026..7608e41 100644
--- a/Room.cpp
+++ b/Room.cpp
@@ -2,17 +2,6 @@
#include "LevelEdge.h"
-void Room::rotateAround(Vertex z, float a) {
- float s = sinf(a);
- float c = cosf(a);
-
- for(Polygon::iterator v = polygon.begin(); v != polygon.end(); v++) {
- *v -= z;
- v->setLocation(c*v->getX() - s*v->getY(), c*v->getY() + s*v->getX());
- *v += z;
- }
-}
-
const Room& Room::operator=(const Room &room) {
polygon.clear();
edges.clear();
@@ -61,3 +50,14 @@ std::vector<SharedPtr<LevelObject> > Room::getChildren() {
return children;
}
+
+void Room::rotate(Vertex m, float a) {
+ float s = sinf(a);
+ float c = cosf(a);
+
+ for(Polygon::iterator v = polygon.begin(); v != polygon.end(); v++) {
+ *v -= m;
+ v->setLocation(c*v->getX() - s*v->getY(), c*v->getY() + s*v->getX());
+ *v += m;
+ }
+}
diff --git a/Room.h b/Room.h
index 46d372f..855a00c 100644
--- a/Room.h
+++ b/Room.h
@@ -17,8 +17,6 @@ class Room : public LevelObject, private VertexProvider, private EdgeProvider {
std::vector<Edge> edges;
- void rotateAround(Vertex z, float a);
-
public:
Room() {height = 10;}
Room(std::string name) {this->name = name; height = 10;}
@@ -57,18 +55,7 @@ class Room : public LevelObject, private VertexProvider, private EdgeProvider {
*v += m;
}
- virtual void rotate(float a) {
- rotateAround(getCenter(), a);
- }
-
- virtual Vertex getCenter() const {
- Vertex ret;
-
- for(Polygon::const_iterator v = polygon.begin(); v != polygon.end(); v++)
- ret += *v;
-
- return ret / polygon.size();
- }
+ virtual void rotate(Vertex m, float a);
virtual const Vertex* getVertex(size_t id) const {
return &polygon[id];
@@ -82,8 +69,8 @@ class Room : public LevelObject, private VertexProvider, private EdgeProvider {
polygon[id] += Vertex(x, y);
}
- virtual void rotateVertex(size_t id, float a) {
- rotateAround(polygon[id], a);
+ virtual void rotateVertex(size_t id, Vertex m, float a) {
+ rotate(m, a);
}
virtual const Edge* getEdge(size_t id) const {
@@ -99,8 +86,8 @@ class Room : public LevelObject, private VertexProvider, private EdgeProvider {
moveVertex((id+1)%polygon.size(), x, y);
}
- virtual void rotateEdge(size_t id, float a) {
- rotateAround((polygon[id]+polygon[(id+1)%polygon.size()])/2, a);
+ virtual void rotateEdge(size_t id, Vertex m, float a) {
+ rotate(m, a);
}
};
diff --git a/ToolAddPolygon.h b/ToolAddPolygon.h
index 69a0e07..59a4bb6 100644
--- a/ToolAddPolygon.h
+++ b/ToolAddPolygon.h
@@ -6,7 +6,7 @@
#include "SidebarAdd.h"
-class ToolAddPolygon : public Tool, public EventHandler, public Renderer {
+class ToolAddPolygon : public Tool, private EventHandler, private Renderer {
private:
GtkWidget *image;
diff --git a/ToolRotate.cpp b/ToolRotate.cpp
index 6cd7626..65bf334 100644
--- a/ToolRotate.cpp
+++ b/ToolRotate.cpp
@@ -1,6 +1,8 @@
#include "ToolRotate.h"
+#include <GL/gl.h>
-ToolRotate::ToolRotate(EditManager *editManager) : sidebar(editManager) {
+
+ToolRotate::ToolRotate(EditManager *editManager) : Renderer(editManager), sidebar(editManager) {
this->editManager = editManager;
pressed = false;
@@ -24,8 +26,8 @@ bool ToolRotate::buttonPress(unsigned int button) {
return false;
pressed = true;
- Vertex v = *editManager->getHoveredVertex() - editManager->getHoveredObject()->getCenter();
- angle = atan2(v.getY(), v.getX());
+ valid = false;
+ v0 = v = *editManager->getHoveredVertex();
editManager->setSelectedObject(editManager->getHoveredObject());
@@ -58,13 +60,40 @@ bool ToolRotate::motion() {
if(!editManager->getHoveredVertex())
return false;
- Vertex v = *editManager->getHoveredVertex() - editManager->getSelectedObject()->getCenter();
+ v = *editManager->getHoveredVertex();
- float a = atan2(v.getY(), v.getX());
+ float a = atan2((v-v0).getY(), (v-v0).getX());
- editManager->getSelectedObject()->rotate(a-angle);
+ if(v0.distanceSq(v) > 0.04f) {
+ if(valid)
+ editManager->getSelectedObject()->rotate(v0, a-angle);
+
+ else
+ valid = true;
+ }
+ else
+ valid = false;
angle = a;
return false;
}
+
+void ToolRotate::render(const Level &level, const Rectangle &rect, float scale) {
+ Renderer::render(level, rect, scale);
+
+ if(pressed && valid) {
+ glLineWidth(1.0f);
+ glColor4f(1.0f, 1.0f, 1.0f, 0.7f);
+ drawCircleDotted(v0, v0.distance(v), 64, 16, angle);
+
+ glLineWidth(2.0f);
+
+ glBegin(GL_LINES);
+
+ glVertex2f(v0.getX(), v0.getY());
+ glVertex2f(v.getX(), v.getY());
+
+ glEnd();
+ }
+}
diff --git a/ToolRotate.h b/ToolRotate.h
index 419eb6a..27491fb 100644
--- a/ToolRotate.h
+++ b/ToolRotate.h
@@ -3,8 +3,9 @@
#include "Tool.h"
#include "SidebarView.h"
+#include "Renderer.h"
-class ToolRotate : public Tool, EventHandler {
+class ToolRotate : public Tool, private EventHandler, private Renderer {
private:
GtkWidget *image;
@@ -12,12 +13,14 @@ class ToolRotate : public Tool, EventHandler {
SidebarView sidebar;
- bool pressed;
+ bool pressed, valid;
float angle;
+ Vertex v0, v;
// prevent shallow copy
ToolRotate(const ToolRotate &t);
const ToolRotate& operator=(const ToolRotate &t);
+
public:
ToolRotate(EditManager *editManager);
virtual ~ToolRotate();
@@ -48,6 +51,12 @@ class ToolRotate : public Tool, EventHandler {
virtual bool buttonRelease(unsigned int button);
virtual bool motion();
+ virtual Renderer *getRenderer() {
+ return this;
+ }
+
+ virtual void render(const Level &level, const Rectangle &rect, float scale);
+
virtual Sidebar* getSidebar() {
return &sidebar;
}
diff --git a/VertexProvider.h b/VertexProvider.h
index fadda04..2f4b3be 100644
--- a/VertexProvider.h
+++ b/VertexProvider.h
@@ -12,7 +12,7 @@ class VertexProvider {
virtual size_t getVertexCount() const = 0;
virtual void moveVertex(size_t id, float x, float y) {}
- virtual void rotateVertex(size_t id, float a) {}
+ virtual void rotateVertex(size_t id, Vertex m, float a) {}
};
#endif /*VERTEXPROVIDER_H_*/