ServerBlockChunkDiskMap pooling

This commit is contained in:
austin 2025-05-25 17:01:31 -04:00
parent 9a223159e5
commit 90c27c0321
7 changed files with 220 additions and 112 deletions

View File

@ -1990,6 +1990,7 @@ Performance improvements
- More vector pool usage - More vector pool usage
- Model anim calculations no longer allocate new matrix4d's - Model anim calculations no longer allocate new matrix4d's
- Undo most object pooling - Undo most object pooling
- ServerBlockChunkDiskMap uses short pool
Increase human move speed Increase human move speed
LOD components re-attach physics LOD components re-attach physics
VectorPool->JomlPool VectorPool->JomlPool

View File

@ -478,7 +478,10 @@ public class Actor {
model.updateNodeTransform(boneRotators,staticMorph); model.updateNodeTransform(boneRotators,staticMorph);
for(Bone bone : model.getBones()){ for(Bone bone : model.getBones()){
//store position //store position
Vector4d result = new Matrix4d(bone.getFinalTransform()).transform(bone.getMOffset().invert().transform(new Vector4d(0,0,0,1))); Matrix4d betweenMat = new Matrix4d(bone.getMOffset()).invert();
Vector4d result = betweenMat.transform(new Vector4d(0,0,0,1));
betweenMat.set(bone.getFinalTransform());
result = betweenMat.transform(result);
this.bonePositionMap.put(bone.boneID,new Vector3d(result.x,result.y,result.z)); this.bonePositionMap.put(bone.boneID,new Vector3d(result.x,result.y,result.z));
//store rotation //store rotation
Quaterniond rotation = new Matrix4d(bone.getFinalTransform()).getNormalizedRotation(new Quaterniond()); Quaterniond rotation = new Matrix4d(bone.getFinalTransform()).getNormalizedRotation(new Quaterniond());
@ -664,7 +667,10 @@ public class Actor {
this.calculateNodeTransforms(model); this.calculateNodeTransforms(model);
Bone currentBone = model.getBoneMap().get(boneName); Bone currentBone = model.getBoneMap().get(boneName);
if(currentBone != null){ if(currentBone != null){
Vector4d result = new Matrix4d(currentBone.getFinalTransform()).transform(currentBone.getMOffset().invert().transform(new Vector4d(rVal.x,rVal.y,rVal.z,1))); Matrix4d betweenMat = new Matrix4d(currentBone.getMOffset()).invert();
Vector4d result = betweenMat.transform(new Vector4d(rVal.x,rVal.y,rVal.z,1));
betweenMat.set(currentBone.getFinalTransform());
result = betweenMat.transform(result);
rVal.x = (float)result.x; rVal.x = (float)result.x;
rVal.y = (float)result.y; rVal.y = (float)result.y;
rVal.z = (float)result.z; rVal.z = (float)result.z;
@ -718,7 +724,7 @@ public class Actor {
calculateNodeTransforms(model); calculateNodeTransforms(model);
Bone currentBone = model.getBoneMap().get(boneName); Bone currentBone = model.getBoneMap().get(boneName);
if(currentBone != null){ if(currentBone != null){
rVal = currentBone.getFinalTransform(); rVal.set(currentBone.getFinalTransform());
} else { } else {
throw new IllegalArgumentException("Trying to get rotation of bone that does not exist on model!"); throw new IllegalArgumentException("Trying to get rotation of bone that does not exist on model!");
} }

View File

@ -35,12 +35,12 @@ public class Bone {
/** /**
* the current deform value of the bone * the current deform value of the bone
*/ */
private Matrix4d deform; private Matrix4d deform = new Matrix4d();
/** /**
* the final transform that is used for drawing, data, etc * the final transform that is used for drawing, data, etc
*/ */
private Matrix4d finalTransform; private Matrix4d finalTransform = new Matrix4d();
/** /**
* the raw data for the bone * the raw data for the bone
@ -51,8 +51,6 @@ public class Bone {
* Cnostructor * Cnostructor
*/ */
public Bone(){ public Bone(){
deform = new Matrix4d();
finalTransform = new Matrix4d();
} }
/** /**
@ -60,8 +58,6 @@ public class Bone {
* @param raw_data The raw assimp data * @param raw_data The raw assimp data
*/ */
public Bone(AIBone raw_data){ public Bone(AIBone raw_data){
deform = new Matrix4d();
finalTransform = new Matrix4d();
boneID = raw_data.mName().dataString(); boneID = raw_data.mName().dataString();
mOffsetMatrix = electrosphere.util.Utilities.convertAIMatrixd(raw_data.mOffsetMatrix()); mOffsetMatrix = electrosphere.util.Utilities.convertAIMatrixd(raw_data.mOffsetMatrix());
numWeights = raw_data.mNumWeights(); numWeights = raw_data.mNumWeights();
@ -89,7 +85,7 @@ public class Bone {
* @return The offset matrix * @return The offset matrix
*/ */
public Matrix4d getMOffset(){ public Matrix4d getMOffset(){
return new Matrix4d(mOffsetMatrix); return mOffsetMatrix;
} }
/** /**
@ -97,7 +93,7 @@ public class Bone {
* @param mTransform the offset matrix * @param mTransform the offset matrix
*/ */
public void setMOffset(Matrix4d mOffset){ public void setMOffset(Matrix4d mOffset){
this.mOffsetMatrix = new Matrix4d(mOffset); this.mOffsetMatrix.set(mOffset);
} }
/** /**
@ -105,7 +101,7 @@ public class Bone {
* @return The deform matrix * @return The deform matrix
*/ */
public Matrix4d getDeform(){ public Matrix4d getDeform(){
return new Matrix4d(deform); return deform;
} }
/** /**
@ -113,7 +109,7 @@ public class Bone {
* @param deform The deform matrix * @param deform The deform matrix
*/ */
public void setDeform(Matrix4d deform){ public void setDeform(Matrix4d deform){
this.deform = new Matrix4d(deform); this.deform.set(deform);
} }
/** /**
@ -121,7 +117,7 @@ public class Bone {
* @return The final transform * @return The final transform
*/ */
public Matrix4d getFinalTransform(){ public Matrix4d getFinalTransform(){
return new Matrix4d(finalTransform); return finalTransform;
} }
/** /**
@ -129,7 +125,7 @@ public class Bone {
* @param finalTransform The final transform * @param finalTransform The final transform
*/ */
public void setFinalTransform(Matrix4d finalTransform){ public void setFinalTransform(Matrix4d finalTransform){
this.finalTransform = new Matrix4d(finalTransform); this.finalTransform.set(finalTransform);
} }
/** /**

View File

@ -60,6 +60,21 @@ public class Mesh {
*/ */
public static final int DEFAULT_TEXTURE_ATTRIB_INDEX = 4; public static final int DEFAULT_TEXTURE_ATTRIB_INDEX = 4;
/**
* Static matrix used for draw calls
*/
private static final Matrix4d drawMat4 = new Matrix4d();
/**
* Static vector used for draw calls
*/
private static final Vector3f drawVec3f = new Vector3f();
/**
* Static vector used for draw calls
*/
private static final Vector3i drawVec3i = new Vector3i();
/** /**
* The name of this mesh * The name of this mesh
*/ */
@ -415,6 +430,7 @@ public class Mesh {
} }
/** /**
* Draws the mesh * Draws the mesh
* @param renderPipelineState The state of the render pipeline * @param renderPipelineState The state of the render pipeline
@ -459,7 +475,7 @@ public class Mesh {
//set uniforms required //set uniforms required
openGLState.getActiveShader().setUniform(openGLState, "zNear", CameraEntityUtils.getNearClip(Globals.clientState.playerCamera)); openGLState.getActiveShader().setUniform(openGLState, "zNear", CameraEntityUtils.getNearClip(Globals.clientState.playerCamera));
openGLState.getActiveShader().setUniform(openGLState, "zFar", CameraEntityUtils.getFarClip(Globals.clientState.playerCamera)); openGLState.getActiveShader().setUniform(openGLState, "zFar", CameraEntityUtils.getFarClip(Globals.clientState.playerCamera));
openGLState.getActiveShader().setUniform(openGLState, "gridSize", new Vector3i(LightManager.LIGHT_CLUSTER_WIDTH_X,LightManager.LIGHT_CLUSTER_WIDTH_Y,LightManager.LIGHT_CLUSTER_WIDTH_Z)); openGLState.getActiveShader().setUniform(openGLState, "gridSize", drawVec3i.set(LightManager.LIGHT_CLUSTER_WIDTH_X,LightManager.LIGHT_CLUSTER_WIDTH_Y,LightManager.LIGHT_CLUSTER_WIDTH_Z));
openGLState.getActiveShader().setUniform(openGLState, "screenDimensions", openGLState.getViewport()); openGLState.getActiveShader().setUniform(openGLState, "screenDimensions", openGLState.getViewport());
} }
@ -527,6 +543,7 @@ public class Mesh {
boolean sentBones = false; boolean sentBones = false;
Globals.profiler.beginAggregateCpuSample("Bones"); Globals.profiler.beginAggregateCpuSample("Bones");
drawMat4.identity();
if(renderPipelineState.getUseBones()){ if(renderPipelineState.getUseBones()){
// //
//Handle bones //Handle bones
@ -542,7 +559,7 @@ public class Mesh {
Matrix4d currentMat = currentBone.getFinalTransform(); Matrix4d currentMat = currentBone.getFinalTransform();
openGLState.getActiveShader().setUniform(openGLState, currentUniform, currentMat); openGLState.getActiveShader().setUniform(openGLState, currentUniform, currentMat);
} else { } else {
openGLState.getActiveShader().setUniform(openGLState, currentUniform, new Matrix4d()); openGLState.getActiveShader().setUniform(openGLState, currentUniform, drawMat4);
} }
incrementer++; incrementer++;
} }
@ -552,7 +569,7 @@ public class Mesh {
if(!sentBones){ if(!sentBones){
for(int i = 0; i < 4; i++){ for(int i = 0; i < 4; i++){
String currentUniform = "bones[" + i + "]"; String currentUniform = "bones[" + i + "]";
openGLState.getActiveShader().setUniform(openGLState, currentUniform, new Matrix4d().identity()); openGLState.getActiveShader().setUniform(openGLState, currentUniform, drawMat4);
} }
} }
Globals.profiler.endCpuSample(); Globals.profiler.endCpuSample();
@ -564,8 +581,8 @@ public class Mesh {
try(MemoryStack stack = MemoryStack.stackPush()){ try(MemoryStack stack = MemoryStack.stackPush()){
openGLState.getActiveShader().setUniform(openGLState, "model", parent.getModelMatrix()); openGLState.getActiveShader().setUniform(openGLState, "model", parent.getModelMatrix());
openGLState.getActiveShader().setUniform(openGLState, "viewPos", CameraEntityUtils.getCameraEye(Globals.clientState.playerCamera)); openGLState.getActiveShader().setUniform(openGLState, "viewPos", CameraEntityUtils.getCameraEye(Globals.clientState.playerCamera));
Vector3f worldPos = new Vector3f((float)parent.getWorldPos().x,(float)parent.getWorldPos().y,(float)parent.getWorldPos().z); drawVec3f.set((float)parent.getWorldPos().x,(float)parent.getWorldPos().y,(float)parent.getWorldPos().z);
openGLState.getActiveShader().setUniform(openGLState, "modelWorldPos", worldPos); openGLState.getActiveShader().setUniform(openGLState, "modelWorldPos", drawVec3f);
openGLState.glBindBufferBase(StandardUniformManager.STANDARD_UNIFORM_BUFFER_BIND_POINT, Globals.renderingEngine.getStandardUniformManager().getStandardUnifomSSBO()); openGLState.glBindBufferBase(StandardUniformManager.STANDARD_UNIFORM_BUFFER_BIND_POINT, Globals.renderingEngine.getStandardUniformManager().getStandardUnifomSSBO());
} }
Globals.renderingEngine.checkError(); Globals.renderingEngine.checkError();

View File

@ -11,7 +11,6 @@ import org.joml.Vector3f;
import org.joml.Vector3i; import org.joml.Vector3i;
import org.joml.Vector4f; import org.joml.Vector4f;
import org.lwjgl.opengl.GL40; import org.lwjgl.opengl.GL40;
import org.lwjgl.system.MemoryStack;
import electrosphere.engine.Globals; import electrosphere.engine.Globals;
import electrosphere.renderer.OpenGLState; import electrosphere.renderer.OpenGLState;
@ -21,6 +20,41 @@ import electrosphere.renderer.OpenGLState;
*/ */
public class ShaderUtils { public class ShaderUtils {
/**
* Private float array for setting uniforms
*/
private static final float[] float16Arr = new float[16];
/**
* Private float array for setting uniforms
*/
private static final float[] float4Arr = new float[4];
/**
* Private float array for setting uniforms
*/
private static final float[] float3Arr = new float[3];
/**
* Private double array for setting uniforms
*/
private static final double[] double3Arr = new double[3];
/**
* Private double array for setting uniforms
*/
private static final int[] int3Arr = new int[3];
/**
* Private double array for setting uniforms
*/
private static final double[] double2Arr = new double[2];
/**
* Private double array for setting uniforms
*/
private static final int[] int2Arr = new int[2];
/** /**
* Sets the value of a uniform on this shader * Sets the value of a uniform on this shader
* @param uniformLocation the uniform location * @param uniformLocation the uniform location
@ -32,71 +66,119 @@ public class ShaderUtils {
!uniformMap.containsKey(uniformLocation) || !uniformMap.containsKey(uniformLocation) ||
!uniformMap.get(uniformLocation).equals(value) !uniformMap.get(uniformLocation).equals(value)
){ ){
try(MemoryStack stack = MemoryStack.stackPush()){
// //
//matrix4f //matrix4f
if(value instanceof Matrix4f){ if(value instanceof Matrix4f){
Matrix4f currentUniform = (Matrix4f)value; Matrix4f currentUniform = (Matrix4f)value;
GL40.glUniformMatrix4fv(uniformLocation, false, currentUniform.get(stack.mallocFloat(16))); GL40.glUniformMatrix4fv(uniformLocation, false, currentUniform.get(float16Arr));
Globals.renderingEngine.checkError(); Globals.renderingEngine.checkError();
if(uniformMap.containsKey(uniformLocation)){
((Matrix4f)uniformMap.get(uniformLocation)).set(currentUniform);
} else {
uniformMap.put(uniformLocation,new Matrix4f(currentUniform)); //create new matrix4f to break pointer-matching with equals on cache check uniformMap.put(uniformLocation,new Matrix4f(currentUniform)); //create new matrix4f to break pointer-matching with equals on cache check
}
// //
//matrix4d //matrix4d
} else if(value instanceof Matrix4d){ } else if(value instanceof Matrix4d){
Matrix4d currentUniform = (Matrix4d)value; Matrix4d currentUniform = (Matrix4d)value;
GL40.glUniformMatrix4fv(uniformLocation, false, currentUniform.get(stack.mallocFloat(16))); GL40.glUniformMatrix4fv(uniformLocation, false, currentUniform.get(float16Arr));
Globals.renderingEngine.checkError(); Globals.renderingEngine.checkError();
if(uniformMap.containsKey(uniformLocation)){
((Matrix4d)uniformMap.get(uniformLocation)).set(currentUniform);
} else {
uniformMap.put(uniformLocation,new Matrix4d(currentUniform)); //create new matrix4f to break pointer-matching with equals on cache check uniformMap.put(uniformLocation,new Matrix4d(currentUniform)); //create new matrix4f to break pointer-matching with equals on cache check
}
// //
//vector4f //vector4f
} else if(value instanceof Vector4f){ } else if(value instanceof Vector4f){
Vector4f currentUniform = (Vector4f)value; Vector4f currentUniform = (Vector4f)value;
GL40.glUniform4fv(uniformLocation, currentUniform.get(stack.mallocFloat(4))); float4Arr[0] = currentUniform.x;
float4Arr[1] = currentUniform.y;
float4Arr[2] = currentUniform.z;
float4Arr[3] = currentUniform.w;
GL40.glUniform4fv(uniformLocation, float4Arr);
Globals.renderingEngine.checkError(); Globals.renderingEngine.checkError();
if(uniformMap.containsKey(uniformLocation)){
((Vector4f)uniformMap.get(uniformLocation)).set(currentUniform);
} else {
uniformMap.put(uniformLocation,new Vector4f(currentUniform)); //create new vector3f to break pointer-matching with equals on cache check uniformMap.put(uniformLocation,new Vector4f(currentUniform)); //create new vector3f to break pointer-matching with equals on cache check
}
// //
//vector3d //vector3d
} else if(value instanceof Vector3f){ } else if(value instanceof Vector3f){
Vector3f currentUniform = (Vector3f)value; Vector3f currentUniform = (Vector3f)value;
GL40.glUniform3fv(uniformLocation, currentUniform.get(stack.mallocFloat(3))); float3Arr[0] = currentUniform.x;
float3Arr[1] = currentUniform.y;
float3Arr[2] = currentUniform.z;
GL40.glUniform3fv(uniformLocation, float3Arr);
Globals.renderingEngine.checkError(); Globals.renderingEngine.checkError();
if(uniformMap.containsKey(uniformLocation)){
((Vector3f)uniformMap.get(uniformLocation)).set(currentUniform);
} else {
uniformMap.put(uniformLocation,new Vector3f(currentUniform)); //create new vector3f to break pointer-matching with equals on cache check uniformMap.put(uniformLocation,new Vector3f(currentUniform)); //create new vector3f to break pointer-matching with equals on cache check
}
// //
//vector3d //vector3d
} else if(value instanceof Vector3d){ } else if(value instanceof Vector3d){
Vector3d currentUniform = (Vector3d)value; Vector3d currentUniform = (Vector3d)value;
GL40.glUniform3dv(uniformLocation, currentUniform.get(stack.mallocDouble(3))); double3Arr[0] = currentUniform.x;
double3Arr[1] = currentUniform.y;
double3Arr[2] = currentUniform.z;
GL40.glUniform3dv(uniformLocation, double3Arr);
Globals.renderingEngine.checkError(); Globals.renderingEngine.checkError();
if(uniformMap.containsKey(uniformLocation)){
((Vector3d)uniformMap.get(uniformLocation)).set(currentUniform);
} else {
uniformMap.put(uniformLocation,new Vector3d(currentUniform)); //create new vector3d to break pointer-matching with equals on cache check uniformMap.put(uniformLocation,new Vector3d(currentUniform)); //create new vector3d to break pointer-matching with equals on cache check
}
// //
//vector2d //vector2d
} else if(value instanceof Vector2d){ } else if(value instanceof Vector2d){
Vector2d currentUniform = (Vector2d)value; Vector2d currentUniform = (Vector2d)value;
GL40.glUniform2dv(uniformLocation, currentUniform.get(stack.mallocDouble(2))); double2Arr[0] = currentUniform.x;
double2Arr[1] = currentUniform.y;
GL40.glUniform2dv(uniformLocation, double2Arr);
Globals.renderingEngine.checkError(); Globals.renderingEngine.checkError();
if(uniformMap.containsKey(uniformLocation)){
((Vector2d)uniformMap.get(uniformLocation)).set(currentUniform);
} else {
uniformMap.put(uniformLocation,new Vector2d(currentUniform)); //create new vector2d to break pointer-matching with equals on cache check uniformMap.put(uniformLocation,new Vector2d(currentUniform)); //create new vector2d to break pointer-matching with equals on cache check
}
// //
//Vector3i //Vector3i
} else if(value instanceof Vector3i){ } else if(value instanceof Vector3i){
Vector3i currentUniform = (Vector3i)value; Vector3i currentUniform = (Vector3i)value;
GL40.glUniform3uiv(uniformLocation, currentUniform.get(stack.mallocInt(3))); int3Arr[0] = currentUniform.x;
int3Arr[1] = currentUniform.y;
int3Arr[2] = currentUniform.z;
GL40.glUniform3uiv(uniformLocation, int3Arr);
Globals.renderingEngine.checkError(); Globals.renderingEngine.checkError();
if(uniformMap.containsKey(uniformLocation)){
((Vector3i)uniformMap.get(uniformLocation)).set(currentUniform);
} else {
uniformMap.put(uniformLocation,new Vector3i(currentUniform)); //create new vector2d to break pointer-matching with equals on cache check uniformMap.put(uniformLocation,new Vector3i(currentUniform)); //create new vector2d to break pointer-matching with equals on cache check
}
// //
//Vector2i //Vector2i
} else if(value instanceof Vector2i){ } else if(value instanceof Vector2i){
Vector2i currentUniform = (Vector2i)value; Vector2i currentUniform = (Vector2i)value;
GL40.glUniform2uiv(uniformLocation, currentUniform.get(stack.mallocInt(2))); int2Arr[0] = currentUniform.x;
int2Arr[1] = currentUniform.y;
GL40.glUniform2uiv(uniformLocation, int2Arr);
Globals.renderingEngine.checkError(); Globals.renderingEngine.checkError();
if(uniformMap.containsKey(uniformLocation)){
((Vector2i)uniformMap.get(uniformLocation)).set(currentUniform);
} else {
uniformMap.put(uniformLocation,new Vector2i(currentUniform)); //create new vector2d to break pointer-matching with equals on cache check uniformMap.put(uniformLocation,new Vector2i(currentUniform)); //create new vector2d to break pointer-matching with equals on cache check
}
// //
//integer //integer
@ -124,6 +206,5 @@ public class ShaderUtils {
} }
} }
} }
}
} }

View File

@ -387,7 +387,10 @@ public class PoseActor {
model.updateNodeTransform(boneRotators,staticMorph); model.updateNodeTransform(boneRotators,staticMorph);
for(Bone bone : model.getBones()){ for(Bone bone : model.getBones()){
//store position //store position
Vector4d result = new Matrix4d(bone.getFinalTransform()).transform(bone.getMOffset().invert().transform(new Vector4d(0,0,0,1))); Matrix4d betweenMat = new Matrix4d(bone.getMOffset()).invert();
Vector4d result = betweenMat.transform(new Vector4d(0,0,0,1));
betweenMat.set(bone.getFinalTransform());
result = betweenMat.transform(result);
this.bonePositionMap.put(bone.boneID,new Vector3d(result.x,result.y,result.z)); this.bonePositionMap.put(bone.boneID,new Vector3d(result.x,result.y,result.z));
//store rotation //store rotation
Quaterniond rotation = new Matrix4d(bone.getFinalTransform()).getNormalizedRotation(new Quaterniond()); Quaterniond rotation = new Matrix4d(bone.getFinalTransform()).getNormalizedRotation(new Quaterniond());
@ -500,7 +503,10 @@ public class PoseActor {
calculateNodeTransforms(model); calculateNodeTransforms(model);
Bone currentBone = model.boneMap.get(boneName); Bone currentBone = model.boneMap.get(boneName);
if(currentBone != null){ if(currentBone != null){
Vector4d result = new Matrix4d(currentBone.getFinalTransform()).transform(currentBone.getMOffset().invert().transform(new Vector4d(rVal.x,rVal.y,rVal.z,1))); Matrix4d betweenMat = new Matrix4d(currentBone.getMOffset()).invert();
Vector4d result = betweenMat.transform(new Vector4d(rVal.x,rVal.y,rVal.z,1));
betweenMat.set(currentBone.getFinalTransform());
result = betweenMat.transform(result);
rVal.x = (float)result.x; rVal.x = (float)result.x;
rVal.y = (float)result.y; rVal.y = (float)result.y;
rVal.z = (float)result.z; rVal.z = (float)result.z;
@ -529,7 +535,7 @@ public class PoseActor {
calculateNodeTransforms(model); calculateNodeTransforms(model);
Bone currentBone = model.getBoneMap().get(boneName); Bone currentBone = model.getBoneMap().get(boneName);
if(currentBone != null){ if(currentBone != null){
rVal = currentBone.getFinalTransform(); rVal.set(currentBone.getFinalTransform());
} else { } else {
throw new IllegalArgumentException("Trying to get rotation of bone that does not exist on model!"); throw new IllegalArgumentException("Trying to get rotation of bone that does not exist on model!");
} }

View File

@ -13,6 +13,7 @@ import java.util.zip.InflaterOutputStream;
import electrosphere.client.block.BlockChunkData; import electrosphere.client.block.BlockChunkData;
import electrosphere.engine.Globals; import electrosphere.engine.Globals;
import electrosphere.logger.LoggerInterface; import electrosphere.logger.LoggerInterface;
import electrosphere.mem.BlockChunkPool;
import electrosphere.util.FileUtils; import electrosphere.util.FileUtils;
import electrosphere.util.annotation.Exclude; import electrosphere.util.annotation.Exclude;
import electrosphere.util.math.HashUtils; import electrosphere.util.math.HashUtils;
@ -160,8 +161,8 @@ public class ServerBlockChunkDiskMap {
//read a non-homogenous chunk //read a non-homogenous chunk
ShortBuffer shortView = buffer.asShortBuffer(); ShortBuffer shortView = buffer.asShortBuffer();
short[] type = new short[BlockChunkData.TOTAL_DATA_WIDTH]; short[] type = BlockChunkPool.getShort();
short[] metadata = new short[BlockChunkData.TOTAL_DATA_WIDTH]; short[] metadata = BlockChunkPool.getShort();
short firstType = -1; short firstType = -1;
boolean homogenous = true; boolean homogenous = true;
for(int i = 0; i < BlockChunkData.TOTAL_DATA_WIDTH; i++){ for(int i = 0; i < BlockChunkData.TOTAL_DATA_WIDTH; i++){