abstracted out room size and variance. also tried centering window panes properly

This commit is contained in:
mmaheshwari2 2025-02-10 11:19:12 -08:00
parent b53dd4744f
commit b7bdbf7759
2 changed files with 71 additions and 54 deletions

View file

@ -1,4 +1,4 @@
import { Vec3 } from 'vec3';
import {Vec3} from 'vec3';
export class ConstructionTaskValidator {
constructor(data, agent) {
@ -301,20 +301,28 @@ export class Blueprint {
* @param n height of the 3D space
* @param p depth of the 3D space
* @param rooms Number of rooms to attempt to generate
* @param minRoomWidth
* @param minRoomLength
* @param minRoomDepth
* @param roomVariance How much the room size will vary
* @param wrapping material of wrapping (air, glass, etc...) -> default is air
* @param carpetStyle 0,1,2 increasingly more complex
* @param windowStyle 0,1,2 increasingly more complex
* @param complexity 0,1,2,3,4 for increasingly complex materials for room generation
* @returns a blueprint matrix
* @returns a blueprint object
*/
export function proceduralGeneration(m = 20,
n = 20,
p = 20,
rooms = 8,
wrapping = "air",
carpetStyle = 1,
windowStyle = 1,
complexity = 4) {
n = 20,
p = 20,
rooms = 8,
minRoomWidth = 5,
minRoomLength = 5,
minRoomDepth = 6,
roomVariance = 5,
wrapping = "air",
carpetStyle = 1,
windowStyle = 1,
complexity = 4) {
// Build 3D space
const matrix = Array.from({length: p}, () =>
Array.from({length: m}, () =>
@ -469,12 +477,14 @@ export function proceduralGeneration(m = 20,
// Takes in a room and randomly converts some faces to be windows
// todo if time: the centering of windows is still kinda buggy
function addWindowsAsSquares(matrix, x, y, z, newLength, newWidth, newDepth, material) {
// Matrix dimensions
const matrixDepth = matrix.length;
const matrixLength = matrix[0].length;
const matrixWidth = matrix[0][0].length;
const windowX = Math.ceil(minRoomWidth/2)
const windowY = Math.ceil(minRoomLength/2)
const windowZ = Math.ceil(minRoomDepth/2)
// Helper function to check if coordinates are within bounds
function isInBounds(z, x, y) {
@ -485,11 +495,11 @@ export function proceduralGeneration(m = 20,
// Front and back faces (z is constant)
if (Math.random() < 0.8) {
let centerX = x + Math.floor(newLength / 2);
let centerY = y + Math.floor(newWidth / 2);
let centerX = x + Math.floor(newLength / 2 - windowX/2);
let centerY = y + Math.floor(newWidth / 2 - windowY/2);
for (let dx = -1; dx <= 0; dx++) {
for (let dy = -1; dy <= 0; dy++) {
for (let dx = 0; dx <= windowX; dx++) {
for (let dy = 0; dy <= windowY; dy++) {
let frontZ = z;
let backZ = z + newDepth - 1;
@ -507,11 +517,11 @@ export function proceduralGeneration(m = 20,
// Left and right faces (x is constant)
if (Math.random() < 0.8) {
let centerZ = z + Math.floor(newDepth / 2);
let centerY = y + Math.floor(newWidth / 2);
let centerZ = z + Math.floor(newDepth / 2 - windowZ/2);
let centerY = y + Math.floor(newWidth / 2 - windowY/2);
for (let dz = -1; dz <= 0; dz++) {
for (let dy = -1; dy <= 0; dy++) {
for (let dz = 0; dz <= windowZ; dz++) {
for (let dy = 0; dy <= windowY; dy++) {
let leftX = x;
let rightX = x + newLength - 1;
@ -529,11 +539,11 @@ export function proceduralGeneration(m = 20,
// Top and bottom faces (y is constant)
if (Math.random() < 0.8) {
let centerX = x + Math.floor(newLength / 2);
let centerZ = z + Math.floor(newDepth / 2);
let centerX = x + Math.floor(newLength / 2 - windowX/2);
let centerZ = z + Math.floor(newDepth / 2 - windowZ / 2);
for (let dx = -1; dx <= 0; dx++) {
for (let dz = -1; dz <= 0; dz++) {
for (let dx = 0; dx <= windowX; dx++) {
for (let dz = 0; dz <= windowZ; dz++) {
let bottomY = y;
let topY = y + newWidth - 1;
@ -649,7 +659,7 @@ export function proceduralGeneration(m = 20,
}
}
function addCarpet(probability, matrix, newX, newY, newZ, newLength, newWidth) {
function addCarpet(probability, matrix, newX, newY, newZ, newLength, newWidth, material) {
let colors = ["blue", "cyan", "light_blue", "lime"];
// Iterate through the dimensions of the room
@ -660,7 +670,7 @@ export function proceduralGeneration(m = 20,
let z = newZ; // Start at floor level
// Check if there is floor (not air)
if (matrix[z][x][y] === 'stone') {
if (matrix[z][x][y] === material) {
// Consider a random probability of adding a carpet
if (Math.random() < probability) {
// Choose a random color for the carpet
@ -715,10 +725,10 @@ export function proceduralGeneration(m = 20,
case 0:
break;
case 1:
addCarpet(0.3,matrix,newX, newY, newZ, newLength, newWidth);
addCarpet(0.3,matrix,newX, newY, newZ, newLength, newWidth, material);
break;
case 2:
addCarpet(0.7,matrix,newX, newY, newZ, newLength, newWidth)
addCarpet(0.7,matrix,newX, newY, newZ, newLength, newWidth, material)
break;
}
@ -737,9 +747,9 @@ export function proceduralGeneration(m = 20,
// dimensions of room
const newLength = Math.max(6, Math.floor(Math.random() * 6) + 4);
const newWidth = Math.max(6, Math.floor(Math.random() * 6) + 4);
const newDepth = Math.max(5, Math.floor(Math.random() * 5) + 2);
const newLength = Math.max(minRoomLength, Math.floor(Math.random() * roomVariance) + minRoomLength);
const newWidth = Math.max(minRoomWidth, Math.floor(Math.random() * roomVariance) + minRoomWidth);
const newDepth = Math.max(minRoomDepth, Math.floor(Math.random() * Math.floor(roomVariance/2) ) + minRoomDepth );
let newX, newY, newZ;
// first room is special
@ -897,10 +907,7 @@ export function proceduralGeneration(m = 20,
}
}
return matrix
return matrixToBlueprint(matrix)
}

View file

@ -106,6 +106,10 @@ function generateAbstractRooms(m, n, p, rooms = 5) {
* @param n height of the 3D space
* @param p depth of the 3D space
* @param rooms Number of rooms to attempt to generate
* @param minRoomWidth
* @param minRoomLength
* @param minRoomDepth
* @param roomVariance How much the room size will vary
* @param wrapping material of wrapping (air, glass, etc...) -> default is air
* @param carpetStyle 0,1,2 increasingly more complex
* @param windowStyle 0,1,2 increasingly more complex
@ -117,6 +121,10 @@ function proceduralGeneration(m = 20,
n = 20,
p = 20,
rooms = 8,
minRoomWidth = 5,
minRoomLength = 5,
minRoomDepth = 6,
roomVariance = 5,
wrapping = "air",
carpetStyle = 1,
windowStyle = 1,
@ -275,12 +283,14 @@ function proceduralGeneration(m = 20,
// Takes in a room and randomly converts some faces to be windows
// todo if time: the centering of windows is still kinda buggy
function addWindowsAsSquares(matrix, x, y, z, newLength, newWidth, newDepth, material) {
// Matrix dimensions
const matrixDepth = matrix.length;
const matrixLength = matrix[0].length;
const matrixWidth = matrix[0][0].length;
const windowX = Math.ceil(minRoomWidth/2)
const windowY = Math.ceil(minRoomLength/2)
const windowZ = Math.ceil(minRoomDepth/2)
// Helper function to check if coordinates are within bounds
function isInBounds(z, x, y) {
@ -291,11 +301,11 @@ function proceduralGeneration(m = 20,
// Front and back faces (z is constant)
if (Math.random() < 0.8) {
let centerX = x + Math.floor(newLength / 2);
let centerY = y + Math.floor(newWidth / 2);
let centerX = x + Math.floor(newLength / 2 - windowX/2);
let centerY = y + Math.floor(newWidth / 2 - windowY/2);
for (let dx = -1; dx <= 0; dx++) {
for (let dy = -1; dy <= 0; dy++) {
for (let dx = 0; dx <= windowX; dx++) {
for (let dy = 0; dy <= windowY; dy++) {
let frontZ = z;
let backZ = z + newDepth - 1;
@ -313,11 +323,11 @@ function proceduralGeneration(m = 20,
// Left and right faces (x is constant)
if (Math.random() < 0.8) {
let centerZ = z + Math.floor(newDepth / 2);
let centerY = y + Math.floor(newWidth / 2);
let centerZ = z + Math.floor(newDepth / 2 - windowZ/2);
let centerY = y + Math.floor(newWidth / 2 - windowY/2);
for (let dz = -1; dz <= 0; dz++) {
for (let dy = -1; dy <= 0; dy++) {
for (let dz = 0; dz <= windowZ; dz++) {
for (let dy = 0; dy <= windowY; dy++) {
let leftX = x;
let rightX = x + newLength - 1;
@ -335,11 +345,11 @@ function proceduralGeneration(m = 20,
// Top and bottom faces (y is constant)
if (Math.random() < 0.8) {
let centerX = x + Math.floor(newLength / 2);
let centerZ = z + Math.floor(newDepth / 2);
let centerX = x + Math.floor(newLength / 2 - windowX/2);
let centerZ = z + Math.floor(newDepth / 2 - windowZ / 2);
for (let dx = -1; dx <= 0; dx++) {
for (let dz = -1; dz <= 0; dz++) {
for (let dx = 0; dx <= windowX; dx++) {
for (let dz = 0; dz <= windowZ; dz++) {
let bottomY = y;
let topY = y + newWidth - 1;
@ -455,7 +465,7 @@ function proceduralGeneration(m = 20,
}
}
function addCarpet(probability, matrix, newX, newY, newZ, newLength, newWidth) {
function addCarpet(probability, matrix, newX, newY, newZ, newLength, newWidth, material) {
let colors = ["blue", "cyan", "light_blue", "lime"];
// Iterate through the dimensions of the room
@ -466,7 +476,7 @@ function proceduralGeneration(m = 20,
let z = newZ; // Start at floor level
// Check if there is floor (not air)
if (matrix[z][x][y] === 'stone') {
if (matrix[z][x][y] === material) {
// Consider a random probability of adding a carpet
if (Math.random() < probability) {
// Choose a random color for the carpet
@ -521,10 +531,10 @@ function proceduralGeneration(m = 20,
case 0:
break;
case 1:
addCarpet(0.3,matrix,newX, newY, newZ, newLength, newWidth);
addCarpet(0.3,matrix,newX, newY, newZ, newLength, newWidth, material);
break;
case 2:
addCarpet(0.7,matrix,newX, newY, newZ, newLength, newWidth)
addCarpet(0.7,matrix,newX, newY, newZ, newLength, newWidth, material)
break;
}
@ -543,9 +553,9 @@ function proceduralGeneration(m = 20,
// dimensions of room
const newLength = Math.max(6, Math.floor(Math.random() * 6) + 4);
const newWidth = Math.max(6, Math.floor(Math.random() * 6) + 4);
const newDepth = Math.max(5, Math.floor(Math.random() * 5) + 2);
const newLength = Math.max(minRoomLength, Math.floor(Math.random() * roomVariance) + minRoomLength);
const newWidth = Math.max(minRoomWidth, Math.floor(Math.random() * roomVariance) + minRoomWidth);
const newDepth = Math.max(minRoomDepth, Math.floor(Math.random() * Math.floor(roomVariance/2) ) + minRoomDepth );
let newX, newY, newZ;
// first room is special
@ -776,7 +786,7 @@ function printMatrix(matrix) {
// main:
const resultMatrix = proceduralGeneration(20, 10, 20, 10, "air", 1, 1, 4);
const resultMatrix = proceduralGeneration(30, 30, 30, 30, 6, 6, 6, 6,"air", 1, 1, 4);
printMatrix(resultMatrix)
let blueprint = matrixToBlueprint(resultMatrix,[194, -60, -94])