foliage work
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit

This commit is contained in:
austin 2024-11-21 18:30:17 -05:00
parent 4d934873c3
commit cc51e4c908
3 changed files with 168 additions and 170 deletions

View File

@ -1113,6 +1113,7 @@ Change grass texture
Fix allocations on FoliageChunk child iterations Fix allocations on FoliageChunk child iterations
Reduce near clip to remove flickering on far chunks Reduce near clip to remove flickering on far chunks
Complete overhaul of foliage management Complete overhaul of foliage management
Fix foliage inconsistently placing on varied terrain
# TODO # TODO

View File

@ -276,7 +276,7 @@ public class FoliageCell {
*/ */
protected void generate(){ protected void generate(){
boolean shouldGenerate = false; boolean shouldGenerate = false;
if(voxelPos.y + 1 >= ServerTerrainChunk.CHUNK_DIMENSION){ if(!Globals.clientDrawCellManager.hasGeneratedPhysics(worldPos.x, worldPos.y, worldPos.z)){
return; return;
} }
ChunkData data = Globals.clientTerrainManager.getChunkDataAtWorldPoint(worldPos,ChunkData.NO_STRIDE); ChunkData data = Globals.clientTerrainManager.getChunkDataAtWorldPoint(worldPos,ChunkData.NO_STRIDE);
@ -285,61 +285,38 @@ public class FoliageCell {
} }
//get foliage types supported //get foliage types supported
List<String> foliageTypesSupported = new LinkedList<String>(); List<String> foliageTypesSupported = new LinkedList<String>();
boolean airAbove = data.getType(voxelPos.x,voxelPos.y+1,voxelPos.z) == 0; boolean airAbove = true;
int scale = (int)Math.pow(2,lod); int scale = (int)Math.pow(2,lod);
for(int x = 0; x < scale; x++){ for(int x = 0; x < scale; x++){
for(int y = 0; y < scale; y++){ for(int y = 0; y < scale; y++){
for(int z = 0; z < scale; z++){ for(int z = 0; z < scale; z++){
List<String> currentList = Globals.gameConfigCurrent.getVoxelData().getTypeFromId(data.getType(voxelPos)).getAmbientFoliage(); if(voxelPos.y + y >= ServerTerrainChunk.CHUNK_DIMENSION){
continue;
}
List<String> currentList = Globals.gameConfigCurrent.getVoxelData().getTypeFromId(data.getType(new Vector3i(voxelPos).add(x,y,z))).getAmbientFoliage();
if(currentList == null){ if(currentList == null){
continue; continue;
} }
foliageTypesSupported.addAll(currentList); foliageTypesSupported.addAll(currentList);
airAbove = data.getType(voxelPos.x,voxelPos.y+1,voxelPos.z) == 0; airAbove = data.getType(voxelPos.x + x,voxelPos.y + y + 1,voxelPos.z + z) == 0;
if(foliageTypesSupported != null && foliageTypesSupported.size() > 0 && airAbove){ if(foliageTypesSupported != null && foliageTypesSupported.size() > 0 && airAbove){
shouldGenerate = true; shouldGenerate = true;
break;
} }
} }
if(shouldGenerate){
break;
}
}
if(shouldGenerate){
break;
} }
} }
if(shouldGenerate){ if(shouldGenerate){
Entity oldEntity = this.modelEntity;
//create entity //create entity
this.modelEntity = EntityCreationUtils.createClientSpatialEntity(); this.modelEntity = EntityCreationUtils.createClientSpatialEntity();
FoliageModel.clientCreateFoliageChunkEntity(foliageTypesSupported,scale,this.modelEntity,this.getRealPos(),worldPos,voxelPos,null,null); FoliageModel.clientCreateFoliageChunkEntity(foliageTypesSupported,scale,this.modelEntity,this.getRealPos(),worldPos,voxelPos,notifyTarget,oldEntity);
//get type
// String foliageTypeName = foliageTypesSupported.get(placementRandomizer.nextInt() % foliageTypesSupported.size());
// FoliageType foliageType = Globals.gameConfigCurrent.getFoliageMap().getFoliage(foliageTypeName);
// //create cell and buffer
// ByteBuffer buffer = BufferUtils.createByteBuffer(TARGET_FOLIAGE_PER_CELL * SINGLE_FOLIAGE_DATA_SIZE_BYTES);
// if(buffer.capacity() < TARGET_FOLIAGE_PER_CELL * SINGLE_FOLIAGE_DATA_SIZE_BYTES){
// LoggerInterface.loggerEngine.WARNING("Failed to allocate data for foliage cell! " + buffer.limit());
// }
// FloatBuffer floatBufferView = buffer.asFloatBuffer();
// int drawCount = 0;
// for(int x = 0; x < scale; x++){
// for(int y = 0; y < scale; y++){
// for(int z = 0; z < scale; z++){
// drawCount = drawCount + this.insertBlades(x, y, z, floatBufferView, data);
// }
// }
// }
// // drawCount = drawCount + this.insertBlades(0, 0, 0, floatBufferView, data);
// if(drawCount > 0){
// buffer.position(0);
// buffer.limit(TARGET_FOLIAGE_PER_CELL * SINGLE_FOLIAGE_DATA_SIZE_BYTES);
// //construct data texture
// Texture dataTexture = new Texture(Globals.renderingEngine.getOpenGLState(),buffer,SINGLE_FOLIAGE_DATA_SIZE_BYTES / 4,TARGET_FOLIAGE_PER_CELL);
// //create entity
// this.modelEntity = EntityCreationUtils.createClientSpatialEntity();
// TextureInstancedActor.attachTextureInstancedActor(this.modelEntity, foliageType.getGraphicsTemplate().getModel().getPath(), vertexPath, fragmentPath, dataTexture, drawCount);
// ClientEntityUtils.initiallyPositionEntity(this.modelEntity, this.getRealPos(), new Quaterniond());
// EntityUtils.getScale(this.modelEntity).set(1,1,1);
// //add ambient foliage behavior tree
// AmbientFoliage.attachAmbientFoliageTree(this.modelEntity, 1.0f, foliageType.getGrowthModel().getGrowthRate());
// }
} else { } else {
this.homogenous = true; this.homogenous = true;
} }

View File

@ -48,7 +48,7 @@ public class FoliageModel {
/** /**
* The interval to space along * The interval to space along
*/ */
static final int TARGET_FOLIAGE_SPACING = 50; static final int TARGET_FOLIAGE_SPACING = 25;
/** /**
* The target number of foliage to place per cell * The target number of foliage to place per cell
@ -58,12 +58,12 @@ public class FoliageModel {
/** /**
* The length of the ray to ground test with * The length of the ray to ground test with
*/ */
static final float RAY_LENGTH = 1.0f; static final float RAY_LENGTH = 2.5f;
/** /**
* The height above the chunk to start from when sampling downwards * The height above the chunk to start from when sampling downwards
*/ */
static final float SAMPLE_START_HEIGHT = 0.5f; static final float SAMPLE_START_HEIGHT = 1.0f;
/** /**
* The ID of the air voxel * The ID of the air voxel
@ -86,6 +86,11 @@ public class FoliageModel {
*/ */
static final int SINGLE_FOLIAGE_DATA_SIZE_BYTES = 3 * 4 + 2 * 4; static final int SINGLE_FOLIAGE_DATA_SIZE_BYTES = 3 * 4 + 2 * 4;
/**
* Offset to sample by
*/
static final float SAMPLE_OFFSET = 0.499f;
/** /**
* Vertex shader path * Vertex shader path
*/ */
@ -137,19 +142,41 @@ public class FoliageModel {
} }
FloatBuffer floatBufferView = buffer.asFloatBuffer(); FloatBuffer floatBufferView = buffer.asFloatBuffer();
int drawCount = 0; int drawCount = 0;
Vector3i currWorldPos = new Vector3i();
Vector3i currVoxelPos = new Vector3i(voxelPos);
Vector3d currRealPos = new Vector3d();
for(int x = 0; x < scale; x++){ for(int x = 0; x < scale; x++){
for(int y = 0; y < scale; y++){ for(int z = 0; z < scale; z++){
for(int z = 0; z < scale; z++){ for(int y = 0; y < scale; y++){
ChunkData data = Globals.clientTerrainManager.getChunkDataAtWorldPoint(worldPos,ChunkData.NO_STRIDE); currVoxelPos.set(voxelPos).add(x,y,z);
if(data == null){ currWorldPos.set(worldPos).add(
x / ServerTerrainChunk.CHUNK_DIMENSION,
y / ServerTerrainChunk.CHUNK_DIMENSION,
z / ServerTerrainChunk.CHUNK_DIMENSION
);
currRealPos.set(
currVoxelPos.x + currWorldPos.x * ServerTerrainChunk.CHUNK_PLACEMENT_OFFSET,
currVoxelPos.y + currWorldPos.y * ServerTerrainChunk.CHUNK_PLACEMENT_OFFSET,
currVoxelPos.z + currWorldPos.z * ServerTerrainChunk.CHUNK_PLACEMENT_OFFSET
);
ChunkData data = Globals.clientTerrainManager.getChunkDataAtWorldPoint(currWorldPos,ChunkData.NO_STRIDE);
List<String> currentList = Globals.gameConfigCurrent.getVoxelData().getTypeFromId(data.getType(currVoxelPos)).getAmbientFoliage();
if(currentList == null){
continue; continue;
} }
drawCount = drawCount + FoliageModel.insertBlades( if(data.getType(currVoxelPos.x,currVoxelPos.y+1,currVoxelPos.z) != AIR_VOXEL_ID){
realPos, voxelPos, continue;
}
int numGenerated = FoliageModel.insertBlades(
currWorldPos, currRealPos, currVoxelPos,
scale, placementRandomizer, scale, placementRandomizer,
x, y, z, x, y, z,
floatBufferView, data floatBufferView, data
); );
drawCount = drawCount + numGenerated;
// if(numGenerated > 0){
// break;
// }
} }
} }
} }
@ -187,144 +214,137 @@ public class FoliageModel {
* @return the number of blades of grass added * @return the number of blades of grass added
*/ */
protected static int insertBlades( protected static int insertBlades(
Vector3d realPos, Vector3i voxelPos, Vector3i worldPos, Vector3d realPos, Vector3i voxelPos,
int scale, Random placementRandomizer, int scale, Random placementRandomizer,
int vX, int vY, int vZ, int vX, int vY, int vZ,
FloatBuffer floatBufferView, ChunkData chunkData FloatBuffer floatBufferView, ChunkData chunkData
){ ){
int rVal = 0; int rVal = 0;
//get positions offset //construct simple grid to place foliage on
Vector3d voxelRealPos = new Vector3d(realPos).add(vX,vY,vZ); Vector3d sample_00 = Globals.clientSceneWrapper.getCollisionEngine().rayCastPosition(new Vector3d(realPos).add(-SAMPLE_OFFSET,SAMPLE_START_HEIGHT,-SAMPLE_OFFSET), new Vector3d(0,-1,0), RAY_LENGTH);
Vector3i currVoxelPos = new Vector3i(voxelPos).add(vX,vY,vZ); Vector3d sample_01 = Globals.clientSceneWrapper.getCollisionEngine().rayCastPosition(new Vector3d(realPos).add(-SAMPLE_OFFSET,SAMPLE_START_HEIGHT, 0), new Vector3d(0,-1,0), RAY_LENGTH);
Vector3d sample_02 = Globals.clientSceneWrapper.getCollisionEngine().rayCastPosition(new Vector3d(realPos).add(-SAMPLE_OFFSET,SAMPLE_START_HEIGHT, SAMPLE_OFFSET), new Vector3d(0,-1,0), RAY_LENGTH);
Vector3d sample_10 = Globals.clientSceneWrapper.getCollisionEngine().rayCastPosition(new Vector3d(realPos).add( 0,SAMPLE_START_HEIGHT,-SAMPLE_OFFSET), new Vector3d(0,-1,0), RAY_LENGTH);
Vector3d sample_11 = Globals.clientSceneWrapper.getCollisionEngine().rayCastPosition(new Vector3d(realPos).add( 0,SAMPLE_START_HEIGHT, 0), new Vector3d(0,-1,0), RAY_LENGTH);
Vector3d sample_12 = Globals.clientSceneWrapper.getCollisionEngine().rayCastPosition(new Vector3d(realPos).add( 0,SAMPLE_START_HEIGHT, SAMPLE_OFFSET), new Vector3d(0,-1,0), RAY_LENGTH);
Vector3d sample_20 = Globals.clientSceneWrapper.getCollisionEngine().rayCastPosition(new Vector3d(realPos).add( SAMPLE_OFFSET,SAMPLE_START_HEIGHT,-SAMPLE_OFFSET), new Vector3d(0,-1,0), RAY_LENGTH);
Vector3d sample_21 = Globals.clientSceneWrapper.getCollisionEngine().rayCastPosition(new Vector3d(realPos).add( SAMPLE_OFFSET,SAMPLE_START_HEIGHT, 0), new Vector3d(0,-1,0), RAY_LENGTH);
Vector3d sample_22 = Globals.clientSceneWrapper.getCollisionEngine().rayCastPosition(new Vector3d(realPos).add( SAMPLE_OFFSET,SAMPLE_START_HEIGHT, SAMPLE_OFFSET), new Vector3d(0,-1,0), RAY_LENGTH);
//get the heights of each sample
float height_11 = (float)(sample_11 != null ? sample_11.y : 0);
float height_00 = (float)(sample_00 != null ? sample_00.y : height_11);
float height_01 = (float)(sample_01 != null ? sample_01.y : height_11);
float height_02 = (float)(sample_02 != null ? sample_02.y : height_11);
float height_10 = (float)(sample_10 != null ? sample_10.y : height_11);
float height_12 = (float)(sample_12 != null ? sample_12.y : height_11);
float height_20 = (float)(sample_20 != null ? sample_20.y : height_11);
float height_21 = (float)(sample_21 != null ? sample_21.y : height_11);
float height_22 = (float)(sample_22 != null ? sample_22.y : height_11);
//each height is in real world coordinates that are absolute
//when rendering, there's already a y offset for the center of the field of grass (based on the model matrix)
//so when offseting the position of the blade of grass RELATIVE to the overall instance being drawn, need to subtract the real world coordinates of the overall instance
//in other words realPos SPECIFICALLY for the y dimension, for x and z you don't need to worry about it
//check that the current voxel even supports foliage //if we don't find data for the center sample, can't place grass so don't create entity
boolean shouldGenerate = false; if(sample_11 != null){
List<String> foliageTypesSupported = null; //generate positions to place
if(chunkData != null && currVoxelPos.y + 1 < ServerTerrainChunk.CHUNK_DIMENSION){ for(int x = 0; x < TARGET_FOLIAGE_SPACING; x=x+scale){
foliageTypesSupported = Globals.gameConfigCurrent.getVoxelData().getTypeFromId(chunkData.getType(currVoxelPos)).getAmbientFoliage(); for(int z = 0; z < TARGET_FOLIAGE_SPACING; z=z+scale){
boolean airAbove = chunkData.getType(currVoxelPos.x,currVoxelPos.y+1,currVoxelPos.z) == AIR_VOXEL_ID; //get position to place
if(foliageTypesSupported != null && airAbove){ double rand1 = placementRandomizer.nextDouble();
shouldGenerate = true; double rand2 = placementRandomizer.nextDouble();
} double relativePositionOnGridX = x / (1.0 * TARGET_FOLIAGE_SPACING) + rand1 / TARGET_FOLIAGE_SPACING;
} double relativePositionOnGridZ = z / (1.0 * TARGET_FOLIAGE_SPACING) + rand2 / TARGET_FOLIAGE_SPACING;
if(shouldGenerate){ double offsetX = relativePositionOnGridX - 0.5;
//construct simple grid to place foliage on double offsetZ = relativePositionOnGridZ - 0.5;
Vector3d sample_00 = Globals.clientSceneWrapper.getCollisionEngine().rayCastPosition(new Vector3d(voxelRealPos).add(-0.5,SAMPLE_START_HEIGHT,-0.5), new Vector3d(0,-1,0), RAY_LENGTH); //determine quadrant we're placing in
Vector3d sample_01 = Globals.clientSceneWrapper.getCollisionEngine().rayCastPosition(new Vector3d(voxelRealPos).add(-0.5,SAMPLE_START_HEIGHT, 0), new Vector3d(0,-1,0), RAY_LENGTH); double offsetY = 0;
Vector3d sample_02 = Globals.clientSceneWrapper.getCollisionEngine().rayCastPosition(new Vector3d(voxelRealPos).add(-0.5,SAMPLE_START_HEIGHT, 0.5), new Vector3d(0,-1,0), RAY_LENGTH); boolean addBlade = false;
Vector3d sample_10 = Globals.clientSceneWrapper.getCollisionEngine().rayCastPosition(new Vector3d(voxelRealPos).add( 0,SAMPLE_START_HEIGHT,-0.5), new Vector3d(0,-1,0), RAY_LENGTH); if(relativePositionOnGridX >=0.5){
Vector3d sample_11 = Globals.clientSceneWrapper.getCollisionEngine().rayCastPosition(new Vector3d(voxelRealPos).add( 0,SAMPLE_START_HEIGHT, 0), new Vector3d(0,-1,0), RAY_LENGTH); if(relativePositionOnGridZ >= 0.5){
Vector3d sample_12 = Globals.clientSceneWrapper.getCollisionEngine().rayCastPosition(new Vector3d(voxelRealPos).add( 0,SAMPLE_START_HEIGHT, 0.5), new Vector3d(0,-1,0), RAY_LENGTH); relativePositionOnGridX = relativePositionOnGridX - 0.5;
Vector3d sample_20 = Globals.clientSceneWrapper.getCollisionEngine().rayCastPosition(new Vector3d(voxelRealPos).add( 0.5,SAMPLE_START_HEIGHT,-0.5), new Vector3d(0,-1,0), RAY_LENGTH); relativePositionOnGridZ = relativePositionOnGridZ - 0.5;
Vector3d sample_21 = Globals.clientSceneWrapper.getCollisionEngine().rayCastPosition(new Vector3d(voxelRealPos).add( 0.5,SAMPLE_START_HEIGHT, 0), new Vector3d(0,-1,0), RAY_LENGTH); relativePositionOnGridX /= 0.5;
Vector3d sample_22 = Globals.clientSceneWrapper.getCollisionEngine().rayCastPosition(new Vector3d(voxelRealPos).add( 0.5,SAMPLE_START_HEIGHT, 0.5), new Vector3d(0,-1,0), RAY_LENGTH); relativePositionOnGridZ /= 0.5;
//get the heights of each sample // System.out.println(relativePositionOnGridX + " " + relativePositionOnGridZ);
float height_11 = (float)(sample_11 != null ? sample_11.y : 0); //if we have heights for all four surrounding spots, interpolate for y value
float height_00 = (float)(sample_00 != null ? sample_00.y : height_11); if(sample_11 != null && sample_12 != null && sample_21 != null && sample_22 != null){
float height_01 = (float)(sample_01 != null ? sample_01.y : height_11); offsetY =
float height_02 = (float)(sample_02 != null ? sample_02.y : height_11); height_11 * (1-relativePositionOnGridX) * (1-relativePositionOnGridZ) +
float height_10 = (float)(sample_10 != null ? sample_10.y : height_11); height_12 * (1-relativePositionOnGridX) * ( relativePositionOnGridZ) +
float height_12 = (float)(sample_12 != null ? sample_12.y : height_11); height_21 * ( relativePositionOnGridX) * (1-relativePositionOnGridZ) +
float height_20 = (float)(sample_20 != null ? sample_20.y : height_11); height_22 * ( relativePositionOnGridX) * ( relativePositionOnGridZ);
float height_21 = (float)(sample_21 != null ? sample_21.y : height_11); addBlade = true;
float height_22 = (float)(sample_22 != null ? sample_22.y : height_11);
//each height is in real world coordinates that are absolute
//when rendering, there's already a y offset for the center of the field of grass (based on the model matrix)
//so when offseting the position of the blade of grass RELATIVE to the overall instance being drawn, need to subtract the real world coordinates of the overall instance
//in other words realPos SPECIFICALLY for the y dimension, for x and z you don't need to worry about it
//if we don't find data for the center sample, can't place grass so don't create entity
if(sample_11 != null){
//generate positions to place
for(int x = 0; x < TARGET_FOLIAGE_SPACING; x=x+scale){
for(int z = 0; z < TARGET_FOLIAGE_SPACING; z=z+scale){
//get position to place
double rand1 = placementRandomizer.nextDouble();
double rand2 = placementRandomizer.nextDouble();
double relativePositionOnGridX = x / (1.0 * TARGET_FOLIAGE_SPACING) + rand1 / TARGET_FOLIAGE_SPACING;
double relativePositionOnGridZ = z / (1.0 * TARGET_FOLIAGE_SPACING) + rand2 / TARGET_FOLIAGE_SPACING;
double offsetX = relativePositionOnGridX - 0.5;
double offsetZ = relativePositionOnGridZ - 0.5;
//determine quadrant we're placing in
double offsetY = 0;
boolean addBlade = false;
if(relativePositionOnGridX >=0.5){
if(relativePositionOnGridZ >= 0.5){
relativePositionOnGridX = relativePositionOnGridX - 0.5;
relativePositionOnGridZ = relativePositionOnGridZ - 0.5;
relativePositionOnGridX /= 0.5;
relativePositionOnGridZ /= 0.5;
// System.out.println(relativePositionOnGridX + " " + relativePositionOnGridZ);
//if we have heights for all four surrounding spots, interpolate for y value
if(sample_11 != null && sample_12 != null && sample_21 != null && sample_22 != null){
offsetY =
height_11 * (1-relativePositionOnGridX) * (1-relativePositionOnGridZ) +
height_12 * (1-relativePositionOnGridX) * ( relativePositionOnGridZ) +
height_21 * ( relativePositionOnGridX) * (1-relativePositionOnGridZ) +
height_22 * ( relativePositionOnGridX) * ( relativePositionOnGridZ);
addBlade = true;
}
} else {
relativePositionOnGridX = relativePositionOnGridX - 0.5;
relativePositionOnGridX /= 0.5;
relativePositionOnGridZ /= 0.5;
//if we have heights for all four surrounding spots, interpolate for y value
if(sample_10 != null && sample_11 != null && sample_20 != null && sample_21 != null){
offsetY =
height_10 * (1-relativePositionOnGridX) * (1-relativePositionOnGridZ) +
height_11 * (1-relativePositionOnGridX) * ( relativePositionOnGridZ) +
height_20 * ( relativePositionOnGridX) * (1-relativePositionOnGridZ) +
height_21 * ( relativePositionOnGridX) * ( relativePositionOnGridZ);
addBlade = true;
}
} }
} else { } else {
if(relativePositionOnGridZ >= 0.5){ relativePositionOnGridX = relativePositionOnGridX - 0.5;
relativePositionOnGridZ = relativePositionOnGridZ - 0.5; relativePositionOnGridX /= 0.5;
relativePositionOnGridX /= 0.5; relativePositionOnGridZ /= 0.5;
relativePositionOnGridZ /= 0.5; //if we have heights for all four surrounding spots, interpolate for y value
//if we have heights for all four surrounding spots, interpolate for y value if(sample_10 != null && sample_11 != null && sample_20 != null && sample_21 != null){
if(sample_01 != null && sample_02 != null && sample_11 != null && sample_12 != null){ offsetY =
offsetY = height_10 * (1-relativePositionOnGridX) * (1-relativePositionOnGridZ) +
height_01 * (1-relativePositionOnGridX) * (1-relativePositionOnGridZ) + height_11 * (1-relativePositionOnGridX) * ( relativePositionOnGridZ) +
height_02 * (1-relativePositionOnGridX) * ( relativePositionOnGridZ) + height_20 * ( relativePositionOnGridX) * (1-relativePositionOnGridZ) +
height_11 * ( relativePositionOnGridX) * (1-relativePositionOnGridZ) + height_21 * ( relativePositionOnGridX) * ( relativePositionOnGridZ);
height_12 * ( relativePositionOnGridX) * ( relativePositionOnGridZ); addBlade = true;
addBlade = true;
}
} else {
relativePositionOnGridX /= 0.5;
relativePositionOnGridZ /= 0.5;
//if we have heights for all four surrounding spots, interpolate for y value
if(sample_00 != null && sample_01 != null && sample_10 != null && sample_11 != null){
offsetY =
height_00 * (1-relativePositionOnGridX) * (1-relativePositionOnGridZ) +
height_01 * (1-relativePositionOnGridX) * ( relativePositionOnGridZ) +
height_10 * ( relativePositionOnGridX) * (1-relativePositionOnGridZ) +
height_11 * ( relativePositionOnGridX) * ( relativePositionOnGridZ);
addBlade = true;
}
} }
} }
if(addBlade){ } else {
//convert y to relative to chunk if(relativePositionOnGridZ >= 0.5){
offsetY = offsetY - realPos.y; relativePositionOnGridZ = relativePositionOnGridZ - 0.5;
double rotVar = placementRandomizer.nextDouble() * Math.PI * 2; relativePositionOnGridX /= 0.5;
double rotVar2 = placementRandomizer.nextDouble(); relativePositionOnGridZ /= 0.5;
if(floatBufferView.limit() >= floatBufferView.position() + SINGLE_FOLIAGE_DATA_SIZE_BYTES / 4){ //if we have heights for all four surrounding spots, interpolate for y value
floatBufferView.put((float)offsetX + vX); if(sample_01 != null && sample_02 != null && sample_11 != null && sample_12 != null){
floatBufferView.put((float)offsetY + vY); offsetY =
floatBufferView.put((float)offsetZ + vZ); height_01 * (1-relativePositionOnGridX) * (1-relativePositionOnGridZ) +
floatBufferView.put((float)rotVar); height_02 * (1-relativePositionOnGridX) * ( relativePositionOnGridZ) +
floatBufferView.put((float)rotVar2); height_11 * ( relativePositionOnGridX) * (1-relativePositionOnGridZ) +
rVal++; height_12 * ( relativePositionOnGridX) * ( relativePositionOnGridZ);
addBlade = true;
} }
} else {
relativePositionOnGridX /= 0.5;
relativePositionOnGridZ /= 0.5;
//if we have heights for all four surrounding spots, interpolate for y value
if(sample_00 != null && sample_01 != null && sample_10 != null && sample_11 != null){
offsetY =
height_00 * (1-relativePositionOnGridX) * (1-relativePositionOnGridZ) +
height_01 * (1-relativePositionOnGridX) * ( relativePositionOnGridZ) +
height_10 * ( relativePositionOnGridX) * (1-relativePositionOnGridZ) +
height_11 * ( relativePositionOnGridX) * ( relativePositionOnGridZ);
addBlade = true;
}
}
}
if(addBlade){
// if(realPos.y == 20 && sample_11 != null){
// System.out.println("asdf");
// }
//convert y to relative to chunk
offsetY = offsetY - realPos.y;
double rotVar = placementRandomizer.nextDouble() * Math.PI * 2;
double rotVar2 = placementRandomizer.nextDouble();
if(floatBufferView.limit() >= floatBufferView.position() + SINGLE_FOLIAGE_DATA_SIZE_BYTES / 4){
floatBufferView.put((float)offsetX + vX);
floatBufferView.put((float)offsetY + vY);
floatBufferView.put((float)offsetZ + vZ);
floatBufferView.put((float)rotVar);
floatBufferView.put((float)rotVar2);
rVal++;
} }
} }
} }
} }
} }
// else {
// String message = "Failed to collide with a chunk that definitely should already exist!\n";
// message = message + "sample pos: " + new Vector3d(realPos).add(0,SAMPLE_START_HEIGHT,0) + "\n";
// message = message + "generated physics: " + Globals.clientDrawCellManager.hasGeneratedPhysics(worldPos.x, worldPos.y, worldPos.z) + "\n";
// throw new Error(message);
// }
return rVal; return rVal;
} }