From 0ea1d388651217697d49029820b02b4f002f1ac0 Mon Sep 17 00:00:00 2001 From: neoraider Date: Fri, 15 Feb 2008 19:10:04 +0000 Subject: zoomedit: Made rotation tool much nicer ;-) --- EdgeProvider.h | 2 +- LevelEdge.h | 10 ++-------- LevelObject.h | 4 +--- LevelVertex.h | 8 ++------ Portal.h | 22 +++++++++++----------- Renderer.cpp | 14 ++++++++++++++ Renderer.h | 1 + Room.cpp | 22 +++++++++++----------- Room.h | 23 +++++------------------ ToolAddPolygon.h | 2 +- ToolRotate.cpp | 41 +++++++++++++++++++++++++++++++++++------ ToolRotate.h | 13 +++++++++++-- VertexProvider.h | 2 +- 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 > 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 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 -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_*/ -- cgit v1.2.3