170 lines
3.5 KiB
C++
170 lines
3.5 KiB
C++
#include "edit.h"
|
|
#include "level.h"
|
|
#include "geometry.h"
|
|
#include <stdlib.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(vertexInPolygon(v, &l->rooms[i].polygon)) {
|
|
//hoveredRoom = &l->rooms[i];
|
|
//break;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
hasHoveredVertex = 0;
|
|
hoveredRoom = NULL;
|
|
}
|
|
}
|
|
|
|
void startAddMode() {
|
|
activeRoom = (ROOM*)calloc(1, sizeof(ROOM));
|
|
activeRoom->polygon.nVertices = 0;
|
|
activeRoom->polygon.vertices = NULL;
|
|
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 int isLineOk(LINE *l) {
|
|
LEVEL *lvl = getLevel();
|
|
LINE l2;
|
|
int i;
|
|
|
|
|
|
if(activeRoom) {
|
|
for(i = 0; i+2 < activeRoom->polygon.nVertices; i++) {
|
|
l2.v1 = activeRoom->polygon.vertices[i];
|
|
l2.v2 = activeRoom->polygon.vertices[i+1];
|
|
|
|
if(lineIntersection(l, &l2, NULL) == INTERSECTION_SEGMENT_SEGMENT) return 0;
|
|
}
|
|
|
|
if(activeRoom->polygon.nVertices > 1) {
|
|
l2.v1 = activeRoom->polygon.vertices[activeRoom->polygon.nVertices-2];
|
|
l2.v2 = activeRoom->polygon.vertices[activeRoom->polygon.nVertices-1];
|
|
if(vertexOnLine(&l->v2, &l2)) return 0;
|
|
}
|
|
}
|
|
|
|
for(i = 0; i < lvl->nRooms; i++) {
|
|
if(linePolygonIntersection(l, &lvl->rooms[i].polygon))
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
int isVertexOk(Vertex *v) {
|
|
LEVEL *lvl = getLevel();
|
|
LINE l;
|
|
int i;
|
|
|
|
for(i = 0; i < lvl->nRooms; i++) {
|
|
if(vertexInPolygon(v, &lvl->rooms[i].polygon)) return 0;
|
|
}
|
|
|
|
if(!(getActiveRoom() && getActiveRoom()->polygon.nVertices))
|
|
return 1;
|
|
|
|
l.v1 = getActiveRoom()->polygon.vertices[getActiveRoom()->polygon.nVertices-1];
|
|
l.v2 = *v;
|
|
|
|
return isLineOk(&l);
|
|
}
|
|
|
|
|
|
|
|
int isPolygonOk(POLYGON *polygon) {
|
|
LEVEL *lvl = getLevel();
|
|
LINE l, l2;
|
|
int i, j;
|
|
|
|
if(!polygon->nVertices) return 0;
|
|
|
|
for(i = 0; i < lvl->nRooms; i++) {
|
|
if(!lvl->rooms[i].polygon.nVertices) continue;
|
|
|
|
if(vertexInPolygon(&polygon->vertices[0], &lvl->rooms[i].polygon))
|
|
return 0;
|
|
|
|
if(vertexInPolygon(&lvl->rooms[i].polygon.vertices[0], polygon))
|
|
return 0;
|
|
}
|
|
|
|
if(polygon->nVertices == 1)
|
|
return 1;
|
|
|
|
for(i = 0; i < polygon->nVertices; i++) {
|
|
l.v1 = polygon->vertices[i];
|
|
l.v2 = polygon->vertices[(i+1)%polygon->nVertices];
|
|
|
|
for(j = 0; j < lvl->nRooms; j++) {
|
|
if(linePolygonIntersection(&l, &lvl->rooms[j].polygon))
|
|
return 0;
|
|
}
|
|
|
|
for(j = i+2; j < polygon->nVertices; j++) {
|
|
if(i == 0 && j == polygon->nVertices-1) continue;
|
|
|
|
l2.v1 = polygon->vertices[j];
|
|
l2.v2 = polygon->vertices[(j+1)%polygon->nVertices];
|
|
|
|
if(lineIntersection(&l, &l2, NULL) == INTERSECTION_SEGMENT_SEGMENT)
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
return 1;
|
|
}
|