zoomedit: Vertices are selectable now.
This commit is contained in:
parent
16397f4474
commit
c4aadd9823
12 changed files with 227 additions and 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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
14
Level.h
14
Level.h
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -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) {}
|
||||
|
|
61
LevelVertex.h
Normal file
61
LevelVertex.h
Normal file
|
@ -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_*/
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
75
Portal.h
75
Portal.h
|
@ -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_*/
|
||||
|
|
33
Renderer.cpp
33
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);
|
||||
|
|
40
Room.h
40
Room.h
|
@ -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_*/
|
||||
|
|
18
VertexProvider.h
Normal file
18
VertexProvider.h
Normal file
|
@ -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_*/
|
Reference in a new issue