Created
November 7, 2020 07:56
-
-
Save CorgiTaco/393bfa62b6579befc1da8bbcb27c0d8d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package io.github.opencubicchunks.cubicchunks.chunk.heightmap; | |
import net.minecraft.util.BitStorage; | |
import net.minecraft.world.level.block.state.BlockState; | |
import net.minecraft.world.level.chunk.ChunkAccess; | |
import java.util.function.Predicate; | |
public class CCHeightmap { | |
private static final Predicate<BlockState> NOT_AIR = (blockState) -> !blockState.isAir(); | |
private static final Predicate<BlockState> MATERIAL_MOTION_BLOCKING = (blockState) -> blockState.getMaterial().blocksMotion(); | |
private final BitStorage data; | |
private final Predicate<BlockState> isOpaque; | |
private final ChunkAccess chunk; | |
public static final int BLOCK_COLUMNS_PER_COLUMN = 16 * 16; //Always needs to be a power of 2. | |
int scale; | |
private boolean isDirty = false; | |
public CCHeightmap(int scale) { | |
this.isOpaque = null; | |
this.chunk = null; | |
this.scale = scale; | |
this.data = new BitStorage((4 + scale) + 1, BLOCK_COLUMNS_PER_COLUMN); // If the highest bit is 1, the value is null. | |
} | |
public BitStorage getData() { | |
return data; | |
} | |
public void setDirty() { | |
isDirty = true; | |
} | |
public int getScale() { | |
return scale; | |
} | |
public static class NodeTree<T> { | |
private final List<T> nodes; //Internal node array | |
private final int nodeChildCount; //number of children this node has | |
private CCHeightmap ccHeightmap; | |
private boolean nodesInitialised = false; | |
/** | |
* @param nodeChildCount the number of children for this node | |
*/ | |
private NodeTree(int nodeChildCount) { | |
this.nodeChildCount = nodeChildCount; | |
nodes = new ArrayList<>(nodeChildCount); | |
} | |
public void setCcHeightmap(CCHeightmap ccHeightmap) { | |
this.ccHeightmap = ccHeightmap; | |
} | |
public CCHeightmap getCcHeightmap() { | |
return ccHeightmap; | |
} | |
/** | |
* @param nodeChildCount The number of children per node | |
* @param depth how deep to initialise the tree | |
* @return the full node tree created. | |
* | |
* A tree of depth 1 would have a return type of NodeTree<T> | |
* A tree of depth 2 would have a return type of NodeTree<NodeTree<T>> | |
* etc | |
*/ | |
public static <T> NodeTree<T> createTree(int nodeChildCount, int depth) { | |
if(depth < 1) { | |
NodeTree<T> nodeTree = new NodeTree<>(nodeChildCount); | |
nodeTree.initialiseNodesIfNot(); | |
return nodeTree; | |
} | |
NodeTree<T> tree = new NodeTree<>(nodeChildCount); | |
unsafeAddTreeToNode(tree, depth); | |
return tree; | |
} | |
public void initialiseNodesIfNot() { | |
if(!nodesInitialised) { | |
for (int i = 0; i < nodeChildCount; i++) { | |
nodes.add(null); | |
} | |
} | |
} | |
public void nullNodes() { | |
initialiseNodesIfNot(); | |
for (int i = 0; i < nodeChildCount; i++) { | |
nodes.set(i, null); | |
} | |
} | |
public static <T> void unsafeAddTreeToNode(NodeTree tree, int depth) { | |
depth--; | |
for(int i = tree.nodes.size(); i < tree.nodeChildCount; i++) { | |
NodeTree node = new NodeTree<>(tree.nodeChildCount); | |
if(depth > 1) { | |
unsafeAddTreeToNode(node, depth); | |
node.nodesInitialised = true; | |
} else { | |
node.initialiseNodesIfNot(); | |
} | |
tree.nodes.add(i, node); | |
} | |
} | |
public T getNode(int i) { | |
initialiseNodesIfNot(); | |
return nodes.get(i); | |
} | |
public void setNode(int i, T val) { | |
initialiseNodesIfNot(); | |
nodes.set(i, val); | |
} | |
public T getNodeUnchecked(int i) { | |
return nodes.get(i); | |
} | |
public void setNodeUnchecked(int i, T val) { | |
nodes.set(i, val); | |
} | |
static Random random = new Random(1); | |
public static void main(String[] args) { | |
NodeTree<NodeTree<CCHeightmap>> root = NodeTree.createTree(2, 3); | |
root.setCcHeightmap(new CCHeightmap(2)); | |
root.getCcHeightmap().setDirty(); | |
NodeTree<CCHeightmap> parent = root.getNode(0); | |
parent.setCcHeightmap(new CCHeightmap(1)); | |
parent.getCcHeightmap().setDirty(); | |
NodeTree<CCHeightmap> parent2 = root.getNode(1); | |
parent2.setCcHeightmap(new CCHeightmap(1)); | |
parent2.getCcHeightmap().setDirty(); | |
parent.setNode(0, initializeRandomCCHeightMap(0)); | |
parent.setNode(1, initializeRandomCCHeightMap(0)); | |
parent2.setNode(0, initializeRandomCCHeightMap(0)); | |
parent2.setNode(1, initializeRandomCCHeightMap(0)); | |
System.out.println("ROOT SCALE: " + root.getCcHeightmap().getScale()); | |
System.out.println("Root Child 0 Scale: " + root.getNode(0).getCcHeightmap().getScale()); | |
System.out.println("Root Child 0 Child 0 Scale: " + parent.getNode(0).getScale()); | |
System.out.println("Root Child 0 Child 1 Scale: " + parent.getNode(1).getScale()); | |
System.out.println("\n"); | |
System.out.println("Root Child 1 Scale: " + root.getNode(1).getCcHeightmap().getScale()); | |
System.out.println("Root Child 1 Child 0 Scale: " + parent2.getNode(0).getScale()); | |
System.out.println("Root Child 1 Child 1 Scale: " + parent2.getNode(1).getScale()); | |
} | |
public static CCHeightmap initializeRandomCCHeightMap(int scale) { | |
CCHeightmap ccHeightmap = new CCHeightmap(scale); | |
for (int x = 0; x < 16; x++) { | |
for (int z = 0; z < 16; z++) { | |
ccHeightmap.getData().set(x * 16 + z, random.nextInt()); | |
} | |
} | |
return ccHeightmap; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment