package nova.microblock.multi;
import nova.core.block.Block;
import nova.core.component.Require;
import nova.core.component.misc.Collider;
import nova.core.util.math.MathUtil;
import nova.core.util.shape.Cuboid;
import nova.microblock.common.BlockComponent;
import org.apache.commons.math3.geometry.euclidean.threed.Vector3D;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
/**
* A component attached to any multiblock.
* @author Calclavia
*/
@Require(Collider.class)
public class Multiblock extends BlockComponent {
/**
* The containers that contain (occupy block space) for this multiblock
*/
public final Set<MultiblockContainer> containers = new HashSet<>();
public Multiblock(Block block) {
super(block);
}
/**
* Gets the occupied space within this multiblock that is outside the default blockLength bounds.
* @param blockLength The length of each microblock/block. Used to calculate collision subdivision.
* @return A set of vectors relative to the center block's bottom corner.
*/
public Set<Vector3D> getOccupiedSpace(float blockLength) {
Set<Cuboid> collisionBoxes = block.components.get(Collider.class).occlusionBoxes.apply(Optional.empty());
Set<Vector3D> set = new HashSet<>();
int truncation = (int) (1 / blockLength);
collisionBoxes.forEach(
cuboid -> {
//Truncate bounds to nearest block length
for (double x = MathUtil.truncate(cuboid.min.getX(), truncation); x < cuboid.max.getX(); x += blockLength) {
for (double y = MathUtil.truncate(cuboid.min.getY(), truncation); y < cuboid.max.getY(); y += blockLength) {
for (double z = MathUtil.truncate(cuboid.min.getZ(), truncation); z < cuboid.max.getZ(); z += blockLength) {
set.add(new Vector3D(x, y, z));
}
}
}
}
);
return set;
}
}