WorldOctTree small updates
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit
This commit is contained in:
parent
4f2fcc62c9
commit
183c98367c
@ -14,7 +14,7 @@ import electrosphere.engine.Globals;
|
|||||||
import electrosphere.entity.EntityUtils;
|
import electrosphere.entity.EntityUtils;
|
||||||
import electrosphere.logger.LoggerInterface;
|
import electrosphere.logger.LoggerInterface;
|
||||||
import electrosphere.util.ds.octree.WorldOctTree;
|
import electrosphere.util.ds.octree.WorldOctTree;
|
||||||
import electrosphere.util.ds.octree.WorldOctTree.FloatingChunkTreeNode;
|
import electrosphere.util.ds.octree.WorldOctTree.WorldOctTreeNode;
|
||||||
import electrosphere.util.math.GeomUtils;
|
import electrosphere.util.math.GeomUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -95,7 +95,7 @@ public class ClientDrawCellManager {
|
|||||||
/**
|
/**
|
||||||
* Tracks what nodes have been evaluated this frame -- used to deduplicate evaluation calls
|
* Tracks what nodes have been evaluated this frame -- used to deduplicate evaluation calls
|
||||||
*/
|
*/
|
||||||
Map<FloatingChunkTreeNode<DrawCell>,Boolean> evaluationMap = new HashMap<FloatingChunkTreeNode<DrawCell>,Boolean>();
|
Map<WorldOctTreeNode<DrawCell>,Boolean> evaluationMap = new HashMap<WorldOctTreeNode<DrawCell>,Boolean>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The last recorded player world position
|
* The last recorded player world position
|
||||||
@ -173,7 +173,7 @@ public class ClientDrawCellManager {
|
|||||||
validCellCount = 0;
|
validCellCount = 0;
|
||||||
evaluationMap.clear();
|
evaluationMap.clear();
|
||||||
//update all full res cells
|
//update all full res cells
|
||||||
FloatingChunkTreeNode<DrawCell> rootNode = this.chunkTree.getRoot();
|
WorldOctTreeNode<DrawCell> rootNode = this.chunkTree.getRoot();
|
||||||
Globals.profiler.beginCpuSample("ClientDrawCellManager.update - full res cells");
|
Globals.profiler.beginCpuSample("ClientDrawCellManager.update - full res cells");
|
||||||
updatedLastFrame = this.recursivelyUpdateCells(rootNode, playerWorldPos, evaluationMap, SIXTEENTH_RES_LOD, distCache);
|
updatedLastFrame = this.recursivelyUpdateCells(rootNode, playerWorldPos, evaluationMap, SIXTEENTH_RES_LOD, distCache);
|
||||||
Globals.profiler.endCpuSample();
|
Globals.profiler.endCpuSample();
|
||||||
@ -217,7 +217,7 @@ public class ClientDrawCellManager {
|
|||||||
* @param evaluationMap Map of leaf nodes that have been evaluated this frame
|
* @param evaluationMap Map of leaf nodes that have been evaluated this frame
|
||||||
* @return true if there is work remaining to be done, false otherwise
|
* @return true if there is work remaining to be done, false otherwise
|
||||||
*/
|
*/
|
||||||
private boolean recursivelyUpdateCells(FloatingChunkTreeNode<DrawCell> node, Vector3i playerPos, Map<FloatingChunkTreeNode<DrawCell>,Boolean> evaluationMap, int minLeafLod, int distCache){
|
private boolean recursivelyUpdateCells(WorldOctTreeNode<DrawCell> node, Vector3i playerPos, Map<WorldOctTreeNode<DrawCell>,Boolean> evaluationMap, int minLeafLod, int distCache){
|
||||||
boolean updated = false;
|
boolean updated = false;
|
||||||
if(evaluationMap.containsKey(node)){
|
if(evaluationMap.containsKey(node)){
|
||||||
return false;
|
return false;
|
||||||
@ -229,7 +229,7 @@ public class ClientDrawCellManager {
|
|||||||
if(this.shouldSplit(playerPos, node, distCache)){
|
if(this.shouldSplit(playerPos, node, distCache)){
|
||||||
Globals.profiler.beginCpuSample("ClientDrawCellManager.split");
|
Globals.profiler.beginCpuSample("ClientDrawCellManager.split");
|
||||||
//perform op
|
//perform op
|
||||||
FloatingChunkTreeNode<DrawCell> container = chunkTree.split(node);
|
WorldOctTreeNode<DrawCell> container = chunkTree.split(node);
|
||||||
|
|
||||||
//do deletions
|
//do deletions
|
||||||
this.twoLayerDestroy(node);
|
this.twoLayerDestroy(node);
|
||||||
@ -300,7 +300,7 @@ public class ClientDrawCellManager {
|
|||||||
if(this.shouldJoin(playerPos, node, distCache)) {
|
if(this.shouldJoin(playerPos, node, distCache)) {
|
||||||
Globals.profiler.beginCpuSample("ClientDrawCellManager.join");
|
Globals.profiler.beginCpuSample("ClientDrawCellManager.join");
|
||||||
//perform op
|
//perform op
|
||||||
FloatingChunkTreeNode<DrawCell> newLeaf = chunkTree.join(node);
|
WorldOctTreeNode<DrawCell> newLeaf = chunkTree.join(node);
|
||||||
|
|
||||||
//do deletions
|
//do deletions
|
||||||
this.twoLayerDestroy(node);
|
this.twoLayerDestroy(node);
|
||||||
@ -317,9 +317,9 @@ public class ClientDrawCellManager {
|
|||||||
updated = true;
|
updated = true;
|
||||||
} else {
|
} else {
|
||||||
this.validCellCount++;
|
this.validCellCount++;
|
||||||
List<FloatingChunkTreeNode<DrawCell>> children = node.getChildren();
|
List<WorldOctTreeNode<DrawCell>> children = node.getChildren();
|
||||||
for(int i = 0; i < 8; i++){
|
for(int i = 0; i < 8; i++){
|
||||||
FloatingChunkTreeNode<DrawCell> child = children.get(i);
|
WorldOctTreeNode<DrawCell> child = children.get(i);
|
||||||
boolean childUpdate = recursivelyUpdateCells(child, playerPos, evaluationMap, minLeafLod, distCache);
|
boolean childUpdate = recursivelyUpdateCells(child, playerPos, evaluationMap, minLeafLod, distCache);
|
||||||
if(childUpdate == true){
|
if(childUpdate == true){
|
||||||
updated = true;
|
updated = true;
|
||||||
@ -339,7 +339,7 @@ public class ClientDrawCellManager {
|
|||||||
* @param node the node
|
* @param node the node
|
||||||
* @return the distance
|
* @return the distance
|
||||||
*/
|
*/
|
||||||
public double getMinDistance(Vector3i worldPos, FloatingChunkTreeNode<DrawCell> node, int distCache){
|
public double getMinDistance(Vector3i worldPos, WorldOctTreeNode<DrawCell> node, int distCache){
|
||||||
if(node.getData() == null){
|
if(node.getData() == null){
|
||||||
return GeomUtils.getMinSquaredDistanceAABB(worldPos, node.getMinBound(), node.getMaxBound());
|
return GeomUtils.getMinSquaredDistanceAABB(worldPos, node.getMinBound(), node.getMaxBound());
|
||||||
} else {
|
} else {
|
||||||
@ -388,7 +388,7 @@ public class ClientDrawCellManager {
|
|||||||
* @param node The node
|
* @param node The node
|
||||||
* @return true if should split, false otherwise
|
* @return true if should split, false otherwise
|
||||||
*/
|
*/
|
||||||
public boolean shouldSplit(Vector3i pos, FloatingChunkTreeNode<DrawCell> node, int distCache){
|
public boolean shouldSplit(Vector3i pos, WorldOctTreeNode<DrawCell> node, int distCache){
|
||||||
//breaking out into dedicated function so can add case handling ie if we want
|
//breaking out into dedicated function so can add case handling ie if we want
|
||||||
//to combine fullres nodes into larger nodes to conserve on draw calls
|
//to combine fullres nodes into larger nodes to conserve on draw calls
|
||||||
return
|
return
|
||||||
@ -430,7 +430,7 @@ public class ClientDrawCellManager {
|
|||||||
* @param node The node to consider
|
* @param node The node to consider
|
||||||
* @return -1 if outside of render range, -1 if the node is not a valid draw cell leaf, otherwise returns the LOD level
|
* @return -1 if outside of render range, -1 if the node is not a valid draw cell leaf, otherwise returns the LOD level
|
||||||
*/
|
*/
|
||||||
private int getLODLevel(FloatingChunkTreeNode<DrawCell> node){
|
private int getLODLevel(WorldOctTreeNode<DrawCell> node){
|
||||||
return this.chunkTree.getMaxLevel() - node.getLevel();
|
return this.chunkTree.getMaxLevel() - node.getLevel();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -440,7 +440,7 @@ public class ClientDrawCellManager {
|
|||||||
* @param playerWorldPos The player's world position
|
* @param playerWorldPos The player's world position
|
||||||
* @return true if should solve for high res faces, false otherwise
|
* @return true if should solve for high res faces, false otherwise
|
||||||
*/
|
*/
|
||||||
private boolean shouldSolveFaces(FloatingChunkTreeNode<DrawCell> node, Vector3i playerWorldPos, int distCache){
|
private boolean shouldSolveFaces(WorldOctTreeNode<DrawCell> node, Vector3i playerWorldPos, int distCache){
|
||||||
if(node.getLevel() == this.chunkTree.getMaxLevel()){
|
if(node.getLevel() == this.chunkTree.getMaxLevel()){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -472,7 +472,7 @@ public class ClientDrawCellManager {
|
|||||||
* @param node The node for the chunk
|
* @param node The node for the chunk
|
||||||
* @return The face if there is a higher resolution face, null otherwise
|
* @return The face if there is a higher resolution face, null otherwise
|
||||||
*/
|
*/
|
||||||
private List<DrawCellFace> solveHighResFace(FloatingChunkTreeNode<DrawCell> node){
|
private List<DrawCellFace> solveHighResFace(WorldOctTreeNode<DrawCell> node){
|
||||||
//don't bother to check if it's a full res chunk
|
//don't bother to check if it's a full res chunk
|
||||||
if(node.getLevel() == this.chunkTree.getMaxLevel()){
|
if(node.getLevel() == this.chunkTree.getMaxLevel()){
|
||||||
return null;
|
return null;
|
||||||
@ -484,37 +484,37 @@ public class ClientDrawCellManager {
|
|||||||
int spacing = (int)Math.pow(2,lodMultiplitier);
|
int spacing = (int)Math.pow(2,lodMultiplitier);
|
||||||
List<DrawCellFace> faces = new LinkedList<DrawCellFace>();
|
List<DrawCellFace> faces = new LinkedList<DrawCellFace>();
|
||||||
if(node.getMinBound().x - 1 >= 0){
|
if(node.getMinBound().x - 1 >= 0){
|
||||||
FloatingChunkTreeNode<DrawCell> xNegNode = this.chunkTree.search(new Vector3i(node.getMinBound()).add(-1,1,1), false);
|
WorldOctTreeNode<DrawCell> xNegNode = this.chunkTree.search(new Vector3i(node.getMinBound()).add(-1,1,1), false);
|
||||||
if(xNegNode != null && xNegNode.getLevel() > node.getLevel()){
|
if(xNegNode != null && xNegNode.getLevel() > node.getLevel()){
|
||||||
faces.add(DrawCellFace.X_NEGATIVE);
|
faces.add(DrawCellFace.X_NEGATIVE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(node.getMinBound().y - 1 >= 0){
|
if(node.getMinBound().y - 1 >= 0){
|
||||||
FloatingChunkTreeNode<DrawCell> yNegNode = this.chunkTree.search(new Vector3i(node.getMinBound()).add(1,-1,1), false);
|
WorldOctTreeNode<DrawCell> yNegNode = this.chunkTree.search(new Vector3i(node.getMinBound()).add(1,-1,1), false);
|
||||||
if(yNegNode != null && yNegNode.getLevel() > node.getLevel()){
|
if(yNegNode != null && yNegNode.getLevel() > node.getLevel()){
|
||||||
faces.add(DrawCellFace.Y_NEGATIVE);
|
faces.add(DrawCellFace.Y_NEGATIVE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(node.getMinBound().z - 1 >= 0){
|
if(node.getMinBound().z - 1 >= 0){
|
||||||
FloatingChunkTreeNode<DrawCell> zNegNode = this.chunkTree.search(new Vector3i(node.getMinBound()).add(1,1,-1), false);
|
WorldOctTreeNode<DrawCell> zNegNode = this.chunkTree.search(new Vector3i(node.getMinBound()).add(1,1,-1), false);
|
||||||
if(zNegNode != null && zNegNode.getLevel() > node.getLevel()){
|
if(zNegNode != null && zNegNode.getLevel() > node.getLevel()){
|
||||||
faces.add(DrawCellFace.Z_NEGATIVE);
|
faces.add(DrawCellFace.Z_NEGATIVE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(node.getMaxBound().x + spacing + 1 < this.worldDim){
|
if(node.getMaxBound().x + spacing + 1 < this.worldDim){
|
||||||
FloatingChunkTreeNode<DrawCell> xPosNode = this.chunkTree.search(new Vector3i(node.getMinBound()).add(spacing + 1,1,1), false);
|
WorldOctTreeNode<DrawCell> xPosNode = this.chunkTree.search(new Vector3i(node.getMinBound()).add(spacing + 1,1,1), false);
|
||||||
if(xPosNode != null && xPosNode.getLevel() > node.getLevel()){
|
if(xPosNode != null && xPosNode.getLevel() > node.getLevel()){
|
||||||
faces.add(DrawCellFace.X_POSITIVE);
|
faces.add(DrawCellFace.X_POSITIVE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(node.getMaxBound().y + spacing + 1 < this.worldDim){
|
if(node.getMaxBound().y + spacing + 1 < this.worldDim){
|
||||||
FloatingChunkTreeNode<DrawCell> yPosNode = this.chunkTree.search(new Vector3i(node.getMinBound()).add(1,spacing + 1,1), false);
|
WorldOctTreeNode<DrawCell> yPosNode = this.chunkTree.search(new Vector3i(node.getMinBound()).add(1,spacing + 1,1), false);
|
||||||
if(yPosNode != null && yPosNode.getLevel() > node.getLevel()){
|
if(yPosNode != null && yPosNode.getLevel() > node.getLevel()){
|
||||||
faces.add(DrawCellFace.Y_POSITIVE);
|
faces.add(DrawCellFace.Y_POSITIVE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(node.getMaxBound().z + spacing + 1 < this.worldDim){
|
if(node.getMaxBound().z + spacing + 1 < this.worldDim){
|
||||||
FloatingChunkTreeNode<DrawCell> zPosNode = this.chunkTree.search(new Vector3i(node.getMinBound()).add(1,1,spacing + 1), false);
|
WorldOctTreeNode<DrawCell> zPosNode = this.chunkTree.search(new Vector3i(node.getMinBound()).add(1,1,spacing + 1), false);
|
||||||
if(zPosNode != null && zPosNode.getLevel() > node.getLevel()){
|
if(zPosNode != null && zPosNode.getLevel() > node.getLevel()){
|
||||||
faces.add(DrawCellFace.Z_POSITIVE);
|
faces.add(DrawCellFace.Z_POSITIVE);
|
||||||
}
|
}
|
||||||
@ -530,43 +530,43 @@ public class ClientDrawCellManager {
|
|||||||
* @param node The node to search from adjacencies from
|
* @param node The node to search from adjacencies from
|
||||||
* @param level The level to check against
|
* @param level The level to check against
|
||||||
*/
|
*/
|
||||||
private void conditionalUpdateAdjacentNodes(FloatingChunkTreeNode<DrawCell> node, int level){
|
private void conditionalUpdateAdjacentNodes(WorldOctTreeNode<DrawCell> node, int level){
|
||||||
//don't bother to check if it's a lowest-res chunk
|
//don't bother to check if it's a lowest-res chunk
|
||||||
if(this.chunkTree.getMaxLevel() - level > ClientDrawCellManager.FULL_RES_LOD){
|
if(this.chunkTree.getMaxLevel() - level > ClientDrawCellManager.FULL_RES_LOD){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(node.getMinBound().x - 1 >= 0){
|
if(node.getMinBound().x - 1 >= 0){
|
||||||
FloatingChunkTreeNode<DrawCell> xNegNode = this.chunkTree.search(new Vector3i(node.getMinBound()).add(-1,0,0), false);
|
WorldOctTreeNode<DrawCell> xNegNode = this.chunkTree.search(new Vector3i(node.getMinBound()).add(-1,0,0), false);
|
||||||
if(xNegNode != null && xNegNode.getLevel() < level){
|
if(xNegNode != null && xNegNode.getLevel() < level){
|
||||||
xNegNode.getData().setHasGenerated(false);
|
xNegNode.getData().setHasGenerated(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(node.getMinBound().y - 1 >= 0){
|
if(node.getMinBound().y - 1 >= 0){
|
||||||
FloatingChunkTreeNode<DrawCell> yNegNode = this.chunkTree.search(new Vector3i(node.getMinBound()).add(0,-1,0), false);
|
WorldOctTreeNode<DrawCell> yNegNode = this.chunkTree.search(new Vector3i(node.getMinBound()).add(0,-1,0), false);
|
||||||
if(yNegNode != null && yNegNode.getLevel() < level){
|
if(yNegNode != null && yNegNode.getLevel() < level){
|
||||||
yNegNode.getData().setHasGenerated(false);
|
yNegNode.getData().setHasGenerated(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(node.getMinBound().z - 1 >= 0){
|
if(node.getMinBound().z - 1 >= 0){
|
||||||
FloatingChunkTreeNode<DrawCell> zNegNode = this.chunkTree.search(new Vector3i(node.getMinBound()).add(0,0,-1), false);
|
WorldOctTreeNode<DrawCell> zNegNode = this.chunkTree.search(new Vector3i(node.getMinBound()).add(0,0,-1), false);
|
||||||
if(zNegNode != null && zNegNode.getLevel() < level){
|
if(zNegNode != null && zNegNode.getLevel() < level){
|
||||||
zNegNode.getData().setHasGenerated(false);
|
zNegNode.getData().setHasGenerated(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(node.getMaxBound().x + 1 < this.worldDim){
|
if(node.getMaxBound().x + 1 < this.worldDim){
|
||||||
FloatingChunkTreeNode<DrawCell> xPosNode = this.chunkTree.search(new Vector3i(node.getMaxBound()).add(1,-1,-1), false);
|
WorldOctTreeNode<DrawCell> xPosNode = this.chunkTree.search(new Vector3i(node.getMaxBound()).add(1,-1,-1), false);
|
||||||
if(xPosNode != null && xPosNode.getLevel() < level){
|
if(xPosNode != null && xPosNode.getLevel() < level){
|
||||||
xPosNode.getData().setHasGenerated(false);
|
xPosNode.getData().setHasGenerated(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(node.getMaxBound().y + 1 < this.worldDim){
|
if(node.getMaxBound().y + 1 < this.worldDim){
|
||||||
FloatingChunkTreeNode<DrawCell> yPosNode = this.chunkTree.search(new Vector3i(node.getMaxBound()).add(-1,1,-1), false);
|
WorldOctTreeNode<DrawCell> yPosNode = this.chunkTree.search(new Vector3i(node.getMaxBound()).add(-1,1,-1), false);
|
||||||
if(yPosNode != null && yPosNode.getLevel() < level){
|
if(yPosNode != null && yPosNode.getLevel() < level){
|
||||||
yPosNode.getData().setHasGenerated(false);
|
yPosNode.getData().setHasGenerated(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(node.getMaxBound().z + 1 < this.worldDim){
|
if(node.getMaxBound().z + 1 < this.worldDim){
|
||||||
FloatingChunkTreeNode<DrawCell> zPosNode = this.chunkTree.search(new Vector3i(node.getMaxBound()).add(-1,-1,1), false);
|
WorldOctTreeNode<DrawCell> zPosNode = this.chunkTree.search(new Vector3i(node.getMaxBound()).add(-1,-1,1), false);
|
||||||
if(zPosNode != null && zPosNode.getLevel() < level){
|
if(zPosNode != null && zPosNode.getLevel() < level){
|
||||||
zPosNode.getData().setHasGenerated(false);
|
zPosNode.getData().setHasGenerated(false);
|
||||||
}
|
}
|
||||||
@ -579,7 +579,7 @@ public class ClientDrawCellManager {
|
|||||||
* @param node The node
|
* @param node The node
|
||||||
* @return true if should be joined, false otherwise
|
* @return true if should be joined, false otherwise
|
||||||
*/
|
*/
|
||||||
public boolean shouldJoin(Vector3i pos, FloatingChunkTreeNode<DrawCell> node, int distCache){
|
public boolean shouldJoin(Vector3i pos, WorldOctTreeNode<DrawCell> node, int distCache){
|
||||||
//breaking out into dedicated function so can add case handling ie if we want
|
//breaking out into dedicated function so can add case handling ie if we want
|
||||||
//to combine fullres nodes into larger nodes to conserve on draw calls
|
//to combine fullres nodes into larger nodes to conserve on draw calls
|
||||||
return
|
return
|
||||||
@ -620,7 +620,7 @@ public class ClientDrawCellManager {
|
|||||||
* @param minLeafLod The minimum LOD required to evaluate a leaf
|
* @param minLeafLod The minimum LOD required to evaluate a leaf
|
||||||
* @return true if should request chunk data, false otherwise
|
* @return true if should request chunk data, false otherwise
|
||||||
*/
|
*/
|
||||||
public boolean shouldRequest(Vector3i pos, FloatingChunkTreeNode<DrawCell> node, int minLeafLod, int distCache){
|
public boolean shouldRequest(Vector3i pos, WorldOctTreeNode<DrawCell> node, int minLeafLod, int distCache){
|
||||||
return
|
return
|
||||||
node.getData() != null &&
|
node.getData() != null &&
|
||||||
!node.getData().hasRequested() &&
|
!node.getData().hasRequested() &&
|
||||||
@ -666,7 +666,7 @@ public class ClientDrawCellManager {
|
|||||||
* @param minLeafLod The minimum LOD required to evaluate a leaf
|
* @param minLeafLod The minimum LOD required to evaluate a leaf
|
||||||
* @return true if should generate, false otherwise
|
* @return true if should generate, false otherwise
|
||||||
*/
|
*/
|
||||||
public boolean shouldGenerate(Vector3i pos, FloatingChunkTreeNode<DrawCell> node, int minLeafLod, int distCache){
|
public boolean shouldGenerate(Vector3i pos, WorldOctTreeNode<DrawCell> node, int minLeafLod, int distCache){
|
||||||
return
|
return
|
||||||
node.getData() != null &&
|
node.getData() != null &&
|
||||||
!node.getData().hasGenerated() &&
|
!node.getData().hasGenerated() &&
|
||||||
@ -710,7 +710,7 @@ public class ClientDrawCellManager {
|
|||||||
* @param node The node
|
* @param node The node
|
||||||
* @return true if should destroy, false otherwise
|
* @return true if should destroy, false otherwise
|
||||||
*/
|
*/
|
||||||
public boolean shouldDestroy(FloatingChunkTreeNode<DrawCell> node){
|
public boolean shouldDestroy(WorldOctTreeNode<DrawCell> node){
|
||||||
return
|
return
|
||||||
node.getData() != null &&
|
node.getData() != null &&
|
||||||
node.getData().getEntity() != null
|
node.getData().getEntity() != null
|
||||||
@ -728,7 +728,7 @@ public class ClientDrawCellManager {
|
|||||||
* Recursively destroy a tree
|
* Recursively destroy a tree
|
||||||
* @param node The root of the tree
|
* @param node The root of the tree
|
||||||
*/
|
*/
|
||||||
private void recursivelyDestroy(FloatingChunkTreeNode<DrawCell> node){
|
private void recursivelyDestroy(WorldOctTreeNode<DrawCell> node){
|
||||||
if(node.getChildren().size() > 0){
|
if(node.getChildren().size() > 0){
|
||||||
node.getChildren().forEach(child -> recursivelyDestroy(child));
|
node.getChildren().forEach(child -> recursivelyDestroy(child));
|
||||||
}
|
}
|
||||||
@ -741,9 +741,9 @@ public class ClientDrawCellManager {
|
|||||||
* Destroys two layers of nodes
|
* Destroys two layers of nodes
|
||||||
* @param node The top node
|
* @param node The top node
|
||||||
*/
|
*/
|
||||||
private void twoLayerDestroy(FloatingChunkTreeNode<DrawCell> node){
|
private void twoLayerDestroy(WorldOctTreeNode<DrawCell> node){
|
||||||
if(node.getData() == null){
|
if(node.getData() == null){
|
||||||
for(FloatingChunkTreeNode<DrawCell> child : node.getChildren()){
|
for(WorldOctTreeNode<DrawCell> child : node.getChildren()){
|
||||||
if(child.getData() != null){
|
if(child.getData() != null){
|
||||||
child.getData().destroy();
|
child.getData().destroy();
|
||||||
}
|
}
|
||||||
@ -797,7 +797,7 @@ public class ClientDrawCellManager {
|
|||||||
* @param cell The cell
|
* @param cell The cell
|
||||||
* @return true if all cells were successfully requested, false otherwise
|
* @return true if all cells were successfully requested, false otherwise
|
||||||
*/
|
*/
|
||||||
private boolean requestChunks(WorldOctTree.FloatingChunkTreeNode<DrawCell> node, List<DrawCellFace> highResFaces){
|
private boolean requestChunks(WorldOctTree.WorldOctTreeNode<DrawCell> node, List<DrawCellFace> highResFaces){
|
||||||
DrawCell cell = node.getData();
|
DrawCell cell = node.getData();
|
||||||
int lod = this.chunkTree.getMaxLevel() - node.getLevel();
|
int lod = this.chunkTree.getMaxLevel() - node.getLevel();
|
||||||
int spacingFactor = (int)Math.pow(2,lod);
|
int spacingFactor = (int)Math.pow(2,lod);
|
||||||
@ -873,7 +873,7 @@ public class ClientDrawCellManager {
|
|||||||
* @param highResFace The higher resolution face of a not-full-resolution chunk. Null if the chunk is max resolution or there is no higher resolution face for the current chunk
|
* @param highResFace The higher resolution face of a not-full-resolution chunk. Null if the chunk is max resolution or there is no higher resolution face for the current chunk
|
||||||
* @return true if all data is available, false otherwise
|
* @return true if all data is available, false otherwise
|
||||||
*/
|
*/
|
||||||
private boolean containsDataToGenerate(WorldOctTree.FloatingChunkTreeNode<DrawCell> node, List<DrawCellFace> highResFaces){
|
private boolean containsDataToGenerate(WorldOctTree.WorldOctTreeNode<DrawCell> node, List<DrawCellFace> highResFaces){
|
||||||
DrawCell cell = node.getData();
|
DrawCell cell = node.getData();
|
||||||
int lod = this.chunkTree.getMaxLevel() - node.getLevel();
|
int lod = this.chunkTree.getMaxLevel() - node.getLevel();
|
||||||
int spacingFactor = (int)Math.pow(2,lod);
|
int spacingFactor = (int)Math.pow(2,lod);
|
||||||
@ -966,7 +966,7 @@ public class ClientDrawCellManager {
|
|||||||
* Recursively calculates the status of the manager
|
* Recursively calculates the status of the manager
|
||||||
* @param node The root node
|
* @param node The root node
|
||||||
*/
|
*/
|
||||||
private void recursivelyCalculateStatus(FloatingChunkTreeNode<DrawCell> node){
|
private void recursivelyCalculateStatus(WorldOctTreeNode<DrawCell> node){
|
||||||
if(node.getLevel() == this.chunkTree.getMaxLevel() - 1){
|
if(node.getLevel() == this.chunkTree.getMaxLevel() - 1){
|
||||||
halfResCount++;
|
halfResCount++;
|
||||||
}
|
}
|
||||||
@ -977,8 +977,8 @@ public class ClientDrawCellManager {
|
|||||||
generated++;
|
generated++;
|
||||||
}
|
}
|
||||||
if(node.getChildren() != null && node.getChildren().size() > 0){
|
if(node.getChildren() != null && node.getChildren().size() > 0){
|
||||||
List<FloatingChunkTreeNode<DrawCell>> children = new LinkedList<FloatingChunkTreeNode<DrawCell>>(node.getChildren());
|
List<WorldOctTreeNode<DrawCell>> children = new LinkedList<WorldOctTreeNode<DrawCell>>(node.getChildren());
|
||||||
for(FloatingChunkTreeNode<DrawCell> child : children){
|
for(WorldOctTreeNode<DrawCell> child : children){
|
||||||
recursivelyCalculateStatus(child);
|
recursivelyCalculateStatus(child);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1024,7 +1024,7 @@ public class ClientDrawCellManager {
|
|||||||
* @return The draw cell if it exists, null otherwise
|
* @return The draw cell if it exists, null otherwise
|
||||||
*/
|
*/
|
||||||
public DrawCell getDrawCell(int worldX, int worldY, int worldZ){
|
public DrawCell getDrawCell(int worldX, int worldY, int worldZ){
|
||||||
FloatingChunkTreeNode<DrawCell> node = this.chunkTree.search(new Vector3i(worldX,worldY,worldZ), false);
|
WorldOctTreeNode<DrawCell> node = this.chunkTree.search(new Vector3i(worldX,worldY,worldZ), false);
|
||||||
if(node != null){
|
if(node != null){
|
||||||
return node.getData();
|
return node.getData();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,7 +15,7 @@ import electrosphere.entity.types.terrain.TerrainChunk;
|
|||||||
import electrosphere.renderer.meshgen.TransvoxelModelGeneration;
|
import electrosphere.renderer.meshgen.TransvoxelModelGeneration;
|
||||||
import electrosphere.renderer.meshgen.TransvoxelModelGeneration.TransvoxelChunkData;
|
import electrosphere.renderer.meshgen.TransvoxelModelGeneration.TransvoxelChunkData;
|
||||||
import electrosphere.server.terrain.manager.ServerTerrainChunk;
|
import electrosphere.server.terrain.manager.ServerTerrainChunk;
|
||||||
import electrosphere.util.ds.octree.WorldOctTree.FloatingChunkTreeNode;
|
import electrosphere.util.ds.octree.WorldOctTree.WorldOctTreeNode;
|
||||||
import electrosphere.util.math.GeomUtils;
|
import electrosphere.util.math.GeomUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -536,7 +536,7 @@ public class DrawCell {
|
|||||||
* @param distCache the lod value under which distance caches are invalidated
|
* @param distCache the lod value under which distance caches are invalidated
|
||||||
* @return the distance
|
* @return the distance
|
||||||
*/
|
*/
|
||||||
public double getMinDistance(Vector3i worldPos, FloatingChunkTreeNode<DrawCell> node, int distCache){
|
public double getMinDistance(Vector3i worldPos, WorldOctTreeNode<DrawCell> node, int distCache){
|
||||||
if(cachedMinDistance != INVALID_DIST_CACHE && distCache < lod){
|
if(cachedMinDistance != INVALID_DIST_CACHE && distCache < lod){
|
||||||
return cachedMinDistance;
|
return cachedMinDistance;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -21,12 +21,12 @@ public class WorldOctTree <T> {
|
|||||||
/**
|
/**
|
||||||
* The root node
|
* The root node
|
||||||
*/
|
*/
|
||||||
private FloatingChunkTreeNode<T> root = null;
|
private WorldOctTreeNode<T> root = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The list of all nodes in the tree
|
* The list of all nodes in the tree
|
||||||
*/
|
*/
|
||||||
List<FloatingChunkTreeNode<T>> nodes = null;
|
List<WorldOctTreeNode<T>> nodes = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The minimum position
|
* The minimum position
|
||||||
@ -60,8 +60,8 @@ public class WorldOctTree <T> {
|
|||||||
//calculate max level
|
//calculate max level
|
||||||
int dimRaw = max.x - min.x;
|
int dimRaw = max.x - min.x;
|
||||||
this.maxLevel = (int)MathUtils.log2(dimRaw);
|
this.maxLevel = (int)MathUtils.log2(dimRaw);
|
||||||
this.nodes = new ArrayList<FloatingChunkTreeNode<T>>();
|
this.nodes = new ArrayList<WorldOctTreeNode<T>>();
|
||||||
this.root = new FloatingChunkTreeNode<T>(this, 0, new Vector3i(min), new Vector3i(max));
|
this.root = new WorldOctTreeNode<T>(this, 0, new Vector3i(min), new Vector3i(max));
|
||||||
this.root.isLeaf = true;
|
this.root.isLeaf = true;
|
||||||
this.nodes.add(this.root);
|
this.nodes.add(this.root);
|
||||||
}
|
}
|
||||||
@ -71,7 +71,7 @@ public class WorldOctTree <T> {
|
|||||||
* @param parent The parent
|
* @param parent The parent
|
||||||
* @return The new non-leaf node
|
* @return The new non-leaf node
|
||||||
*/
|
*/
|
||||||
public FloatingChunkTreeNode<T> split(FloatingChunkTreeNode<T> existing){
|
public WorldOctTreeNode<T> split(WorldOctTreeNode<T> existing){
|
||||||
if(!existing.isLeaf()){
|
if(!existing.isLeaf()){
|
||||||
throw new IllegalArgumentException("Tried to split non-leaf!");
|
throw new IllegalArgumentException("Tried to split non-leaf!");
|
||||||
}
|
}
|
||||||
@ -81,20 +81,20 @@ public class WorldOctTree <T> {
|
|||||||
int midY = (max.y - min.y) / 2 + min.y;
|
int midY = (max.y - min.y) / 2 + min.y;
|
||||||
int midZ = (max.z - min.z) / 2 + min.z;
|
int midZ = (max.z - min.z) / 2 + min.z;
|
||||||
int currentLevel = existing.getLevel();
|
int currentLevel = existing.getLevel();
|
||||||
FloatingChunkTreeNode<T> newContainer = new FloatingChunkTreeNode<>(this, currentLevel, min, max);
|
WorldOctTreeNode<T> newContainer = new WorldOctTreeNode<>(this, currentLevel, min, max);
|
||||||
//add children
|
//add children
|
||||||
newContainer.addChild(new FloatingChunkTreeNode<T>(this, currentLevel + 1, new Vector3i(min.x,min.y,min.z), new Vector3i(midX,midY,midZ)));
|
newContainer.addChild(new WorldOctTreeNode<T>(this, currentLevel + 1, new Vector3i(min.x,min.y,min.z), new Vector3i(midX,midY,midZ)));
|
||||||
newContainer.addChild(new FloatingChunkTreeNode<T>(this, currentLevel + 1, new Vector3i(midX,min.y,min.z), new Vector3i(max.x,midY,midZ)));
|
newContainer.addChild(new WorldOctTreeNode<T>(this, currentLevel + 1, new Vector3i(midX,min.y,min.z), new Vector3i(max.x,midY,midZ)));
|
||||||
newContainer.addChild(new FloatingChunkTreeNode<T>(this, currentLevel + 1, new Vector3i(min.x,midY,min.z), new Vector3i(midX,max.y,midZ)));
|
newContainer.addChild(new WorldOctTreeNode<T>(this, currentLevel + 1, new Vector3i(min.x,midY,min.z), new Vector3i(midX,max.y,midZ)));
|
||||||
newContainer.addChild(new FloatingChunkTreeNode<T>(this, currentLevel + 1, new Vector3i(midX,midY,min.z), new Vector3i(max.x,max.y,midZ)));
|
newContainer.addChild(new WorldOctTreeNode<T>(this, currentLevel + 1, new Vector3i(midX,midY,min.z), new Vector3i(max.x,max.y,midZ)));
|
||||||
//
|
//
|
||||||
newContainer.addChild(new FloatingChunkTreeNode<T>(this, currentLevel + 1, new Vector3i(min.x,min.y,midZ), new Vector3i(midX,midY,max.z)));
|
newContainer.addChild(new WorldOctTreeNode<T>(this, currentLevel + 1, new Vector3i(min.x,min.y,midZ), new Vector3i(midX,midY,max.z)));
|
||||||
newContainer.addChild(new FloatingChunkTreeNode<T>(this, currentLevel + 1, new Vector3i(midX,min.y,midZ), new Vector3i(max.x,midY,max.z)));
|
newContainer.addChild(new WorldOctTreeNode<T>(this, currentLevel + 1, new Vector3i(midX,min.y,midZ), new Vector3i(max.x,midY,max.z)));
|
||||||
newContainer.addChild(new FloatingChunkTreeNode<T>(this, currentLevel + 1, new Vector3i(min.x,midY,midZ), new Vector3i(midX,max.y,max.z)));
|
newContainer.addChild(new WorldOctTreeNode<T>(this, currentLevel + 1, new Vector3i(min.x,midY,midZ), new Vector3i(midX,max.y,max.z)));
|
||||||
newContainer.addChild(new FloatingChunkTreeNode<T>(this, currentLevel + 1, new Vector3i(midX,midY,midZ), new Vector3i(max.x,max.y,max.z)));
|
newContainer.addChild(new WorldOctTreeNode<T>(this, currentLevel + 1, new Vector3i(midX,midY,midZ), new Vector3i(max.x,max.y,max.z)));
|
||||||
|
|
||||||
boolean foundMin = false;
|
boolean foundMin = false;
|
||||||
for(FloatingChunkTreeNode<T> child : newContainer.getChildren()){
|
for(WorldOctTreeNode<T> child : newContainer.getChildren()){
|
||||||
if(child.getMinBound().distance(newContainer.getMinBound()) == 0){
|
if(child.getMinBound().distance(newContainer.getMinBound()) == 0){
|
||||||
foundMin = true;
|
foundMin = true;
|
||||||
}
|
}
|
||||||
@ -104,7 +104,7 @@ public class WorldOctTree <T> {
|
|||||||
message = message + min + " " + max + "\n";
|
message = message + min + " " + max + "\n";
|
||||||
message = message + midX + " " + midY + " " + midZ + "\n";
|
message = message + midX + " " + midY + " " + midZ + "\n";
|
||||||
message = message + "container mid: " + newContainer.getMinBound();
|
message = message + "container mid: " + newContainer.getMinBound();
|
||||||
for(FloatingChunkTreeNode<T> child : newContainer.getChildren()){
|
for(WorldOctTreeNode<T> child : newContainer.getChildren()){
|
||||||
message = message + "child min: " + child.getMinBound() + "\n";
|
message = message + "child min: " + child.getMinBound() + "\n";
|
||||||
}
|
}
|
||||||
throw new Error(message);
|
throw new Error(message);
|
||||||
@ -126,14 +126,14 @@ public class WorldOctTree <T> {
|
|||||||
* @param parent The non-leaf
|
* @param parent The non-leaf
|
||||||
* @return The new leaf node
|
* @return The new leaf node
|
||||||
*/
|
*/
|
||||||
public FloatingChunkTreeNode<T> join(FloatingChunkTreeNode<T> existing){
|
public WorldOctTreeNode<T> join(WorldOctTreeNode<T> existing){
|
||||||
if(existing.isLeaf()){
|
if(existing.isLeaf()){
|
||||||
throw new IllegalArgumentException("Tried to split non-leaf!");
|
throw new IllegalArgumentException("Tried to split non-leaf!");
|
||||||
}
|
}
|
||||||
Vector3i min = existing.getMinBound();
|
Vector3i min = existing.getMinBound();
|
||||||
Vector3i max = existing.getMaxBound();
|
Vector3i max = existing.getMaxBound();
|
||||||
int currentLevel = existing.getLevel();
|
int currentLevel = existing.getLevel();
|
||||||
FloatingChunkTreeNode<T> newContainer = new FloatingChunkTreeNode<>(this, currentLevel, min, max);
|
WorldOctTreeNode<T> newContainer = new WorldOctTreeNode<>(this, currentLevel, min, max);
|
||||||
|
|
||||||
//replace existing node
|
//replace existing node
|
||||||
this.replaceNode(existing,newContainer);
|
this.replaceNode(existing,newContainer);
|
||||||
@ -151,11 +151,11 @@ public class WorldOctTree <T> {
|
|||||||
* @param existing the existing node
|
* @param existing the existing node
|
||||||
* @param newNode the new node
|
* @param newNode the new node
|
||||||
*/
|
*/
|
||||||
private void replaceNode(FloatingChunkTreeNode<T> existing, FloatingChunkTreeNode<T> newNode){
|
private void replaceNode(WorldOctTreeNode<T> existing, WorldOctTreeNode<T> newNode){
|
||||||
if(existing == this.root){
|
if(existing == this.root){
|
||||||
this.root = newNode;
|
this.root = newNode;
|
||||||
} else {
|
} else {
|
||||||
FloatingChunkTreeNode<T> parent = existing.getParent();
|
WorldOctTreeNode<T> parent = existing.getParent();
|
||||||
int index = parent.children.indexOf(existing);
|
int index = parent.children.indexOf(existing);
|
||||||
parent.removeChild(existing);
|
parent.removeChild(existing);
|
||||||
parent.addChild(index, newNode);
|
parent.addChild(index, newNode);
|
||||||
@ -165,7 +165,7 @@ public class WorldOctTree <T> {
|
|||||||
/**
|
/**
|
||||||
* Gets the root node of the tree
|
* Gets the root node of the tree
|
||||||
*/
|
*/
|
||||||
public FloatingChunkTreeNode<T> getRoot() {
|
public WorldOctTreeNode<T> getRoot() {
|
||||||
return this.root;
|
return this.root;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -190,7 +190,7 @@ public class WorldOctTree <T> {
|
|||||||
*/
|
*/
|
||||||
public void clear(){
|
public void clear(){
|
||||||
this.nodes.clear();
|
this.nodes.clear();
|
||||||
this.root = new FloatingChunkTreeNode<T>(this, 0, new Vector3i(min), new Vector3i(max));
|
this.root = new WorldOctTreeNode<T>(this, 0, new Vector3i(min), new Vector3i(max));
|
||||||
this.root.isLeaf = true;
|
this.root.isLeaf = true;
|
||||||
this.nodes.add(this.root);
|
this.nodes.add(this.root);
|
||||||
}
|
}
|
||||||
@ -201,7 +201,7 @@ public class WorldOctTree <T> {
|
|||||||
* @param returnNonLeaf If true, the function can return non-leaf nodes, otherwise will only return leaf nodes
|
* @param returnNonLeaf If true, the function can return non-leaf nodes, otherwise will only return leaf nodes
|
||||||
* @return The leaf if it exists, null otherwise
|
* @return The leaf if it exists, null otherwise
|
||||||
*/
|
*/
|
||||||
public FloatingChunkTreeNode<T> search(Vector3i position, boolean returnNonLeaf){
|
public WorldOctTreeNode<T> search(Vector3i position, boolean returnNonLeaf){
|
||||||
return this.search(position,returnNonLeaf,this.maxLevel);
|
return this.search(position,returnNonLeaf,this.maxLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,7 +212,7 @@ public class WorldOctTree <T> {
|
|||||||
* @param maxLevel The maximum level to search for
|
* @param maxLevel The maximum level to search for
|
||||||
* @return The leaf if it exists, null otherwise
|
* @return The leaf if it exists, null otherwise
|
||||||
*/
|
*/
|
||||||
public FloatingChunkTreeNode<T> search(Vector3i position, boolean returnNonLeaf, int maxLevel){
|
public WorldOctTreeNode<T> search(Vector3i position, boolean returnNonLeaf, int maxLevel){
|
||||||
//out of bounds check
|
//out of bounds check
|
||||||
if(
|
if(
|
||||||
position.x < min.x || position.x > max.x ||
|
position.x < min.x || position.x > max.x ||
|
||||||
@ -221,7 +221,7 @@ public class WorldOctTree <T> {
|
|||||||
){
|
){
|
||||||
throw new Error("Trying to search for node outside tree range!");
|
throw new Error("Trying to search for node outside tree range!");
|
||||||
}
|
}
|
||||||
FloatingChunkTreeNode<T> searchResult = recursiveSearchUnsafe(root,position,maxLevel);
|
WorldOctTreeNode<T> searchResult = recursiveSearchUnsafe(root,position,maxLevel);
|
||||||
if(!returnNonLeaf && !searchResult.isLeaf()){
|
if(!returnNonLeaf && !searchResult.isLeaf()){
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -235,7 +235,7 @@ public class WorldOctTree <T> {
|
|||||||
* @param maxLevel The maximum level to search for
|
* @param maxLevel The maximum level to search for
|
||||||
* @return The found node
|
* @return The found node
|
||||||
*/
|
*/
|
||||||
private FloatingChunkTreeNode<T> recursiveSearchUnsafe(FloatingChunkTreeNode<T> currentNode, Vector3i position, int maxLevel){
|
private WorldOctTreeNode<T> recursiveSearchUnsafe(WorldOctTreeNode<T> currentNode, Vector3i position, int maxLevel){
|
||||||
if(maxLevel < 0){
|
if(maxLevel < 0){
|
||||||
throw new Error("Provided invalid max level! Must be created than 0! " + maxLevel);
|
throw new Error("Provided invalid max level! Must be created than 0! " + maxLevel);
|
||||||
}
|
}
|
||||||
@ -246,7 +246,7 @@ public class WorldOctTree <T> {
|
|||||||
return currentNode;
|
return currentNode;
|
||||||
}
|
}
|
||||||
if(currentNode.getChildren().size() > 0){
|
if(currentNode.getChildren().size() > 0){
|
||||||
for(FloatingChunkTreeNode<T> child : currentNode.getChildren()){
|
for(WorldOctTreeNode<T> child : currentNode.getChildren()){
|
||||||
if(
|
if(
|
||||||
position.x < child.getMaxBound().x && position.x >= child.getMinBound().x &&
|
position.x < child.getMaxBound().x && position.x >= child.getMinBound().x &&
|
||||||
position.y < child.getMaxBound().y && position.y >= child.getMinBound().y &&
|
position.y < child.getMaxBound().y && position.y >= child.getMinBound().y &&
|
||||||
@ -258,7 +258,7 @@ public class WorldOctTree <T> {
|
|||||||
String message = "Current node is within range, but no children are! This does not make any sense.\n";
|
String message = "Current node is within range, but no children are! This does not make any sense.\n";
|
||||||
|
|
||||||
message = message + " current pos: " + currentNode.getMinBound() + " " + currentNode.getMaxBound() + "\n";
|
message = message + " current pos: " + currentNode.getMinBound() + " " + currentNode.getMaxBound() + "\n";
|
||||||
for(FloatingChunkTreeNode<T> child : currentNode.getChildren()){
|
for(WorldOctTreeNode<T> child : currentNode.getChildren()){
|
||||||
message = message + " child " + child + " pos: " + child.getMinBound() + " " + child.getMaxBound() + "\n";
|
message = message + " child " + child + " pos: " + child.getMinBound() + " " + child.getMaxBound() + "\n";
|
||||||
}
|
}
|
||||||
message = message + "position to search: " + position + "\n";
|
message = message + "position to search: " + position + "\n";
|
||||||
@ -272,13 +272,13 @@ public class WorldOctTree <T> {
|
|||||||
/**
|
/**
|
||||||
* A node in a chunk tree
|
* A node in a chunk tree
|
||||||
*/
|
*/
|
||||||
public static class FloatingChunkTreeNode<T> {
|
public static class WorldOctTreeNode<T> {
|
||||||
|
|
||||||
//True if this is a leaf node, false otherwise
|
//True if this is a leaf node, false otherwise
|
||||||
private boolean isLeaf;
|
private boolean isLeaf;
|
||||||
|
|
||||||
//the parent node
|
//the parent node
|
||||||
private FloatingChunkTreeNode<T> parent;
|
private WorldOctTreeNode<T> parent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The tree containing this node
|
* The tree containing this node
|
||||||
@ -286,7 +286,7 @@ public class WorldOctTree <T> {
|
|||||||
private WorldOctTree<T> containingTree;
|
private WorldOctTree<T> containingTree;
|
||||||
|
|
||||||
//the children of this node
|
//the children of this node
|
||||||
private List<FloatingChunkTreeNode<T>> children = new LinkedList<FloatingChunkTreeNode<T>>();
|
private List<WorldOctTreeNode<T>> children = new LinkedList<WorldOctTreeNode<T>>();
|
||||||
|
|
||||||
//The data at the node
|
//The data at the node
|
||||||
private T data;
|
private T data;
|
||||||
@ -314,7 +314,7 @@ public class WorldOctTree <T> {
|
|||||||
* @param min The minimum position of the node
|
* @param min The minimum position of the node
|
||||||
* @param max The maximum position of then ode
|
* @param max The maximum position of then ode
|
||||||
*/
|
*/
|
||||||
private FloatingChunkTreeNode(WorldOctTree<T> tree, int level, Vector3i min, Vector3i max){
|
private WorldOctTreeNode(WorldOctTree<T> tree, int level, Vector3i min, Vector3i max){
|
||||||
if(tree == null){
|
if(tree == null){
|
||||||
throw new Error("Invalid tree provided " + tree);
|
throw new Error("Invalid tree provided " + tree);
|
||||||
}
|
}
|
||||||
@ -340,8 +340,8 @@ public class WorldOctTree <T> {
|
|||||||
* @param max The max point
|
* @param max The max point
|
||||||
* @return The node
|
* @return The node
|
||||||
*/
|
*/
|
||||||
public static <T> FloatingChunkTreeNode<T> constructorForTests(WorldOctTree<T> tree, int level, Vector3i min, Vector3i max){
|
public static <T> WorldOctTreeNode<T> constructorForTests(WorldOctTree<T> tree, int level, Vector3i min, Vector3i max){
|
||||||
return new FloatingChunkTreeNode<T>(tree, level, min, max);
|
return new WorldOctTreeNode<T>(tree, level, min, max);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -353,6 +353,22 @@ public class WorldOctTree <T> {
|
|||||||
this.data = data;
|
this.data = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether this node is a leaf or not
|
||||||
|
* @param isLeaf true if it is a leaf, false otherwise
|
||||||
|
*/
|
||||||
|
public void setLeaf(boolean isLeaf){
|
||||||
|
this.isLeaf = isLeaf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the data of the node
|
||||||
|
* @param data The data
|
||||||
|
*/
|
||||||
|
public void setData(T data){
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the data associated with this node
|
* Gets the data associated with this node
|
||||||
*/
|
*/
|
||||||
@ -363,14 +379,14 @@ public class WorldOctTree <T> {
|
|||||||
/**
|
/**
|
||||||
* Gets the parent of this node
|
* Gets the parent of this node
|
||||||
*/
|
*/
|
||||||
public FloatingChunkTreeNode<T> getParent() {
|
public WorldOctTreeNode<T> getParent() {
|
||||||
return parent;
|
return parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the children of this node
|
* Gets the children of this node
|
||||||
*/
|
*/
|
||||||
public List<FloatingChunkTreeNode<T>> getChildren() {
|
public List<WorldOctTreeNode<T>> getChildren() {
|
||||||
return Collections.unmodifiableList(this.children);
|
return Collections.unmodifiableList(this.children);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -418,7 +434,7 @@ public class WorldOctTree <T> {
|
|||||||
* Adds a child to this node
|
* Adds a child to this node
|
||||||
* @param child The child
|
* @param child The child
|
||||||
*/
|
*/
|
||||||
private void addChild(FloatingChunkTreeNode<T> child){
|
private void addChild(WorldOctTreeNode<T> child){
|
||||||
this.children.add(child);
|
this.children.add(child);
|
||||||
child.parent = this;
|
child.parent = this;
|
||||||
}
|
}
|
||||||
@ -428,7 +444,7 @@ public class WorldOctTree <T> {
|
|||||||
* @param index The index of the child
|
* @param index The index of the child
|
||||||
* @param child The child
|
* @param child The child
|
||||||
*/
|
*/
|
||||||
private void addChild(int index, FloatingChunkTreeNode<T> child){
|
private void addChild(int index, WorldOctTreeNode<T> child){
|
||||||
this.children.add(index, child);
|
this.children.add(index, child);
|
||||||
child.parent = this;
|
child.parent = this;
|
||||||
}
|
}
|
||||||
@ -437,7 +453,7 @@ public class WorldOctTree <T> {
|
|||||||
* Removes a child node
|
* Removes a child node
|
||||||
* @param child the child
|
* @param child the child
|
||||||
*/
|
*/
|
||||||
private void removeChild(FloatingChunkTreeNode<T> child){
|
private void removeChild(WorldOctTreeNode<T> child){
|
||||||
this.children.remove(child);
|
this.children.remove(child);
|
||||||
child.parent = null;
|
child.parent = null;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,7 +12,7 @@ import electrosphere.engine.Main;
|
|||||||
import electrosphere.server.terrain.manager.ServerTerrainChunk;
|
import electrosphere.server.terrain.manager.ServerTerrainChunk;
|
||||||
import electrosphere.test.annotations.UnitTest;
|
import electrosphere.test.annotations.UnitTest;
|
||||||
import electrosphere.test.template.extensions.StateCleanupCheckerExtension;
|
import electrosphere.test.template.extensions.StateCleanupCheckerExtension;
|
||||||
import electrosphere.util.ds.octree.WorldOctTree.FloatingChunkTreeNode;
|
import electrosphere.util.ds.octree.WorldOctTree.WorldOctTreeNode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for the client draw cell manager
|
* Tests for the client draw cell manager
|
||||||
@ -39,7 +39,7 @@ public class ClientDrawCellManagerTests {
|
|||||||
ClientDrawCellManager manager = new ClientDrawCellManager(null, 64);
|
ClientDrawCellManager manager = new ClientDrawCellManager(null, 64);
|
||||||
double precomputedMidDist = 0;
|
double precomputedMidDist = 0;
|
||||||
Vector3i playerPos = new Vector3i(0,0,0);
|
Vector3i playerPos = new Vector3i(0,0,0);
|
||||||
FloatingChunkTreeNode<DrawCell> node = FloatingChunkTreeNode.constructorForTests(manager.chunkTree, 1, new Vector3i(16,0,0), new Vector3i(32,16,16));
|
WorldOctTreeNode<DrawCell> node = WorldOctTreeNode.constructorForTests(manager.chunkTree, 1, new Vector3i(16,0,0), new Vector3i(32,16,16));
|
||||||
node.convertToLeaf(DrawCell.generateTerrainCell(new Vector3i(0,0,0),3));
|
node.convertToLeaf(DrawCell.generateTerrainCell(new Vector3i(0,0,0),3));
|
||||||
|
|
||||||
assertTrue(manager.shouldSplit(playerPos, node, 0));
|
assertTrue(manager.shouldSplit(playerPos, node, 0));
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user