mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2025-12-19 15:09:18 +00:00
optimize object maps
This commit is contained in:
@@ -38,7 +38,6 @@ import com.volmit.iris.util.decree.specialhandlers.ObjectHandler;
|
|||||||
import com.volmit.iris.util.format.C;
|
import com.volmit.iris.util.format.C;
|
||||||
import com.volmit.iris.util.math.Direction;
|
import com.volmit.iris.util.math.Direction;
|
||||||
import com.volmit.iris.util.math.RNG;
|
import com.volmit.iris.util.math.RNG;
|
||||||
import com.volmit.iris.util.scheduling.Queue;
|
|
||||||
import org.bukkit.*;
|
import org.bukkit.*;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
@@ -140,7 +139,7 @@ public class CommandObject implements DecreeExecutor {
|
|||||||
sender().sendMessage("Object Size: " + o.getW() + " * " + o.getH() + " * " + o.getD() + "");
|
sender().sendMessage("Object Size: " + o.getW() + " * " + o.getH() + " * " + o.getD() + "");
|
||||||
sender().sendMessage("Blocks Used: " + NumberFormat.getIntegerInstance().format(o.getBlocks().size()));
|
sender().sendMessage("Blocks Used: " + NumberFormat.getIntegerInstance().format(o.getBlocks().size()));
|
||||||
|
|
||||||
Queue<BlockData> queue = o.getBlocks().enqueueValues();
|
var queue = o.getBlocks().values();
|
||||||
Map<Material, Set<BlockData>> unsorted = new HashMap<>();
|
Map<Material, Set<BlockData>> unsorted = new HashMap<>();
|
||||||
Map<BlockData, Integer> amounts = new HashMap<>();
|
Map<BlockData, Integer> amounts = new HashMap<>();
|
||||||
Map<Material, Integer> materials = new HashMap<>();
|
Map<Material, Integer> materials = new HashMap<>();
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ public class IrisDepositModifier extends EngineAssignedModifier<BlockData> {
|
|||||||
if (y > k.getMaxHeight() || y < k.getMinHeight() || y > height - 2)
|
if (y > k.getMaxHeight() || y < k.getMinHeight() || y > height - 2)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (BlockVector j : clump.getBlocks().keySet()) {
|
for (BlockVector j : clump.getBlocks().keys()) {
|
||||||
int nx = j.getBlockX() + x;
|
int nx = j.getBlockX() + x;
|
||||||
int ny = j.getBlockY() + y;
|
int ny = j.getBlockY() + y;
|
||||||
int nz = j.getBlockZ() + z;
|
int nz = j.getBlockZ() + z;
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import com.volmit.iris.util.collection.KMap;
|
|||||||
import com.volmit.iris.util.context.IrisContext;
|
import com.volmit.iris.util.context.IrisContext;
|
||||||
import com.volmit.iris.util.data.B;
|
import com.volmit.iris.util.data.B;
|
||||||
import com.volmit.iris.util.data.IrisCustomData;
|
import com.volmit.iris.util.data.IrisCustomData;
|
||||||
|
import com.volmit.iris.util.data.VectorMap;
|
||||||
import com.volmit.iris.util.format.Form;
|
import com.volmit.iris.util.format.Form;
|
||||||
import com.volmit.iris.util.interpolation.IrisInterpolation;
|
import com.volmit.iris.util.interpolation.IrisInterpolation;
|
||||||
import com.volmit.iris.util.json.JSONObject;
|
import com.volmit.iris.util.json.JSONObject;
|
||||||
@@ -63,6 +64,7 @@ import java.util.concurrent.CountDownLatch;
|
|||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
|
import java.util.stream.StreamSupport;
|
||||||
|
|
||||||
@Accessors(chain = true)
|
@Accessors(chain = true)
|
||||||
@EqualsAndHashCode(callSuper = false)
|
@EqualsAndHashCode(callSuper = false)
|
||||||
@@ -81,8 +83,8 @@ public class IrisObject extends IrisRegistrant {
|
|||||||
protected transient IrisLock lock = new IrisLock("Preloadcache");
|
protected transient IrisLock lock = new IrisLock("Preloadcache");
|
||||||
@Setter
|
@Setter
|
||||||
protected transient AtomicCache<AxisAlignedBB> aabb = new AtomicCache<>();
|
protected transient AtomicCache<AxisAlignedBB> aabb = new AtomicCache<>();
|
||||||
private KMap<Vector3i, BlockData> blocks;
|
private VectorMap<BlockData> blocks;
|
||||||
private KMap<Vector3i, TileData> states;
|
private VectorMap<TileData> states;
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
private int w;
|
private int w;
|
||||||
@@ -97,8 +99,8 @@ public class IrisObject extends IrisRegistrant {
|
|||||||
private transient Vector3i center;
|
private transient Vector3i center;
|
||||||
|
|
||||||
public IrisObject(int w, int h, int d) {
|
public IrisObject(int w, int h, int d) {
|
||||||
blocks = new KMap<>();
|
blocks = new VectorMap<>();
|
||||||
states = new KMap<>();
|
states = new VectorMap<>();
|
||||||
this.w = w;
|
this.w = w;
|
||||||
this.h = h;
|
this.h = h;
|
||||||
this.d = d;
|
this.d = d;
|
||||||
@@ -170,7 +172,7 @@ public class IrisObject extends IrisRegistrant {
|
|||||||
BlockVector max = new BlockVector(Double.MIN_VALUE, Double.MIN_VALUE, Double.MIN_VALUE);
|
BlockVector max = new BlockVector(Double.MIN_VALUE, Double.MIN_VALUE, Double.MIN_VALUE);
|
||||||
BlockVector min = new BlockVector(Double.MAX_VALUE, Double.MAX_VALUE, Double.MAX_VALUE);
|
BlockVector min = new BlockVector(Double.MAX_VALUE, Double.MAX_VALUE, Double.MAX_VALUE);
|
||||||
|
|
||||||
for (BlockVector i : getBlocks().keySet()) {
|
for (BlockVector i : getBlocks().keys()) {
|
||||||
max.setX(Math.max(i.getX(), max.getX()));
|
max.setX(Math.max(i.getX(), max.getX()));
|
||||||
min.setX(Math.min(i.getX(), min.getX()));
|
min.setX(Math.min(i.getX(), min.getX()));
|
||||||
max.setY(Math.max(i.getY(), max.getY()));
|
max.setY(Math.max(i.getY(), max.getY()));
|
||||||
@@ -281,13 +283,8 @@ public class IrisObject extends IrisRegistrant {
|
|||||||
o.setLoadFile(getLoadFile());
|
o.setLoadFile(getLoadFile());
|
||||||
o.setCenter(getCenter().clone());
|
o.setCenter(getCenter().clone());
|
||||||
|
|
||||||
for (Vector3i i : getBlocks().keySet()) {
|
getBlocks().forEach((i, v) -> o.getBlocks().put(i.clone(), v.clone()));
|
||||||
o.getBlocks().put(i.clone(), Objects.requireNonNull(getBlocks().get(i)).clone());
|
getStates().forEach((i, v) -> o.getStates().put(i.clone(), v.clone()));
|
||||||
}
|
|
||||||
|
|
||||||
for (Vector3i i : getStates().keySet()) {
|
|
||||||
o.getStates().put(i.clone(), Objects.requireNonNull(getStates().get(i)).clone());
|
|
||||||
}
|
|
||||||
|
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
@@ -366,19 +363,21 @@ public class IrisObject extends IrisRegistrant {
|
|||||||
|
|
||||||
dos.writeInt(getBlocks().size());
|
dos.writeInt(getBlocks().size());
|
||||||
|
|
||||||
for (Vector3i i : getBlocks().keySet()) {
|
for (var entry : getBlocks()) {
|
||||||
|
var i = entry.getKey();
|
||||||
dos.writeShort(i.getBlockX());
|
dos.writeShort(i.getBlockX());
|
||||||
dos.writeShort(i.getBlockY());
|
dos.writeShort(i.getBlockY());
|
||||||
dos.writeShort(i.getBlockZ());
|
dos.writeShort(i.getBlockZ());
|
||||||
dos.writeShort(palette.indexOf(getBlocks().get(i).getAsString()));
|
dos.writeShort(palette.indexOf(entry.getValue().getAsString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
dos.writeInt(getStates().size());
|
dos.writeInt(getStates().size());
|
||||||
for (Vector3i i : getStates().keySet()) {
|
for (var entry : getStates()) {
|
||||||
|
var i = entry.getKey();
|
||||||
dos.writeShort(i.getBlockX());
|
dos.writeShort(i.getBlockX());
|
||||||
dos.writeShort(i.getBlockY());
|
dos.writeShort(i.getBlockY());
|
||||||
dos.writeShort(i.getBlockZ());
|
dos.writeShort(i.getBlockZ());
|
||||||
getStates().get(i).toBinary(dos);
|
entry.getValue().toBinary(dos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -420,20 +419,22 @@ public class IrisObject extends IrisRegistrant {
|
|||||||
|
|
||||||
dos.writeInt(getBlocks().size());
|
dos.writeInt(getBlocks().size());
|
||||||
|
|
||||||
for (Vector3i i : getBlocks().keySet()) {
|
for (var entry : getBlocks()) {
|
||||||
|
var i = entry.getKey();
|
||||||
dos.writeShort(i.getBlockX());
|
dos.writeShort(i.getBlockX());
|
||||||
dos.writeShort(i.getBlockY());
|
dos.writeShort(i.getBlockY());
|
||||||
dos.writeShort(i.getBlockZ());
|
dos.writeShort(i.getBlockZ());
|
||||||
dos.writeShort(palette.indexOf(getBlocks().get(i).getAsString()));
|
dos.writeShort(palette.indexOf(entry.getValue().getAsString()));
|
||||||
++c;
|
++c;
|
||||||
}
|
}
|
||||||
|
|
||||||
dos.writeInt(getStates().size());
|
dos.writeInt(getStates().size());
|
||||||
for (Vector3i i : getStates().keySet()) {
|
for (var entry : getStates()) {
|
||||||
|
var i = entry.getKey();
|
||||||
dos.writeShort(i.getBlockX());
|
dos.writeShort(i.getBlockX());
|
||||||
dos.writeShort(i.getBlockY());
|
dos.writeShort(i.getBlockY());
|
||||||
dos.writeShort(i.getBlockZ());
|
dos.writeShort(i.getBlockZ());
|
||||||
getStates().get(i).toBinary(dos);
|
entry.getValue().toBinary(dos);
|
||||||
++c;
|
++c;
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
@@ -502,7 +503,7 @@ public class IrisObject extends IrisRegistrant {
|
|||||||
BlockVector min = new BlockVector();
|
BlockVector min = new BlockVector();
|
||||||
BlockVector max = new BlockVector();
|
BlockVector max = new BlockVector();
|
||||||
|
|
||||||
for (BlockVector i : getBlocks().keySet()) {
|
for (BlockVector i : getBlocks().keys()) {
|
||||||
min.setX(Math.min(min.getX(), i.getX()));
|
min.setX(Math.min(min.getX(), i.getX()));
|
||||||
min.setY(Math.min(min.getY(), i.getY()));
|
min.setY(Math.min(min.getY(), i.getY()));
|
||||||
min.setZ(Math.min(min.getZ(), i.getZ()));
|
min.setZ(Math.min(min.getZ(), i.getZ()));
|
||||||
@@ -518,21 +519,11 @@ public class IrisObject extends IrisRegistrant {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void clean() {
|
public void clean() {
|
||||||
KMap<Vector3i, BlockData> d = new KMap<>();
|
VectorMap<BlockData> d = new VectorMap<>();
|
||||||
|
d.putAll(getBlocks());
|
||||||
|
|
||||||
for (Vector3i i : getBlocks().keySet()) {
|
VectorMap<TileData> dx = new VectorMap<>();
|
||||||
d.put(new Vector3i(i.getBlockX(), i.getBlockY(), i.getBlockZ()), Objects.requireNonNull(getBlocks().get(i)));
|
dx.putAll(getStates());
|
||||||
}
|
|
||||||
|
|
||||||
KMap<Vector3i, TileData> dx = new KMap<>();
|
|
||||||
|
|
||||||
for (Vector3i i : getBlocks().keySet()) {
|
|
||||||
d.put(new Vector3i(i.getBlockX(), i.getBlockY(), i.getBlockZ()), Objects.requireNonNull(getBlocks().get(i)));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Vector3i i : getStates().keySet()) {
|
|
||||||
dx.put(new Vector3i(i.getBlockX(), i.getBlockY(), i.getBlockZ()), Objects.requireNonNull(getStates().get(i)));
|
|
||||||
}
|
|
||||||
|
|
||||||
blocks = d;
|
blocks = d;
|
||||||
states = dx;
|
states = dx;
|
||||||
@@ -866,6 +857,9 @@ public class IrisObject extends IrisRegistrant {
|
|||||||
try {
|
try {
|
||||||
if (config.getMarkers().isNotEmpty() && placer.getEngine() != null) {
|
if (config.getMarkers().isNotEmpty() && placer.getEngine() != null) {
|
||||||
markers = new KMap<>();
|
markers = new KMap<>();
|
||||||
|
var list = StreamSupport.stream(getBlocks().keys().spliterator(), false)
|
||||||
|
.collect(KList.collector());
|
||||||
|
|
||||||
for (IrisObjectMarker j : config.getMarkers()) {
|
for (IrisObjectMarker j : config.getMarkers()) {
|
||||||
IrisMarker marker = getLoader().getMarkerLoader().load(j.getMarker());
|
IrisMarker marker = getLoader().getMarkerLoader().load(j.getMarker());
|
||||||
|
|
||||||
@@ -874,8 +868,7 @@ public class IrisObject extends IrisRegistrant {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int max = j.getMaximumMarkers();
|
int max = j.getMaximumMarkers();
|
||||||
|
for (BlockVector i : list.shuffle()) {
|
||||||
for (Vector3i i : getBlocks().k().shuffle()) {
|
|
||||||
if (max <= 0) {
|
if (max <= 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -888,8 +881,8 @@ public class IrisObject extends IrisRegistrant {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (j.isExact() ? k.matches(data) : k.getMaterial().equals(data.getMaterial())) {
|
if (j.isExact() ? k.matches(data) : k.getMaterial().equals(data.getMaterial())) {
|
||||||
boolean a = !blocks.containsKey((Vector3i) i.clone().add(new BlockVector(0, 1, 0)));
|
boolean a = !blocks.containsKey((BlockVector) i.clone().add(new BlockVector(0, 1, 0)));
|
||||||
boolean fff = !blocks.containsKey((Vector3i) i.clone().add(new BlockVector(0, 2, 0)));
|
boolean fff = !blocks.containsKey((BlockVector) i.clone().add(new BlockVector(0, 2, 0)));
|
||||||
|
|
||||||
if (!marker.isEmptyAbove() || (a && fff)) {
|
if (!marker.isEmptyAbove() || (a && fff)) {
|
||||||
markers.put(i, j.getMarker());
|
markers.put(i, j.getMarker());
|
||||||
@@ -901,7 +894,7 @@ public class IrisObject extends IrisRegistrant {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var entry : getBlocks().entrySet()) {
|
for (var entry : getBlocks()) {
|
||||||
var g = entry.getKey();
|
var g = entry.getKey();
|
||||||
BlockData d;
|
BlockData d;
|
||||||
TileData tile = null;
|
TileData tile = null;
|
||||||
@@ -1026,7 +1019,7 @@ public class IrisObject extends IrisRegistrant {
|
|||||||
if (stilting) {
|
if (stilting) {
|
||||||
readLock.lock();
|
readLock.lock();
|
||||||
IrisStiltSettings settings = config.getStiltSettings();
|
IrisStiltSettings settings = config.getStiltSettings();
|
||||||
for (Vector3i g : getBlocks().keySet()) {
|
for (BlockVector g : getBlocks().keys()) {
|
||||||
BlockData d;
|
BlockData d;
|
||||||
|
|
||||||
if (settings == null || settings.getPalette() == null) {
|
if (settings == null || settings.getPalette() == null) {
|
||||||
@@ -1138,16 +1131,16 @@ public class IrisObject extends IrisRegistrant {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void rotate(IrisObjectRotation r, int spinx, int spiny, int spinz) {
|
public void rotate(IrisObjectRotation r, int spinx, int spiny, int spinz) {
|
||||||
KMap<Vector3i, BlockData> d = new KMap<>();
|
VectorMap<BlockData> d = new VectorMap<>();
|
||||||
|
|
||||||
for (Vector3i i : getBlocks().keySet()) {
|
for (var entry : getBlocks()) {
|
||||||
d.put(new Vector3i(r.rotate(i, spinx, spiny, spinz)), r.rotate(getBlocks().get(i).clone(), spinx, spiny, spinz));
|
d.put(r.rotate(entry.getKey(), spinx, spiny, spinz), r.rotate(entry.getValue(), spinx, spiny, spinz));
|
||||||
}
|
}
|
||||||
|
|
||||||
KMap<Vector3i, TileData> dx = new KMap<>();
|
VectorMap<TileData> dx = new VectorMap<>();
|
||||||
|
|
||||||
for (Vector3i i : getStates().keySet()) {
|
for (var entry : getStates()) {
|
||||||
dx.put(new Vector3i(r.rotate(i, spinx, spiny, spinz)), getStates().get(i));
|
dx.put(r.rotate(entry.getKey(), spinx, spiny, spinz), entry.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
blocks = d;
|
blocks = d;
|
||||||
@@ -1156,9 +1149,10 @@ public class IrisObject extends IrisRegistrant {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void place(Location at) {
|
public void place(Location at) {
|
||||||
for (Vector3i i : getBlocks().keySet()) {
|
for (var entry : getBlocks()) {
|
||||||
|
var i = entry.getKey();
|
||||||
Block b = at.clone().add(0, getCenter().getY(), 0).add(i).getBlock();
|
Block b = at.clone().add(0, getCenter().getY(), 0).add(i).getBlock();
|
||||||
b.setBlockData(Objects.requireNonNull(getBlocks().get(i)), false);
|
b.setBlockData(Objects.requireNonNull(entry.getValue()), false);
|
||||||
|
|
||||||
if (getStates().containsKey(i)) {
|
if (getStates().containsKey(i)) {
|
||||||
Iris.info(Objects.requireNonNull(states.get(i)).toString());
|
Iris.info(Objects.requireNonNull(states.get(i)).toString());
|
||||||
@@ -1168,9 +1162,10 @@ public class IrisObject extends IrisRegistrant {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void placeCenterY(Location at) {
|
public void placeCenterY(Location at) {
|
||||||
for (Vector3i i : getBlocks().keySet()) {
|
for (var entry : getBlocks()) {
|
||||||
|
var i = entry.getKey();
|
||||||
Block b = at.clone().add(getCenter().getX(), getCenter().getY(), getCenter().getZ()).add(i).getBlock();
|
Block b = at.clone().add(getCenter().getX(), getCenter().getY(), getCenter().getZ()).add(i).getBlock();
|
||||||
b.setBlockData(Objects.requireNonNull(getBlocks().get(i)), false);
|
b.setBlockData(Objects.requireNonNull(entry.getValue()), false);
|
||||||
|
|
||||||
if (getStates().containsKey(i)) {
|
if (getStates().containsKey(i)) {
|
||||||
Objects.requireNonNull(getStates().get(i)).toBukkitTry(b);
|
Objects.requireNonNull(getStates().get(i)).toBukkitTry(b);
|
||||||
@@ -1178,16 +1173,16 @@ public class IrisObject extends IrisRegistrant {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized KMap<Vector3i, BlockData> getBlocks() {
|
public synchronized VectorMap<BlockData> getBlocks() {
|
||||||
return blocks;
|
return blocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized KMap<Vector3i, TileData> getStates() {
|
public synchronized VectorMap<TileData> getStates() {
|
||||||
return states;
|
return states;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void unplaceCenterY(Location at) {
|
public void unplaceCenterY(Location at) {
|
||||||
for (BlockVector i : getBlocks().keySet()) {
|
for (BlockVector i : getBlocks().keys()) {
|
||||||
at.clone().add(getCenter().getX(), getCenter().getY(), getCenter().getZ()).add(i).getBlock().setBlockData(AIR, false);
|
at.clone().add(getCenter().getX(), getCenter().getY(), getCenter().getZ()).add(i).getBlock().setBlockData(AIR, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1201,7 +1196,7 @@ public class IrisObject extends IrisRegistrant {
|
|||||||
|
|
||||||
IrisPosition l1 = getAABB().max();
|
IrisPosition l1 = getAABB().max();
|
||||||
IrisPosition l2 = getAABB().min();
|
IrisPosition l2 = getAABB().min();
|
||||||
@SuppressWarnings({"unchecked", "rawtypes"}) HashMap<BlockVector, BlockData> placeBlock = new HashMap();
|
VectorMap<BlockData> placeBlock = new VectorMap<>();
|
||||||
|
|
||||||
Vector center = getCenter();
|
Vector center = getCenter();
|
||||||
if (getH() == 2) {
|
if (getH() == 2) {
|
||||||
@@ -1216,17 +1211,17 @@ public class IrisObject extends IrisRegistrant {
|
|||||||
|
|
||||||
IrisObject oo = new IrisObject((int) Math.ceil((w * scale) + (scale * 2)), (int) Math.ceil((h * scale) + (scale * 2)), (int) Math.ceil((d * scale) + (scale * 2)));
|
IrisObject oo = new IrisObject((int) Math.ceil((w * scale) + (scale * 2)), (int) Math.ceil((h * scale) + (scale * 2)), (int) Math.ceil((d * scale) + (scale * 2)));
|
||||||
|
|
||||||
for (Map.Entry<Vector3i, BlockData> entry : blocks.entrySet()) {
|
for (var entry : blocks) {
|
||||||
BlockData bd = entry.getValue();
|
BlockData bd = entry.getValue();
|
||||||
placeBlock.put(entry.getKey().clone().add(HALF).subtract(center)
|
placeBlock.put(entry.getKey().clone().add(HALF).subtract(center)
|
||||||
.multiply(scale).add(sm1).toBlockVector(), bd);
|
.multiply(scale).add(sm1).toBlockVector(), bd);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Map.Entry<BlockVector, BlockData> entry : placeBlock.entrySet()) {
|
for (var entry : placeBlock) {
|
||||||
BlockVector v = entry.getKey();
|
BlockVector v = entry.getKey();
|
||||||
if (scale > 1) {
|
if (scale > 1) {
|
||||||
for (BlockVector vec : blocksBetweenTwoPoints(v.clone().add(center), v.clone().add(center).add(sm1))) {
|
for (BlockVector vec : blocksBetweenTwoPoints(v.clone().add(center), v.clone().add(center).add(sm1))) {
|
||||||
oo.getBlocks().put(new Vector3i(vec), entry.getValue());
|
oo.getBlocks().put(vec, entry.getValue());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
oo.setUnsigned(v.getBlockX(), v.getBlockY(), v.getBlockZ(), entry.getValue());
|
oo.setUnsigned(v.getBlockX(), v.getBlockY(), v.getBlockZ(), entry.getValue());
|
||||||
@@ -1245,8 +1240,8 @@ public class IrisObject extends IrisRegistrant {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void trilinear(int rad) {
|
public void trilinear(int rad) {
|
||||||
KMap<Vector3i, BlockData> v = getBlocks().copy();
|
VectorMap<BlockData> v = getBlocks();
|
||||||
KMap<Vector3i, BlockData> b = new KMap<>();
|
VectorMap<BlockData> b = new VectorMap<>();
|
||||||
BlockVector min = getAABB().minbv();
|
BlockVector min = getAABB().minbv();
|
||||||
BlockVector max = getAABB().maxbv();
|
BlockVector max = getAABB().maxbv();
|
||||||
|
|
||||||
@@ -1254,7 +1249,7 @@ public class IrisObject extends IrisRegistrant {
|
|||||||
for (int y = min.getBlockY(); y <= max.getBlockY(); y++) {
|
for (int y = min.getBlockY(); y <= max.getBlockY(); y++) {
|
||||||
for (int z = min.getBlockZ(); z <= max.getBlockZ(); z++) {
|
for (int z = min.getBlockZ(); z <= max.getBlockZ(); z++) {
|
||||||
if (IrisInterpolation.getTrilinear(x, y, z, rad, (xx, yy, zz) -> {
|
if (IrisInterpolation.getTrilinear(x, y, z, rad, (xx, yy, zz) -> {
|
||||||
BlockData data = v.get(new Vector3i((int) xx, (int) yy, (int) zz));
|
BlockData data = v.get(new BlockVector((int) xx, (int) yy, (int) zz));
|
||||||
|
|
||||||
if (data == null || data.getMaterial().isAir()) {
|
if (data == null || data.getMaterial().isAir()) {
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1262,9 +1257,9 @@ public class IrisObject extends IrisRegistrant {
|
|||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}) >= 0.5) {
|
}) >= 0.5) {
|
||||||
b.put(new Vector3i(x, y, z), nearestBlockData(x, y, z));
|
b.put(new BlockVector(x, y, z), nearestBlockData(x, y, z));
|
||||||
} else {
|
} else {
|
||||||
b.put(new Vector3i(x, y, z), AIR);
|
b.put(new BlockVector(x, y, z), AIR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1274,8 +1269,8 @@ public class IrisObject extends IrisRegistrant {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void tricubic(int rad) {
|
public void tricubic(int rad) {
|
||||||
KMap<Vector3i, BlockData> v = getBlocks().copy();
|
VectorMap<BlockData> v = getBlocks();
|
||||||
KMap<Vector3i, BlockData> b = new KMap<>();
|
VectorMap<BlockData> b = new VectorMap<>();
|
||||||
BlockVector min = getAABB().minbv();
|
BlockVector min = getAABB().minbv();
|
||||||
BlockVector max = getAABB().maxbv();
|
BlockVector max = getAABB().maxbv();
|
||||||
|
|
||||||
@@ -1283,7 +1278,7 @@ public class IrisObject extends IrisRegistrant {
|
|||||||
for (int y = min.getBlockY(); y <= max.getBlockY(); y++) {
|
for (int y = min.getBlockY(); y <= max.getBlockY(); y++) {
|
||||||
for (int z = min.getBlockZ(); z <= max.getBlockZ(); z++) {
|
for (int z = min.getBlockZ(); z <= max.getBlockZ(); z++) {
|
||||||
if (IrisInterpolation.getTricubic(x, y, z, rad, (xx, yy, zz) -> {
|
if (IrisInterpolation.getTricubic(x, y, z, rad, (xx, yy, zz) -> {
|
||||||
BlockData data = v.get(new Vector3i((int) xx, (int) yy, (int) zz));
|
BlockData data = v.get(new BlockVector((int) xx, (int) yy, (int) zz));
|
||||||
|
|
||||||
if (data == null || data.getMaterial().isAir()) {
|
if (data == null || data.getMaterial().isAir()) {
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1291,9 +1286,9 @@ public class IrisObject extends IrisRegistrant {
|
|||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}) >= 0.5) {
|
}) >= 0.5) {
|
||||||
b.put(new Vector3i(x, y, z), nearestBlockData(x, y, z));
|
b.put(new BlockVector(x, y, z), nearestBlockData(x, y, z));
|
||||||
} else {
|
} else {
|
||||||
b.put(new Vector3i(x, y, z), AIR);
|
b.put(new BlockVector(x, y, z), AIR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1307,8 +1302,8 @@ public class IrisObject extends IrisRegistrant {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void trihermite(int rad, double tension, double bias) {
|
public void trihermite(int rad, double tension, double bias) {
|
||||||
KMap<Vector3i, BlockData> v = getBlocks().copy();
|
VectorMap<BlockData> v = getBlocks();
|
||||||
KMap<Vector3i, BlockData> b = new KMap<>();
|
VectorMap<BlockData> b = new VectorMap<>();
|
||||||
BlockVector min = getAABB().minbv();
|
BlockVector min = getAABB().minbv();
|
||||||
BlockVector max = getAABB().maxbv();
|
BlockVector max = getAABB().maxbv();
|
||||||
|
|
||||||
@@ -1316,7 +1311,7 @@ public class IrisObject extends IrisRegistrant {
|
|||||||
for (int y = min.getBlockY(); y <= max.getBlockY(); y++) {
|
for (int y = min.getBlockY(); y <= max.getBlockY(); y++) {
|
||||||
for (int z = min.getBlockZ(); z <= max.getBlockZ(); z++) {
|
for (int z = min.getBlockZ(); z <= max.getBlockZ(); z++) {
|
||||||
if (IrisInterpolation.getTrihermite(x, y, z, rad, (xx, yy, zz) -> {
|
if (IrisInterpolation.getTrihermite(x, y, z, rad, (xx, yy, zz) -> {
|
||||||
BlockData data = v.get(new Vector3i((int) xx, (int) yy, (int) zz));
|
BlockData data = v.get(new BlockVector((int) xx, (int) yy, (int) zz));
|
||||||
|
|
||||||
if (data == null || data.getMaterial().isAir()) {
|
if (data == null || data.getMaterial().isAir()) {
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1324,9 +1319,9 @@ public class IrisObject extends IrisRegistrant {
|
|||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}, tension, bias) >= 0.5) {
|
}, tension, bias) >= 0.5) {
|
||||||
b.put(new Vector3i(x, y, z), nearestBlockData(x, y, z));
|
b.put(new BlockVector(x, y, z), nearestBlockData(x, y, z));
|
||||||
} else {
|
} else {
|
||||||
b.put(new Vector3i(x, y, z), AIR);
|
b.put(new BlockVector(x, y, z), AIR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1345,7 +1340,7 @@ public class IrisObject extends IrisRegistrant {
|
|||||||
|
|
||||||
double d = Double.MAX_VALUE;
|
double d = Double.MAX_VALUE;
|
||||||
|
|
||||||
for (Map.Entry<Vector3i, BlockData> entry : blocks.entrySet()) {
|
for (var entry : blocks) {
|
||||||
BlockData dat = entry.getValue();
|
BlockData dat = entry.getValue();
|
||||||
|
|
||||||
if (dat.getMaterial().isAir()) {
|
if (dat.getMaterial().isAir()) {
|
||||||
|
|||||||
220
core/src/main/java/com/volmit/iris/util/data/VectorMap.java
Normal file
220
core/src/main/java/com/volmit/iris/util/data/VectorMap.java
Normal file
@@ -0,0 +1,220 @@
|
|||||||
|
package com.volmit.iris.util.data;
|
||||||
|
|
||||||
|
import com.volmit.iris.util.collection.KMap;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import org.bukkit.util.BlockVector;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.BiConsumer;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
public class VectorMap<T> implements Iterable<Map.Entry<BlockVector, T>> {
|
||||||
|
private final Map<Key, Map<Key, T>> map = new KMap<>();
|
||||||
|
|
||||||
|
public int size() {
|
||||||
|
return map.values().stream().mapToInt(Map::size).sum();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return map.values().stream().allMatch(Map::isEmpty);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean containsKey(@NonNull BlockVector vector) {
|
||||||
|
var chunk = map.get(chunk(vector));
|
||||||
|
return chunk != null && chunk.containsKey(relative(vector));
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean containsValue(@NonNull T value) {
|
||||||
|
return map.values().stream().anyMatch(m -> m.containsValue(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable T get(@NonNull BlockVector vector) {
|
||||||
|
var chunk = map.get(chunk(vector));
|
||||||
|
return chunk == null ? null : chunk.get(relative(vector));
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable T put(@NonNull BlockVector vector, @NonNull T value) {
|
||||||
|
return map.computeIfAbsent(chunk(vector), k -> new KMap<>())
|
||||||
|
.put(relative(vector), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable T computeIfAbsent(@NonNull BlockVector vector, @NonNull Function<@NonNull BlockVector, @NonNull T> mappingFunction) {
|
||||||
|
return map.computeIfAbsent(chunk(vector), k -> new KMap<>())
|
||||||
|
.computeIfAbsent(relative(vector), $ -> mappingFunction.apply(vector));
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable T remove(@NonNull BlockVector vector) {
|
||||||
|
var chunk = map.get(chunk(vector));
|
||||||
|
return chunk == null ? null : chunk.remove(relative(vector));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void putAll(@NonNull VectorMap<T> map) {
|
||||||
|
map.forEach(this::put);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear() {
|
||||||
|
map.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void forEach(@NonNull BiConsumer<@NonNull BlockVector, @NonNull T> consumer) {
|
||||||
|
map.forEach((chunk, values) -> {
|
||||||
|
int rX = chunk.x << 10;
|
||||||
|
int rY = chunk.y << 10;
|
||||||
|
int rZ = chunk.z << 10;
|
||||||
|
|
||||||
|
values.forEach((relative, value) -> consumer.accept(
|
||||||
|
relative.resolve(rX, rY, rZ),
|
||||||
|
value
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Key chunk(BlockVector vector) {
|
||||||
|
return new Key(vector.getBlockX() >> 10, vector.getBlockY() >> 10, vector.getBlockZ() >> 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Key relative(BlockVector vector) {
|
||||||
|
return new Key(vector.getBlockX() & 0x3FF, vector.getBlockY() & 0x3FF, vector.getBlockZ() & 0x3FF);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull EntryIterator iterator() {
|
||||||
|
return new EntryIterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NotNull KeyIterator keys() {
|
||||||
|
return new KeyIterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NotNull ValueIterator values() {
|
||||||
|
return new ValueIterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class EntryIterator implements Iterator<Map.Entry<BlockVector, T>> {
|
||||||
|
private final Iterator<Map.Entry<Key, Map<Key, T>>> chunkIterator = map.entrySet().iterator();
|
||||||
|
private Iterator<Map.Entry<Key, T>> relativeIterator;
|
||||||
|
private int rX, rY, rZ;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasNext() {
|
||||||
|
return relativeIterator != null && relativeIterator.hasNext() || chunkIterator.hasNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map.Entry<BlockVector, T> next() {
|
||||||
|
if (relativeIterator == null || !relativeIterator.hasNext()) {
|
||||||
|
if (!chunkIterator.hasNext()) throw new IllegalStateException("No more elements");
|
||||||
|
var chunk = chunkIterator.next();
|
||||||
|
rX = chunk.getKey().x << 10;
|
||||||
|
rY = chunk.getKey().y << 10;
|
||||||
|
rZ = chunk.getKey().z << 10;
|
||||||
|
relativeIterator = chunk.getValue().entrySet().iterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
var entry = relativeIterator.next();
|
||||||
|
return Map.entry(entry.getKey().resolve(rX, rY, rZ), entry.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void remove() {
|
||||||
|
if (relativeIterator == null) throw new IllegalStateException("No element to remove");
|
||||||
|
relativeIterator.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class KeyIterator implements Iterator<BlockVector>, Iterable<BlockVector> {
|
||||||
|
private final Iterator<Map.Entry<Key, Map<Key, T>>> chunkIterator = map.entrySet().iterator();
|
||||||
|
private Iterator<Key> relativeIterator;
|
||||||
|
private int rX, rY, rZ;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasNext() {
|
||||||
|
return relativeIterator != null && relativeIterator.hasNext() || chunkIterator.hasNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockVector next() {
|
||||||
|
if (relativeIterator == null || !relativeIterator.hasNext()) {
|
||||||
|
var chunk = chunkIterator.next();
|
||||||
|
rX = chunk.getKey().x << 10;
|
||||||
|
rY = chunk.getKey().y << 10;
|
||||||
|
rZ = chunk.getKey().z << 10;
|
||||||
|
relativeIterator = chunk.getValue().keySet().iterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
return relativeIterator.next().resolve(rX, rY, rZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void remove() {
|
||||||
|
if (relativeIterator == null) throw new IllegalStateException("No element to remove");
|
||||||
|
relativeIterator.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull Iterator<BlockVector> iterator() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ValueIterator implements Iterator<T>, Iterable<T> {
|
||||||
|
private final Iterator<Map<Key, T>> chunkIterator = map.values().iterator();
|
||||||
|
private Iterator<T> relativeIterator;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasNext() {
|
||||||
|
return relativeIterator != null && relativeIterator.hasNext() || chunkIterator.hasNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public T next() {
|
||||||
|
if (relativeIterator == null || !relativeIterator.hasNext()) {
|
||||||
|
relativeIterator = chunkIterator.next().values().iterator();
|
||||||
|
}
|
||||||
|
return relativeIterator.next();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void remove() {
|
||||||
|
if (relativeIterator == null) throw new IllegalStateException("No element to remove");
|
||||||
|
relativeIterator.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull Iterator<T> iterator() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class Key {
|
||||||
|
private final int x;
|
||||||
|
private final int y;
|
||||||
|
private final int z;
|
||||||
|
private final int hashCode;
|
||||||
|
|
||||||
|
private Key(int x, int y, int z) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.z = z;
|
||||||
|
this.hashCode = (x << 20) | (y << 10) | z;
|
||||||
|
}
|
||||||
|
|
||||||
|
private BlockVector resolve(int rX, int rY, int rZ) {
|
||||||
|
return new BlockVector(rX + x, rY + y, rZ + z);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return hashCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (!(o instanceof Key key)) return false;
|
||||||
|
return x == key.x && y == key.y && z == key.z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -85,13 +85,13 @@ public interface Matter {
|
|||||||
BlockVector min = new BlockVector();
|
BlockVector min = new BlockVector();
|
||||||
Matter m = new IrisMatter(Math.max(object.getW(), 1) + 1, Math.max(object.getH(), 1) + 1, Math.max(object.getD(), 1) + 1);
|
Matter m = new IrisMatter(Math.max(object.getW(), 1) + 1, Math.max(object.getH(), 1) + 1, Math.max(object.getD(), 1) + 1);
|
||||||
|
|
||||||
for (BlockVector i : object.getBlocks().keySet()) {
|
for (BlockVector i : object.getBlocks().keys()) {
|
||||||
min.setX(Math.min(min.getX(), i.getX()));
|
min.setX(Math.min(min.getX(), i.getX()));
|
||||||
min.setY(Math.min(min.getY(), i.getY()));
|
min.setY(Math.min(min.getY(), i.getY()));
|
||||||
min.setZ(Math.min(min.getZ(), i.getZ()));
|
min.setZ(Math.min(min.getZ(), i.getZ()));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (BlockVector i : object.getBlocks().keySet()) {
|
for (BlockVector i : object.getBlocks().keys()) {
|
||||||
m.slice(BlockData.class).set(i.getBlockX() - min.getBlockX(), i.getBlockY() - min.getBlockY(), i.getBlockZ() - min.getBlockZ(), object.getBlocks().get(i));
|
m.slice(BlockData.class).set(i.getBlockX() - min.getBlockX(), i.getBlockY() - min.getBlockY(), i.getBlockZ() - min.getBlockZ(), object.getBlocks().get(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user