Skip to content

Commit

Permalink
Add interior walls when adding touching rectangle. Split interior wal…
Browse files Browse the repository at this point in the history
…ls when adding door.
  • Loading branch information
mcglincy committed Nov 22, 2021
1 parent bf5b751 commit a10cd5d
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 30 deletions.
5 changes: 3 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# 0.8.1
- Blur interior shadows.
# 0.9.0
- Adding a rectangle alongside an existing room/wall will now preserve the interior wall.
- Adding a door within an interior wall will now split the interior wall.
- Add interior shadow on all exterior walls, interior walls, and doors.
- Reorganize floor/shadow/wall render and graphics objects for better layering and to fix some visual artifacts.

Expand Down
49 changes: 46 additions & 3 deletions scripts/dungeon.js
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,26 @@ export class Dungeon extends PlaceableObject {

async addDoor(x1, y1, x2, y2) {
const newState = this.history[this.historyIndex].clone();
const doorPoly = geo.twoPointsToLineString(x1, y1, x2, y2);

// possibly split interior walls
const wallsToDelete = [];
const wallsToAdd = [];
for (let wall of newState.interiorWalls) {
const wallPoly = geo.twoPointsToLineString(wall[0], wall[1], wall[2], wall[3]);
const contains = wallPoly.contains(doorPoly);
if (contains) {
wallsToDelete.push(wall);
// TODO: how should we handle coordinate ordering? Does JTS do this for us?
// TODO: apparently not, and we have to do the reordering ourselves
const wallCoords = wallPoly.getCoordinates();
const doorCoords = doorPoly.getCoordinates();
wallsToAdd.push([wallCoords[0].x, wallCoords[0].y, doorCoords[0].x, doorCoords[0].y]);
wallsToAdd.push([doorCoords[1].x, doorCoords[1].y, wallCoords[1].x, wallCoords[1].y]);
}
}
newState.interiorWalls = newState.interiorWalls.filter(w => wallsToDelete.indexOf(w) === -1);
newState.interiorWalls = newState.interiorWalls.concat(wallsToAdd);
newState.doors.push([x1, y1, x2, y2]);
await this.pushState(newState);
}
Expand All @@ -163,10 +183,10 @@ export class Dungeon extends PlaceableObject {
}

async subtractInteriorWalls(rect) {
const rectPoly = geo.rectToPolygon(rect);
const poly = geo.rectToPolygon(rect);
const wallsToKeep = this.history[this.historyIndex].interiorWalls.filter(w => {
const wallPoly = geo.twoPointsToLineString(w[0], w[1], w[2], w[3]);
return !rectPoly.intersects(wallPoly);
return !poly.intersects(wallPoly);
});
if (wallsToKeep.length != this.history[this.historyIndex].interiorWalls.length) {
const newState = this.history[this.historyIndex].clone();
Expand All @@ -176,9 +196,32 @@ export class Dungeon extends PlaceableObject {
}

async _addPoly(poly) {
const newState = this.history[this.historyIndex].clone();
const oldState = this.history[this.historyIndex];
const newState = oldState.clone();
if (newState.geometry) {
newState.geometry = newState.geometry.union(poly);
const touches = oldState.geometry.touches(poly);
if (touches) {
const intersection = oldState.geometry.intersection(poly);
const coordinates = intersection.getCoordinates();
// TODO: do we need to handle more complicated overlaps, GeometryCollection etc?
// this coordinate 2-step is flimsy
if (coordinates.length > 1 && coordinates.length % 2 === 0) {
console.log(coordinates);
for (let i = 0; i < coordinates.length; i+=2) {
newState.interiorWalls.push([coordinates[i].x, coordinates[i].y, coordinates[i+1].x, coordinates[i+1].y]);
}
}
} else {
// also nuke any interior walls in this new poly
const wallsToKeep = newState.interiorWalls.filter(w => {
const wallPoly = geo.twoPointsToLineString(w[0], w[1], w[2], w[3]);
return !poly.intersects(wallPoly);
});
if (wallsToKeep.length != newState.interiorWalls.length) {
newState.interiorWalls = wallsToKeep;
}
}
} else {
newState.geometry = poly;
}
Expand Down
21 changes: 1 addition & 20 deletions scripts/renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -360,26 +360,6 @@ const drawDoorShadow = (gfx, config, door) => {
const rectEnd = [door[0] + (deltaX * rectEndFraction), door[1] + (deltaY * rectEndFraction)]
const doorRect = rectangleForSegment(config, jamb1End[0], jamb1End[1], rectEnd[0], rectEnd[1]);

// gfx.lineStyle({
// width: config.wallThickness / 2.0 + config.interiorShadowThickness,
// color: PIXI.utils.string2hex(config.interiorShadowColor),
// alpha: config.interiorShadowOpacity,
// // alignment: 1, // outside
// alignment: 0.5,
// join: "round"
// });
console.log(doorRect);

// gfx.moveTo(doorRect[0], doorRect[1]);
// gfx.lineTo(doorRect[2], doorRect[3]);
// gfx.drawPolygon(
// doorRect[0], doorRect[1],
// doorRect[2], doorRect[3],
// doorRect[4], doorRect[5],
// doorRect[6], doorRect[7],
// doorRect[0], doorRect[1]
// );

gfx.lineStyle({
// wide enough to be exposed on either side
width: config.wallThickness + 2.0 * config.interiorShadowThickness,
Expand All @@ -396,6 +376,7 @@ const drawDoorShadow = (gfx, config, door) => {
gfx.moveTo(jamb1End[0], jamb1End[1]);
gfx.lineTo(door[0], door[1]);

// door rectangle
gfx.drawPolygon(
doorRect[0], doorRect[1],
doorRect[2], doorRect[3],
Expand Down
5 changes: 0 additions & 5 deletions scripts/wallmaker.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,14 @@ const deleteAllWalls = async () => {
// which causes an infinite loop of redraw/refresh.
// so avoid it :P
const walls = canvas.scene.getEmbeddedCollection("Wall");

const keys = Array.from(walls.keys());
console.log("======");
console.log(`${keys.length} total walls`);

const ids = [];
for (const wall of walls) {
const flag = wall.getFlag(DungeonDraw.MODULE_NAME, "dungeonVersion");
if (flag) {
ids.push(wall.id);
}
}
console.log(`Deleting ${ids.length} walls`);
await canvas.scene.deleteEmbeddedDocuments("Wall", ids);
} catch(error) {
console.error(error);
Expand Down

0 comments on commit a10cd5d

Please sign in to comment.