Skip to content

Commit

Permalink
Better area filling algorithm for CARGO_ITEMS
Browse files Browse the repository at this point in the history
Technically this is O(C*n^3) runtime, but n and C are quite small.
  • Loading branch information
cam72cam committed Oct 1, 2023
1 parent 9da5f4e commit a3ec2f8
Showing 1 changed file with 61 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -67,26 +67,61 @@ public <T extends Freight> void postRender(T stock, RenderState state) {


for (ModelComponent comp : components) {
double itemsX = comp.length();
double itemsY = comp.height();
double itemsZ = comp.width();

double modelVolume = itemsX * itemsY * itemsZ;
int cargoVolume = (int) Math.ceil(stock.cargoItems.getSlotCount() * modelVolume/totalVolume);

double volumeRatio = Math.pow(cargoVolume / modelVolume, 0.3333);
itemsY = Math.ceil(itemsY * volumeRatio);
double xSize = comp.length();
double ySize = comp.height();
double zSize = comp.width();

double modelVolume = xSize * ySize * zSize;
int cargoSlots = (int) Math.ceil(stock.cargoItems.getSlotCount() * modelVolume/totalVolume);

// Goal: We want the biggest cubes to fill in the space
// Define fitment: How close each of the dimensions are to their reference given a specific scale
// These numbers are small enough that we can test each permutation.

// The "ideal" storage ratio
double ratio = Math.pow(cargoSlots / modelVolume, 0.33333);
double xItemsIdeal = ratio * xSize;
double yItemsIdeal = ratio * ySize;
double zItemsIdeal = ratio * zSize;

double bestFit = Double.MAX_VALUE;
int xItems = (int)Math.round(xItemsIdeal);
int yItems = (int)Math.round(yItemsIdeal);
int zItems = (int)Math.round(zItemsIdeal);

for (int x = 1; x < cargoSlots; x++) {
for (int y = 1; y < cargoSlots; y++) {
for (int z = 1; z < cargoSlots; z++) {
int currentSlots = x * y * z;
if (currentSlots < cargoSlots) {
continue;
}
double fitSize = Math.abs(1 - x / xItemsIdeal) + Math.abs(1 - y / yItemsIdeal) + Math.abs(1 - z / zItemsIdeal);
double fitRatio = Math.max(xSize / x, Math.max(ySize / y, zSize / z));
int fitItems = Math.abs(1 - currentSlots / cargoSlots);
double fit = fitSize + fitItems + fitRatio;
if (fit < bestFit) {
bestFit = fit;
xItems = x;
yItems = y;
zItems = z;
}
}
}
}

modelVolume = itemsX * itemsY * itemsZ;
volumeRatio = Math.pow(cargoVolume / modelVolume, 0.3333);
itemsZ = Math.ceil(itemsZ * volumeRatio);
double xScale = xSize / xItems;
double yScale = ySize / yItems;
double zScale = zSize / zItems;
if (!comp.key.contains("STRETCHED")) {
xScale = yScale = zScale = Math.min(xScale, Math.min(yScale, zScale));
}

modelVolume = itemsX * itemsY * itemsZ;
volumeRatio = cargoVolume / modelVolume;
itemsX = Math.ceil(itemsX * volumeRatio);
// Center X, Z
Vec3d offset = comp.min.add((xSize - xItems * xScale)/2,0,(zSize - zItems * zScale)/2);

int renderSlot = 0;
for (int i = slotOffset; i < Math.min(slotOffset+ cargoVolume, stock.cargoItems.getSlotCount()); i++) {
for (int i = slotOffset; i < Math.min(slotOffset+ cargoSlots, stock.cargoItems.getSlotCount()); i++) {
ItemStack stack = stock.cargoItems.get(i);
if (stack.isEmpty()) {
continue;
Expand Down Expand Up @@ -133,21 +168,18 @@ public <T extends Freight> void postRender(T stock, RenderState state) {
continue;
}
}
int x = renderSlot % (int) itemsX;
int z = (renderSlot / (int) itemsX) % (int) itemsZ;
int y = (renderSlot / (int) itemsX / (int) itemsZ) % (int) itemsY;

double scaleX = comp.length() / itemsX;
double scaleY = comp.height() / itemsY;
double scaleZ = comp.width() / itemsZ;
if (!comp.key.contains("STRETCHED")) {
scaleX = scaleY = scaleZ = Math.min(comp.length() / itemsX, Math.min(comp.height() / itemsY, comp.width() / itemsZ));
}
int z = renderSlot % zItems;
int x = (renderSlot / zItems) % xItems;
int y = (renderSlot / zItems / xItems) % yItems;

// Fill from center Z and X
z = zItems/2 + ((z % 2 == 0) ? z/2 : -(z+1)/2);
x = xItems/2 + ((x % 2 == 0) ? x/2 : -(x+1)/2);

Matrix4 matrix = new Matrix4()
//.scale(stock.gauge.scale(), stock.gauge.scale(), stock.gauge.scale())
.translate(comp.min.x, comp.min.y, comp.min.z)
.scale(scaleX, scaleY, scaleZ)
.translate(offset.x, offset.y, offset.z)
.scale(xScale, yScale, zScale)
.translate(0.5, 0.5, 0.5)
.translate(x, y, z);

Expand All @@ -160,7 +192,7 @@ public <T extends Freight> void postRender(T stock, RenderState state) {
model.addItem(stack, matrix);
renderSlot++;
}
slotOffset += cargoVolume;
slotOffset += cargoSlots;
}
cache.put(stock.getUUID(), model);
}
Expand Down

0 comments on commit a3ec2f8

Please sign in to comment.