zoomedit: Vertices are selectable now.

This commit is contained in:
neoraider 2008-02-13 21:06:01 +00:00
parent 16397f4474
commit c4aadd9823
12 changed files with 227 additions and 48 deletions

View file

@ -47,7 +47,7 @@ gboolean Drawer::eventHandler(GtkWidget *widget, GdkEvent *event, Drawer *drawer
return TRUE; return TRUE;
case GDK_LEAVE_NOTIFY: case GDK_LEAVE_NOTIFY:
drawer->window->getEditManager().setHoveredVertex(NULL); drawer->window->getEditManager().setHoveredVertex(NULL, drawer->scale);
drawer->window->getActiveTool()->getEventHandler()->motion(); drawer->window->getActiveTool()->getEventHandler()->motion();
return TRUE; return TRUE;
@ -156,7 +156,7 @@ void Drawer::updateScrollbars(float x, float y) {
void Drawer::updateHoveredPoint(float x, float y) { void Drawer::updateHoveredPoint(float x, float y) {
Vertex v(x, y); Vertex v(x, y);
viewToImage(&v); 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(hRuler), "position", v.getX(), NULL);
g_object_set(G_OBJECT(vRuler), "position", v.getY(), NULL); g_object_set(G_OBJECT(vRuler), "position", v.getY(), NULL);

View file

@ -46,7 +46,7 @@ bool EditManager::addRoom(const Room &newRoom) {
Room *room = new Room(newRoom); Room *room = new Room(newRoom);
room->setName(idManager.generate("room")); room->setName(idManager.generate("room"));
window->getLevel().push_back(SharedPtr<LevelObject>(room)); window->getLevel().addWithChildren(SharedPtr<LevelObject>(room));
selectedObject = room; selectedObject = room;
window->resetTool(); window->resetTool();
@ -62,7 +62,7 @@ const Vertex* EditManager::getHoveredVertex() const {
else return NULL; else return NULL;
} }
void EditManager::setHoveredVertex(const Vertex *v) { void EditManager::setHoveredVertex(const Vertex *v, float scale) {
if(v) { if(v) {
hasHoveredVertex = true; hasHoveredVertex = true;
hoveredVertex = *v; hoveredVertex = *v;
@ -70,7 +70,7 @@ void EditManager::setHoveredVertex(const Vertex *v) {
hoveredObject = NULL; hoveredObject = NULL;
for(Level::iterator object = window->getLevel().begin(); object != window->getLevel().end(); object++) { 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()) if(hoveredObject && (*object)->getPriority() < hoveredObject->getPriority())
continue; continue;

View file

@ -56,7 +56,7 @@ class EditManager {
bool addRoom(const Room &room); bool addRoom(const Room &room);
const Vertex* getHoveredVertex() const; 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 vertexOk(const Vertex &v, const Room *newRoom = NULL) const;
bool polygonOk(const Polygon &polygon) const; bool polygonOk(const Polygon &polygon) const;

14
Level.h
View file

@ -6,13 +6,23 @@
#include "SharedPtr.h" #include "SharedPtr.h"
#include "PlayerStart.h" #include "PlayerStart.h"
#include "Portal.h" #include "Portal.h"
#include "LevelVertex.h"
#include <vector> #include <vector>
class Level : public std::vector<SharedPtr<LevelObject> > { class Level : public std::vector<SharedPtr<LevelObject> > {
public: public:
Level() { Level() {
push_back(SharedPtr<LevelObject>(new PlayerStart())); addWithChildren(SharedPtr<LevelObject>(new PlayerStart()));
push_back(SharedPtr<LevelObject>(new Portal(2, 2, 0.4f))); 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);
} }
}; };

View file

@ -3,14 +3,28 @@
#include "Object.h" #include "Object.h"
#include "Vertex.h" #include "Vertex.h"
#include <list>
class LevelObject : public Object { class LevelObject : public Object {
private:
LevelObject *parent;
public: public:
LevelObject() : parent(NULL) {}
LevelObject(LevelObject *p) : parent(p) {}
virtual ~LevelObject() {} virtual ~LevelObject() {}
virtual bool hit(const Vertex &v) const = 0; LevelObject* getParent() const {
virtual int getPriority() const = 0; 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 move(float x, float y) {}
virtual void rotate(float a) {} virtual void rotate(float a) {}

61
LevelVertex.h Normal file
View 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_*/

View file

@ -7,7 +7,7 @@
class PlayerStart : public Vertex3d, public LevelObject { class PlayerStart : public Vertex3d, public LevelObject {
public: 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); return (v.distanceSq(Vertex(getX(), getZ())) < 0.09);
} }

View file

@ -3,29 +3,45 @@
#include "LevelObject.h" #include "LevelObject.h"
#include "Polygon.h" #include "Polygon.h"
#include "VertexProvider.h"
#include "LevelVertex.h"
#include <math.h> #include <math.h>
class Portal : public LevelObject { class Portal : public LevelObject, public VertexProvider {
private: private:
float width, height, thickness; float width, height, thickness;
Vertex pos; Vertex pos;
float orient; float orient;
Polygon createPolygon() const { Vertex vertices[4];
Polygon p; float s, c;
float s = sinf(orient);
float c = cosf(orient); void updateVertices() {
float x = width/2*c; float x = width/2*c;
float y = width/2*s; float y = width/2*s;
float ts = thickness/2*s; float ts = thickness/2*s;
float tc = thickness/2*c; float tc = thickness/2*c;
p.push_back(Vertex(pos.getX()-x-ts, pos.getY()-y+tc)); vertices[0].setLocation(pos.getX()-x-ts, pos.getY()-y+tc);
p.push_back(Vertex(pos.getX()-x+ts, pos.getY()-y-tc)); vertices[1].setLocation(pos.getX()-x+ts, pos.getY()-y-tc);
p.push_back(Vertex(pos.getX()+x+ts, pos.getY()+y-tc)); vertices[2].setLocation(pos.getX()+x+ts, pos.getY()+y-tc);
p.push_back(Vertex(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; return p;
} }
@ -37,6 +53,8 @@ class Portal : public LevelObject {
this->thickness = thickness; this->thickness = thickness;
orient = 0; orient = 0;
updateOrient();
} }
float getWidth() const {return width;} float getWidth() const {return width;}
@ -44,12 +62,21 @@ class Portal : public LevelObject {
float getThickness() const {return thickness;} float getThickness() const {return thickness;}
const Vertex& getPosition() const {return pos;} const Vertex& getPosition() const {return pos;}
void setPosition(Vertex v) {pos = v;} void setPosition(Vertex v) {pos = v; updateVertices();}
float getOrientation() const {return orient;} 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 int getPriority() const {return 1;}
virtual const char* getType() const { virtual const char* getType() const {
@ -58,15 +85,37 @@ class Portal : public LevelObject {
virtual void move(float x, float y) { virtual void move(float x, float y) {
pos += Vertex(x, y); pos += Vertex(x, y);
updateVertices();
} }
virtual void rotate(float a) { virtual void rotate(float a) {
orient = fmodf(orient+a, 2*M_PI); orient = fmodf(orient+a, 2*M_PI);
updateOrient();
} }
virtual Vertex getCenter() const { virtual Vertex getCenter() const {
return pos; 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_*/ #endif /*PORTAL_H_*/

View file

@ -91,7 +91,9 @@ void Renderer::drawCross(const Vertex &m, float r) {
} }
void Renderer::renderObject(const LevelObject &object, bool selected, bool highlighted, float scale) { 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); renderRoom(*(Room*)&object, selected, highlighted, scale);
else if(object.isOfType("PlayerStart")) else if(object.isOfType("PlayerStart"))
renderPlayerStart(*(PlayerStart*)&object, selected, highlighted, scale); 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); 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); glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
fillCircle(vertex, 3/scale, 16); fillCircle(*vertex, 3.5f/scale, 16);
glLineWidth(1.0f); glLineWidth(1.0f);
glColor4f(9.0f, 0.7f, 0.0f, 0.9f); if(highlighted)
drawCircle(vertex, 3/scale, 16); 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) { 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); 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) { 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); glVertex2f(portal.getPosition().getX()+x, portal.getPosition().getY()+y);
glEnd(); 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) { void Renderer::render(const Level &level, const Rectangle &rect, float scale) {

View file

@ -25,7 +25,7 @@ class Renderer {
void renderObject(const LevelObject &object, bool selected, bool highlighted, float scale); 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 renderRoom(const Room &room, bool selected, bool highlighted, float scale);
void renderPlayerStart(const PlayerStart &start, bool selected, bool highlighted, float scale); void renderPlayerStart(const PlayerStart &start, bool selected, bool highlighted, float scale);

40
Room.h
View file

@ -3,10 +3,12 @@
#include "Polygon.h" #include "Polygon.h"
#include "LevelObject.h" #include "LevelObject.h"
#include "VertexProvider.h"
#include "LevelVertex.h"
#include <string> #include <string>
class Room : public Polygon, public LevelObject { class Room : public Polygon, public LevelObject, public VertexProvider {
private: private:
std::string name; std::string name;
float height; float height;
@ -22,9 +24,18 @@ class Room : public Polygon, public LevelObject {
float getHeight() const {return height;} float getHeight() const {return height;}
void setHeight(float height) {this->height = 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 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 { virtual const char* getType() const {
return "Room"; return "Room";
} }
@ -56,6 +67,31 @@ class Room : public Polygon, public LevelObject {
return ret / size(); 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_*/ #endif /*ROOM_H_*/

18
VertexProvider.h Normal file
View 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_*/