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;
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);

View file

@ -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;

View file

@ -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
View file

@ -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);
}
};

View file

@ -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
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 {
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);
}

View file

@ -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;
Vertex vertices[4];
float s, c;
float s = sinf(orient);
float c = cosf(orient);
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_*/

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) {
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) {

View file

@ -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
View file

@ -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
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_*/