175 lines
3.6 KiB
C++
175 lines
3.6 KiB
C++
#include "edit.h"
|
|
#include "level.h"
|
|
#include "geometry.h"
|
|
|
|
|
|
static int editMode = EDIT_MODE_VIEW;
|
|
|
|
static ROOM *activeRoom = NULL;
|
|
static ROOM *hoveredRoom = NULL;
|
|
|
|
static Vertex hoveredVertex;
|
|
static int hasHoveredVertex = 0;
|
|
|
|
int getEditMode() {
|
|
return editMode;
|
|
}
|
|
|
|
ROOM *getActiveRoom() {
|
|
return activeRoom;
|
|
}
|
|
|
|
void setActiveRoom(ROOM *room) {
|
|
activeRoom = room;
|
|
|
|
if(room == NULL) {
|
|
editMode = EDIT_MODE_VIEW;
|
|
}
|
|
else if(editMode == EDIT_MODE_VIEW) {
|
|
editMode = EDIT_MODE_SELECTED;
|
|
}
|
|
}
|
|
|
|
Vertex *getHoveredVertex() {
|
|
if(hasHoveredVertex) return &hoveredVertex;
|
|
else return NULL;
|
|
}
|
|
|
|
void setHoveredVertex(Vertex *v) {
|
|
int i;
|
|
LEVEL *l;
|
|
|
|
if(v) {
|
|
hasHoveredVertex = 1;
|
|
hoveredVertex = *v;
|
|
|
|
l = getLevel();
|
|
hoveredRoom = NULL;
|
|
|
|
for(i = 0; i < l->nRooms; i++) {
|
|
if(l->rooms[i].polygon.contains(*v)) {
|
|
hoveredRoom = &l->rooms[i];
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
hasHoveredVertex = 0;
|
|
hoveredRoom = NULL;
|
|
}
|
|
}
|
|
|
|
void startAddMode() {
|
|
activeRoom = (ROOM*)calloc(1, sizeof(ROOM));
|
|
activeRoom->polygon = Polygon();
|
|
activeRoom->name = (char*)calloc(1, sizeof(unsigned char));
|
|
|
|
editMode = EDIT_MODE_ADD;
|
|
}
|
|
|
|
void endAddMode() {
|
|
editMode = activeRoom ? EDIT_MODE_SELECTED : EDIT_MODE_VIEW;
|
|
}
|
|
|
|
ROOM *getHoveredRoom() {
|
|
return hoveredRoom;
|
|
}
|
|
|
|
static bool isLineOk(LINE *l) {
|
|
LEVEL *lvl = getLevel();
|
|
LINE l2;
|
|
|
|
|
|
if(activeRoom) {
|
|
for(int i = 0; i+2 < activeRoom->polygon.size(); i++) {
|
|
l2.v1 = activeRoom->polygon[i];
|
|
l2.v2 = activeRoom->polygon[i+1];
|
|
|
|
if(lineIntersection(l, &l2, NULL) == INTERSECTION_SEGMENT_SEGMENT) return false;
|
|
}
|
|
|
|
if(activeRoom->polygon.size() > 1) {
|
|
l2.v1 = activeRoom->polygon[activeRoom->polygon.size()-2];
|
|
l2.v2 = activeRoom->polygon.back();
|
|
if(vertexOnLine(&l->v2, &l2)) return false;
|
|
}
|
|
}
|
|
|
|
for(int i = 0; i < lvl->nRooms; i++) {
|
|
if(lvl->rooms[i].polygon.intersects(l))
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool isVertexOk(Vertex *v) {
|
|
LEVEL *lvl = getLevel();
|
|
LINE l;
|
|
int i;
|
|
|
|
|
|
for(i = 0; i < lvl->nRooms; i++) {
|
|
if(lvl->rooms[i].polygon.contains(*v)) return false;
|
|
}
|
|
|
|
if(!(getActiveRoom() && !getActiveRoom()->polygon.empty()))
|
|
return true;
|
|
|
|
l.v1 = getActiveRoom()->polygon.back();
|
|
l.v2 = *v;
|
|
|
|
return isLineOk(&l);
|
|
}
|
|
|
|
|
|
|
|
bool isPolygonOk(Polygon *polygon) {
|
|
LEVEL *lvl = getLevel();
|
|
LINE l, l2;
|
|
|
|
if(polygon->empty()) return false;
|
|
|
|
for(int i = 0; i < lvl->nRooms; i++) {
|
|
if(lvl->rooms[i].polygon.empty()) continue;
|
|
|
|
if(lvl->rooms[i].polygon.contains(polygon->front()));
|
|
return false;
|
|
|
|
if(polygon->contains(lvl->rooms[i].polygon.front()));
|
|
return false;
|
|
}
|
|
|
|
if(polygon->size() == 1)
|
|
return true;
|
|
|
|
for(Polygon::const_iterator it = polygon->begin(); it != polygon->end(); it++) {
|
|
Polygon::const_iterator it2 = it+1;
|
|
if(it2 == polygon->end()) it2 = polygon->begin();
|
|
|
|
l.v1 = *it;
|
|
l.v2 = *it2;
|
|
|
|
for(int i = 0; i < lvl->nRooms; i++) {
|
|
if(lvl->rooms[i].polygon.intersects(&l))
|
|
return false;
|
|
}
|
|
|
|
if(it2 != polygon->begin()) {
|
|
for(Polygon::const_iterator it3 = it2+1; it3 != polygon->end(); it3++) {
|
|
Polygon::const_iterator it4 = it3+1;
|
|
if(it4 == polygon->end()) it4 = polygon->begin();
|
|
|
|
if(it == polygon->begin() && it4 == polygon->begin()) continue;
|
|
|
|
l2.v1 = *it3;
|
|
l2.v2 = *it4;
|
|
|
|
if(lineIntersection(&l, &l2, NULL) == INTERSECTION_SEGMENT_SEGMENT)
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|