zoomedit: Made rotation tool much nicer ;-)
This commit is contained in:
parent
80b4f14530
commit
0ea1d38865
13 changed files with 96 additions and 68 deletions
|
@ -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_*/
|
||||
|
|
10
LevelEdge.h
10
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);}
|
||||
|
|
|
@ -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_*/
|
||||
|
|
|
@ -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);}
|
||||
|
|
22
Portal.h
22
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);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
14
Renderer.cpp
14
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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
22
Room.cpp
22
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;
|
||||
}
|
||||
}
|
||||
|
|
23
Room.h
23
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);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
13
ToolRotate.h
13
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;
|
||||
}
|
||||
|
|
|
@ -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_*/
|
||||
|
|
Reference in a new issue