transvoxel position checking work
This commit is contained in:
parent
bc66523cde
commit
df4fe45dd5
@ -491,6 +491,182 @@ public class DrawCellManager {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
transvoxel algorithm spacing management
|
||||
|
||||
want to specify a radius and have it be a circle so we're not wasting resolution on far off corners
|
||||
To benefit from the LOD, should have a series of for loops
|
||||
First loop iterates over (-largest radius) -> (largest radius) at an interval of the width of the lowest level of detail chunk
|
||||
We check all 8 corners of the chunk to see if they all fall within the largest lod concentric circle
|
||||
There are a few cases to consider
|
||||
- All fall outside the largest LOD radius (ignore)
|
||||
- All but one fall outside thel argest LOD radius (ignore)
|
||||
- All fall within the largest LOD circle (make LOD chunk)
|
||||
- One is within the next LOD radius, others are within the current LOD radius (ignore for this pass)
|
||||
- All are within a lower LOD radius (ignore)
|
||||
|
||||
Once we're done with the largest LOD radius, we go to a higher resolution radius and iterate for smaller bounds
|
||||
|
||||
In a middle LOD level, if all corners are outside, but the lower resolution didn't
|
||||
already pick it up, still need to generate a chunk at the current resolution
|
||||
|
||||
Detection of this case is tricky
|
||||
We could snap the currently considered position to the nearest low-resolution chunk and then bounds check that low resolution chunk for every
|
||||
higher resolution position we're considering
|
||||
This is probably a bad idea
|
||||
|
||||
We could recurse every time a chunk doesn't work for the current level of detail, then evaluate it for a higher level of detail at this closer value
|
||||
|
||||
*/
|
||||
|
||||
//the number of corners to consider for a valid chunk
|
||||
static final int NUM_CORNERS_TO_CONSIDER = 8;
|
||||
|
||||
//offsets to get from current position to the actual corner to consider
|
||||
int[] cornerOffsetsX = new int[]{0,1,0,1,0,1,0,1,};
|
||||
int[] cornerOffsetsY = new int[]{0,0,0,0,1,1,1,1,};
|
||||
int[] cornerOffsetsZ = new int[]{0,0,1,1,0,0,1,1,};
|
||||
|
||||
/**
|
||||
* Recursive function that does chunk validity checking
|
||||
* @param playerChunkPos
|
||||
* @param minPoint
|
||||
* @param maxPoint
|
||||
* @param currentLOD
|
||||
*/
|
||||
public void assesChunkPositionsAtLOD(
|
||||
Vector3i playerChunkPos,
|
||||
Vector3i minPoint,
|
||||
Vector3i maxPoint,
|
||||
int currentLOD
|
||||
){
|
||||
Vector3i currentChunkPositionConsidered = new Vector3i(playerChunkPos); // The chunk position we're currently considering
|
||||
double currentRadius = lodLevelRadiusTable[currentLOD];
|
||||
double nextRadius = 0;
|
||||
int increment = 1;
|
||||
if(currentLOD > 0){
|
||||
//only works when the LOD is greater than 0. When it's 0, there is no lower bound on chunk positions to generate
|
||||
nextRadius = lodLevelRadiusTable[currentLOD-1];
|
||||
increment = (int)Math.pow(2,currentLOD);
|
||||
}
|
||||
|
||||
//iterate
|
||||
for(int x = minPoint.x; x < maxPoint.x; x = x + increment){
|
||||
for(int y = minPoint.y; y < maxPoint.x; y = y + increment){
|
||||
for(int z = minPoint.z; z < maxPoint.x; z = z + increment){
|
||||
//we have 8 corners to consider
|
||||
//need to identify which case the current position is
|
||||
int positionCase = 0;
|
||||
for(int j = 0; j < NUM_CORNERS_TO_CONSIDER; j++){
|
||||
currentChunkPositionConsidered.set(
|
||||
x + cornerOffsetsX[j] * increment,
|
||||
y + cornerOffsetsY[j] * increment,
|
||||
z + cornerOffsetsZ[j] * increment
|
||||
);
|
||||
//figure out the case of this corner
|
||||
double distance = currentChunkPositionConsidered.distance(playerChunkPos);
|
||||
if(distance > currentRadius){
|
||||
positionCase = 1;
|
||||
break;
|
||||
} else if(distance <= nextRadius){
|
||||
positionCase = 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
switch(positionCase){
|
||||
case 0: {
|
||||
//fully within current band, generate chunk
|
||||
} break;
|
||||
case 1: {
|
||||
//partially outside bound, ignore
|
||||
} break;
|
||||
case 2: {
|
||||
//partially inside higher resolution bound, recurse
|
||||
assesChunkPositionsAtLOD(
|
||||
playerChunkPos,
|
||||
new Vector3i(x,y,z),
|
||||
new Vector3i(x+increment,y+increment,z+increment),
|
||||
currentLOD
|
||||
);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assess all LOD chunk levels
|
||||
*/
|
||||
public void assesLODChunks(){
|
||||
|
||||
//pre-existing values
|
||||
Vector3d playerPosition = EntityUtils.getPosition(Globals.playerEntity);
|
||||
Vector3i playerChunkPosition = Globals.clientWorldData.convertRealToChunkSpace(playerPosition);
|
||||
|
||||
//variables used while iterating across chunk positions
|
||||
double currentRadius = 0; //the current radius is in units of chunks, even though it's a double (it's discrete, not real)
|
||||
double nextRadius = 0; //the next radius is in units of chunks, even though it's a double (it's discrete, not real)
|
||||
int increment = 1; //the increment is in units of chunks, not real
|
||||
//the offsets from the player's position to
|
||||
//the nearest possible spot we could place a chunk of the current LOD at (in units of chunks)
|
||||
Vector3i lowerOffsets = new Vector3i(0,0,0);
|
||||
Vector3i currentChunkPositionConsidered = new Vector3i(playerChunkPosition); // The chunk position we're currently considering
|
||||
|
||||
//actual logic to search for valid chunks
|
||||
for(int i = NUMBER_OF_LOD_LEVELS - 1; i >= 0; i--){
|
||||
currentRadius = lodLevelRadiusTable[i];
|
||||
nextRadius = 0;
|
||||
increment = 1;
|
||||
if(i > 0){
|
||||
//only works when the LOD is greater than 0. When it's 0, there is no lower bound on chunk positions to generate
|
||||
nextRadius = lodLevelRadiusTable[i-1];
|
||||
increment = (int)Math.pow(2,i);
|
||||
}
|
||||
//calculate offsets to get from player's current chunk position to the lower resolution grid for the current LOD
|
||||
lowerOffsets.x = playerChunkPosition.x % ((int)increment);
|
||||
lowerOffsets.y = playerChunkPosition.y % ((int)increment);
|
||||
lowerOffsets.z = playerChunkPosition.z % ((int)increment);
|
||||
|
||||
//iterate
|
||||
for(int x = -(int)currentRadius - lowerOffsets.x; x < currentRadius; x = x + increment){
|
||||
for(int y = -(int)currentRadius - lowerOffsets.y; y < currentRadius; y = y + increment){
|
||||
for(int z = -(int)currentRadius - lowerOffsets.z; z < currentRadius; z = z + increment){
|
||||
//we have 8 corners to consider
|
||||
//need to identify which case the current position is
|
||||
int positionCase = 0;
|
||||
for(int j = 0; j < NUM_CORNERS_TO_CONSIDER; j++){
|
||||
currentChunkPositionConsidered.set(
|
||||
x + cornerOffsetsX[j] * increment,
|
||||
y + cornerOffsetsY[j] * increment,
|
||||
z + cornerOffsetsZ[j] * increment
|
||||
);
|
||||
//figure out the case of this corner
|
||||
double distance = currentChunkPositionConsidered.distance(playerChunkPosition);
|
||||
if(distance > currentRadius){
|
||||
positionCase = 1;
|
||||
break;
|
||||
} else if(distance <= nextRadius){
|
||||
positionCase = 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
switch(positionCase){
|
||||
case 0: {
|
||||
//fully within current band, generate chunk
|
||||
} break;
|
||||
case 1: {
|
||||
//partially outside bound, ignore
|
||||
} break;
|
||||
case 2: {
|
||||
//partially inside higher resolution bound, recurse
|
||||
} break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user