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