diff options
-rw-r--r-- | Drawer.cpp | 4 | ||||
-rw-r--r-- | EditManager.cpp | 6 | ||||
-rw-r--r-- | EditManager.h | 2 | ||||
-rw-r--r-- | Level.h | 14 | ||||
-rw-r--r-- | LevelObject.h | 18 | ||||
-rw-r--r-- | LevelVertex.h | 61 | ||||
-rw-r--r-- | PlayerStart.h | 2 | ||||
-rw-r--r-- | Portal.h | 75 | ||||
-rw-r--r-- | Renderer.cpp | 33 | ||||
-rw-r--r-- | Renderer.h | 2 | ||||
-rw-r--r-- | Room.h | 40 | ||||
-rw-r--r-- | VertexProvider.h | 18 |
12 files changed, 227 insertions, 48 deletions
@@ -47,7 +47,7 @@ gboolean Drawer::eventHandler(GtkWidget *widget, GdkEvent *event, Drawer *drawer return TRUE; case GDK_LEAVE_NOTIFY: - drawer->window->getEditManager().setHoveredVertex(NULL); + drawer->window->getEditManager().setHoveredVertex(NULL, drawer->scale); drawer->window->getActiveTool()->getEventHandler()->motion(); return TRUE; @@ -156,7 +156,7 @@ void Drawer::updateScrollbars(float x, float y) { void Drawer::updateHoveredPoint(float x, float y) { Vertex v(x, y); viewToImage(&v); - window->getEditManager().setHoveredVertex(&v); + window->getEditManager().setHoveredVertex(&v, scale); g_object_set(G_OBJECT(hRuler), "position", v.getX(), NULL); g_object_set(G_OBJECT(vRuler), "position", v.getY(), NULL); diff --git a/EditManager.cpp b/EditManager.cpp index 0052c8f..9ca3dfb 100644 --- a/EditManager.cpp +++ b/EditManager.cpp @@ -46,7 +46,7 @@ bool EditManager::addRoom(const Room &newRoom) { Room *room = new Room(newRoom); room->setName(idManager.generate("room")); - window->getLevel().push_back(SharedPtr<LevelObject>(room)); + window->getLevel().addWithChildren(SharedPtr<LevelObject>(room)); selectedObject = room; window->resetTool(); @@ -62,7 +62,7 @@ const Vertex* EditManager::getHoveredVertex() const { else return NULL; } -void EditManager::setHoveredVertex(const Vertex *v) { +void EditManager::setHoveredVertex(const Vertex *v, float scale) { if(v) { hasHoveredVertex = true; hoveredVertex = *v; @@ -70,7 +70,7 @@ void EditManager::setHoveredVertex(const Vertex *v) { hoveredObject = NULL; for(Level::iterator object = window->getLevel().begin(); object != window->getLevel().end(); object++) { - if((*object)->hit(*v)) { + if((*object)->hit(*v, scale)) { if(hoveredObject && (*object)->getPriority() < hoveredObject->getPriority()) continue; diff --git a/EditManager.h b/EditManager.h index bd33c9d..c3bc03d 100644 --- a/EditManager.h +++ b/EditManager.h @@ -56,7 +56,7 @@ class EditManager { bool addRoom(const Room &room); const Vertex* getHoveredVertex() const; - void setHoveredVertex(const Vertex *v); + void setHoveredVertex(const Vertex *v, float scale); bool vertexOk(const Vertex &v, const Room *newRoom = NULL) const; bool polygonOk(const Polygon &polygon) const; @@ -6,13 +6,23 @@ #include "SharedPtr.h" #include "PlayerStart.h" #include "Portal.h" +#include "LevelVertex.h" #include <vector> class Level : public std::vector<SharedPtr<LevelObject> > { public: Level() { - push_back(SharedPtr<LevelObject>(new PlayerStart())); - push_back(SharedPtr<LevelObject>(new Portal(2, 2, 0.4f))); + addWithChildren(SharedPtr<LevelObject>(new PlayerStart())); + addWithChildren(SharedPtr<LevelObject>(new Portal(2, 2, 0.4f))); + } + + void addWithChildren(SharedPtr<LevelObject> object) { + push_back(object); + + std::vector<SharedPtr<LevelObject> > children = object->getChildren(); + + for(std::vector<SharedPtr<LevelObject> >::iterator child = children.begin(); child != children.end(); child++) + addWithChildren(*child); } }; diff --git a/LevelObject.h b/LevelObject.h index 4cb56a4..005b3a9 100644 --- a/LevelObject.h +++ b/LevelObject.h @@ -3,14 +3,28 @@ #include "Object.h" #include "Vertex.h" +#include <list> class LevelObject : public Object { + private: + LevelObject *parent; + public: + LevelObject() : parent(NULL) {} + LevelObject(LevelObject *p) : parent(p) {} virtual ~LevelObject() {} - virtual bool hit(const Vertex &v) const = 0; - virtual int getPriority() const = 0; + LevelObject* getParent() const { + return parent; + } + + virtual std::vector<SharedPtr<LevelObject> > getChildren() { + return std::vector<SharedPtr<LevelObject> >(); + } + + virtual bool hit(const Vertex &v, float scale) const = 0; + virtual int getPriority() const {return 0;} virtual void move(float x, float y) {} virtual void rotate(float a) {} diff --git a/LevelVertex.h b/LevelVertex.h new file mode 100644 index 0000000..998756f --- /dev/null +++ b/LevelVertex.h @@ -0,0 +1,61 @@ +#ifndef LEVELVERTEX_H_ +#define LEVELVERTEX_H_ + +#include "LevelObject.h" +#include "VertexProvider.h" + + +class LevelVertex : public LevelObject, public VertexProvider { + private: + VertexProvider *provider; + size_t id; + + public: + LevelVertex(VertexProvider *p, size_t i) + : provider(p), id(i) {} + + virtual const char* getType() const { + return "LevelVertex"; + } + + virtual bool hit(const Vertex &v, float scale) const { + return (provider->getVertex(id)->distanceSq(v) < (3.5f*3.5f)/(scale*scale)); + } + + virtual int getPriority() const { + return 1000; + } + + virtual void move(float x, float y) { + provider->moveVertex(id, x, y); + } + + virtual void rotate(float a) { + provider->rotateVertex(id, a); + } + + virtual Vertex getCenter() const { + return *provider->getVertex(id); + } + + virtual const Vertex* getVertex(size_t id) const { + return provider->getVertex(this->id); + } + + virtual size_t getVertexCount() const { + return 1; + } + + virtual void moveVertex(size_t id, float x, float y) { + provider->moveVertex(this->id, x, y); + } + + virtual void rotateVertex(size_t id, float a) { + provider->rotateVertex(this->id, a); + } + + const Vertex* operator->() const {return provider->getVertex(id);} + const Vertex& operator*() const {return *provider->getVertex(id);} +}; + +#endif /*LEVELVERTEX_H_*/ diff --git a/PlayerStart.h b/PlayerStart.h index b40b49e..ed39fd2 100644 --- a/PlayerStart.h +++ b/PlayerStart.h @@ -7,7 +7,7 @@ class PlayerStart : public Vertex3d, public LevelObject { public: - virtual bool hit(const Vertex &v) const { + virtual bool hit(const Vertex &v, float scale) const { return (v.distanceSq(Vertex(getX(), getZ())) < 0.09); } @@ -3,29 +3,45 @@ #include "LevelObject.h" #include "Polygon.h" +#include "VertexProvider.h" +#include "LevelVertex.h" #include <math.h> -class Portal : public LevelObject { +class Portal : public LevelObject, public VertexProvider { private: float width, height, thickness; Vertex pos; float orient; - Polygon createPolygon() const { - Polygon p; - - float s = sinf(orient); - float c = cosf(orient); + Vertex vertices[4]; + float s, c; + + + void updateVertices() { float x = width/2*c; float y = width/2*s; float ts = thickness/2*s; float tc = thickness/2*c; - p.push_back(Vertex(pos.getX()-x-ts, pos.getY()-y+tc)); - p.push_back(Vertex(pos.getX()-x+ts, pos.getY()-y-tc)); - p.push_back(Vertex(pos.getX()+x+ts, pos.getY()+y-tc)); - p.push_back(Vertex(pos.getX()+x-ts, pos.getY()+y+tc)); + vertices[0].setLocation(pos.getX()-x-ts, pos.getY()-y+tc); + vertices[1].setLocation(pos.getX()-x+ts, pos.getY()-y-tc); + vertices[2].setLocation(pos.getX()+x+ts, pos.getY()+y-tc); + vertices[3].setLocation(pos.getX()+x-ts, pos.getY()+y+tc); + } + + void updateOrient() { + s = sinf(orient); + c = cosf(orient); + + updateVertices(); + } + + Polygon createPolygon() const { + Polygon p; + + for(int i = 0; i < 4; i++) + p.push_back(vertices[i]); return p; } @@ -37,6 +53,8 @@ class Portal : public LevelObject { this->thickness = thickness; orient = 0; + + updateOrient(); } float getWidth() const {return width;} @@ -44,12 +62,21 @@ class Portal : public LevelObject { float getThickness() const {return thickness;} const Vertex& getPosition() const {return pos;} - void setPosition(Vertex v) {pos = v;} + void setPosition(Vertex v) {pos = v; updateVertices();} float getOrientation() const {return orient;} - void setOrientation(float orient) {this->orient = orient;} + void setOrientation(float orient) {this->orient = orient; updateOrient();} - virtual bool hit(const Vertex &v) const {return createPolygon().contains(v);} + virtual std::vector<SharedPtr<LevelObject> > getChildren() { + std::vector<SharedPtr<LevelObject> > children; + + for(size_t i = 0; i < 4; i++) + children.push_back(SharedPtr<LevelObject>(new LevelVertex(this, i))); + + return children; + } + + virtual bool hit(const Vertex &v, float scale) const {return createPolygon().contains(v);} virtual int getPriority() const {return 1;} virtual const char* getType() const { @@ -58,15 +85,37 @@ class Portal : public LevelObject { virtual void move(float x, float y) { pos += Vertex(x, y); + updateVertices(); } virtual void rotate(float a) { orient = fmodf(orient+a, 2*M_PI); + updateOrient(); } virtual Vertex getCenter() const { return pos; } + + virtual const Vertex* getVertex(size_t id) const { + return &vertices[id]; + } + + virtual size_t getVertexCount() const { + return 1; + } + + virtual void moveVertex(size_t id, float x, float y) { + move(x, y); + } + + virtual void rotateVertex(size_t id, float a) { + pos = vertices[id]; + rotate(a); + pos = vertices[(id+2)%4]; + + updateVertices(); + } }; #endif /*PORTAL_H_*/ diff --git a/Renderer.cpp b/Renderer.cpp index e2ededc..42614a7 100644 --- a/Renderer.cpp +++ b/Renderer.cpp @@ -91,7 +91,9 @@ void Renderer::drawCross(const Vertex &m, float r) { } void Renderer::renderObject(const LevelObject &object, bool selected, bool highlighted, float scale) { - if(object.isOfType("Room")) + if(object.isOfType("LevelVertex")) + renderLevelVertex(*(LevelVertex*)&object, selected, highlighted, scale); + else if(object.isOfType("Room")) renderRoom(*(Room*)&object, selected, highlighted, scale); else if(object.isOfType("PlayerStart")) renderPlayerStart(*(PlayerStart*)&object, selected, highlighted, scale); @@ -99,13 +101,18 @@ void Renderer::renderObject(const LevelObject &object, bool selected, bool highl renderPortal(*(Portal*)&object, selected, highlighted, scale); } -void Renderer::renderVertex(const Vertex &vertex, bool selected, bool highlighted, float scale) { +void Renderer::renderLevelVertex(const LevelVertex &vertex, bool selected, bool highlighted, float scale) { + if(!selected && !highlighted) return; + glColor4f(0.0f, 0.0f, 0.0f, 1.0f); - fillCircle(vertex, 3/scale, 16); + fillCircle(*vertex, 3.5f/scale, 16); glLineWidth(1.0f); - glColor4f(9.0f, 0.7f, 0.0f, 0.9f); - drawCircle(vertex, 3/scale, 16); + if(highlighted) + glColor4f(1.0f, 0.9f, 0.0f, 0.9f); + else + glColor4f(1.0f, 0.7f, 0.0f, 0.9f); + drawCircle(*vertex, 3.5f/scale, 16); } void Renderer::renderRoom(const Room &room, bool selected, bool highlighted, float scale) { @@ -130,11 +137,6 @@ void Renderer::renderRoom(const Room &room, bool selected, bool highlighted, flo } drawPolygon(room); - - if(selected || highlighted) { - for(Room::const_iterator v = room.begin(); v != room.end(); v++) - renderVertex(*v, false, false, scale); - } } void Renderer::renderPlayerStart(const PlayerStart &start, bool selected, bool highlighted, float scale) { @@ -192,17 +194,6 @@ void Renderer::renderPortal(const Portal &portal, bool selected, bool highlighte glVertex2f(portal.getPosition().getX()+x, portal.getPosition().getY()+y); glEnd(); - - if(highlighted || selected) { - renderVertex(Vertex(portal.getPosition().getX()-x+ts, portal.getPosition().getY()-y-tc), - false, false, scale); - renderVertex(Vertex(portal.getPosition().getX()-x-ts, portal.getPosition().getY()-y+tc), - false, false, scale); - renderVertex(Vertex(portal.getPosition().getX()+x+ts, portal.getPosition().getY()+y-tc), - false, false, scale); - renderVertex(Vertex(portal.getPosition().getX()+x-ts, portal.getPosition().getY()+y+tc), - false, false, scale); - } } void Renderer::render(const Level &level, const Rectangle &rect, float scale) { @@ -25,7 +25,7 @@ class Renderer { void renderObject(const LevelObject &object, bool selected, bool highlighted, float scale); - void renderVertex(const Vertex &vertex, bool selected, bool highlighted, float scale); + void renderLevelVertex(const LevelVertex &vertex, bool selected, bool highlighted, float scale); void renderRoom(const Room &room, bool selected, bool highlighted, float scale); void renderPlayerStart(const PlayerStart &start, bool selected, bool highlighted, float scale); @@ -3,10 +3,12 @@ #include "Polygon.h" #include "LevelObject.h" +#include "VertexProvider.h" +#include "LevelVertex.h" #include <string> -class Room : public Polygon, public LevelObject { +class Room : public Polygon, public LevelObject, public VertexProvider { private: std::string name; float height; @@ -22,9 +24,18 @@ class Room : public Polygon, public LevelObject { float getHeight() const {return height;} void setHeight(float height) {this->height = height;} - virtual bool hit(const Vertex &v) const {return contains(v);} + virtual bool hit(const Vertex &v, float scale) const {return contains(v);} virtual int getPriority() const {return 0;} + virtual std::vector<SharedPtr<LevelObject> > getChildren() { + std::vector<SharedPtr<LevelObject> > children; + + for(size_t i = 0; i < size(); i++) + children.push_back(SharedPtr<LevelObject>(new LevelVertex(this, i))); + + return children; + } + virtual const char* getType() const { return "Room"; } @@ -56,6 +67,31 @@ class Room : public Polygon, public LevelObject { return ret / size(); } + + virtual const Vertex* getVertex(size_t id) const { + return &at(id); + } + + virtual size_t getVertexCount() const { + return size(); + } + + virtual void moveVertex(size_t id, float x, float y) { + at(id) += Vertex(x, y); + } + + virtual void rotateVertex(size_t id, float a) { + Vertex z = at(id); + float s = sinf(a); + float c = cosf(a); + + for(iterator v = begin(); v != end(); v++) { + *v -= z; + v->setLocation(c*v->getX() - s*v->getY(), c*v->getY() + s*v->getX()); + *v += z; + } + } + }; #endif /*ROOM_H_*/ diff --git a/VertexProvider.h b/VertexProvider.h new file mode 100644 index 0000000..fadda04 --- /dev/null +++ b/VertexProvider.h @@ -0,0 +1,18 @@ +#ifndef VERTEXPROVIDER_H_ +#define VERTEXPROVIDER_H_ + +#include "Vertex.h" + + +class VertexProvider { + public: + virtual ~VertexProvider() {} + + virtual const Vertex* getVertex(size_t id) const = 0; + virtual size_t getVertexCount() const = 0; + + virtual void moveVertex(size_t id, float x, float y) {} + virtual void rotateVertex(size_t id, float a) {} +}; + +#endif /*VERTEXPROVIDER_H_*/ |