mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-10-27 06:20:02 +00:00
Fixed object placement bounds
- Native structure vetoes use the full transformed object bounds - Object copies hold the volume read lock during mutation-sensitive reads - Object copies retain independent tiles without redundant coordinate clones - Regression tests cover oblique rotations and off-center object origins - Concurrent copy tests verify volume lock ownership
This commit is contained in:
1 parent
17c927acdd
commit
d55c77572b
4 files changed
+129
-22
No files matched your search
@@ -110,7 +110,7 @@ public class IrisObject extends IrisRegistrant {
|
||||
this.d = d;
|
||||
center = new Vector3i(w / 2, h / 2, d / 2);
|
||||
shrinkOffset = new Vector3i(0, 0, 0);
|
||||
var lock = new ReentrantReadWriteLock();
|
||||
ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
|
||||
readLock = lock.readLock();
|
||||
writeLock = lock.writeLock();
|
||||
}
|
||||
@@ -135,17 +135,22 @@ public class IrisObject extends IrisRegistrant {
|
||||
return aabb.aquire(() -> getAABBFor(new IrisBlockVector(w, h, d)));
|
||||
}
|
||||
|
||||
public synchronized IrisObject copy() {
|
||||
IrisObject o = new IrisObject(w, h, d);
|
||||
o.setLoadKey(getLoadKey());
|
||||
o.setLoader(getLoader());
|
||||
o.setLoadFile(getLoadFile());
|
||||
o.setCenter(getCenter().clone());
|
||||
public IrisObject copy() {
|
||||
readLock.lock();
|
||||
try {
|
||||
IrisObject copy = new IrisObject(w, h, d);
|
||||
copy.setLoadKey(getLoadKey());
|
||||
copy.setLoader(getLoader());
|
||||
copy.setLoadFile(getLoadFile());
|
||||
copy.setCenter(getCenter().clone());
|
||||
|
||||
blocks.forEach((i, v) -> o.blocks.put(i.clone(), v));
|
||||
states.forEach((i, v) -> o.states.put(i.clone(), v.clone()));
|
||||
blocks.forEach(copy.blocks::put);
|
||||
states.forEach((position, tile) -> copy.states.put(position, tile.clone()));
|
||||
|
||||
return o;
|
||||
return copy;
|
||||
} finally {
|
||||
readLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void readLegacy(InputStream in) throws IOException {
|
||||
|
||||
@@ -350,7 +350,7 @@ final class IrisObjectPlacementRunner {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!rawStructurePiece && nativeStructureVetoes(placer, config, spin, translating, translateOffset, ceilingHang,
|
||||
if (!rawStructurePiece && nativeStructureVetoes(placer, config, spin, placementBounds, translating, translateOffset, ceilingHang,
|
||||
yv < 0 && config.getMode() == ObjectPlaceMode.PAINT, warpMargin, x, y + yrand, z)) {
|
||||
return -1;
|
||||
}
|
||||
@@ -955,7 +955,7 @@ final class IrisObjectPlacementRunner {
|
||||
* near this placement means no per block work at all. Only when the placement envelope meets a piece does the
|
||||
* precise pass run, and the first solid block inside a piece rejects the whole object before any write.
|
||||
*/
|
||||
private boolean nativeStructureVetoes(IObjectPlacer placer, IrisObjectPlacement config, SpinKernel spin,
|
||||
private boolean nativeStructureVetoes(IObjectPlacer placer, IrisObjectPlacement config, SpinKernel spin, TransformedBounds bounds,
|
||||
boolean translating, IrisBlockVector translateOffset, boolean ceilingHang,
|
||||
boolean paint, int warpMargin, int x, int y, int z) {
|
||||
Engine engine = placer.getEngine();
|
||||
@@ -963,23 +963,21 @@ final class IrisObjectPlacementRunner {
|
||||
return false;
|
||||
}
|
||||
|
||||
int margin = (Math.max(self.getW(), Math.max(self.getH(), self.getD())) / 2) + 1 + warpMargin;
|
||||
if (translating) {
|
||||
margin += Math.max(Math.abs(translateOffset.getBlockX()),
|
||||
Math.max(Math.abs(translateOffset.getBlockY()), Math.abs(translateOffset.getBlockZ())));
|
||||
}
|
||||
|
||||
KList<NativeStructureVolume> volumes = engine.getNativeStructureVolumes(x - margin, z - margin, x + margin, z + margin);
|
||||
int minX = x + bounds.minX();
|
||||
int maxX = x + bounds.maxX();
|
||||
int minZ = z + bounds.minZ();
|
||||
int maxZ = z + bounds.maxZ();
|
||||
KList<NativeStructureVolume> volumes = engine.getNativeStructureVolumes(minX, minZ, maxX, maxZ);
|
||||
if (volumes == null || volumes.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int worldY = y + engine.getMinHeight();
|
||||
int envelopeMinY = paint ? Integer.MIN_VALUE : worldY - margin;
|
||||
int envelopeMaxY = paint ? Integer.MAX_VALUE : worldY + margin;
|
||||
int envelopeMinY = paint ? Integer.MIN_VALUE : worldY + bounds.minY() - warpMargin;
|
||||
int envelopeMaxY = paint ? Integer.MAX_VALUE : worldY + bounds.maxY() + warpMargin;
|
||||
boolean envelopeMeetsPiece = false;
|
||||
for (NativeStructureVolume volume : volumes) {
|
||||
if (volume.intersects(x - margin, envelopeMinY, z - margin, x + margin, envelopeMaxY, z + margin)) {
|
||||
if (volume.intersects(minX, envelopeMinY, minZ, maxX, envelopeMaxY, maxZ)) {
|
||||
envelopeMeetsPiece = true;
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user