package detectiongame.dungen;
import engine.Entity;
import engine.Vec3f;
import engine.model.Material;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.ARBVertexArrayObject;
import org.lwjgl.opengl.ARBVertexBufferObject;
import static org.lwjgl.opengl.GL11.*;
import org.lwjgl.opengl.GL20;
import org.lwjgl.util.vector.Matrix4f;
import org.lwjgl.util.vector.Vector3f;
/**
*
* @author
* knasaari
*/
public class Chunk extends engine.model.ObjModel{
private int vertcount_fresh;
public boolean drawable, buildStatus;
private Vec3f center_draw, center_fresh;
private float[] bounds_draw, bounds_fresh;
private float[][] rotMatrix;
private Vec3f size;
float vertice[] = new float[8];
public Chunk(){
super(null);
center_draw = new Vec3f(0.0f,0.0f,0.0f);
center_fresh = new Vec3f(0.0f,0.0f,0.0f);
size = new Vec3f(0.0f,0.0f,0.0f);
bounds_fresh = new float[6];
bounds_draw = new float[6];
rotMatrix = new float[3][3];
VBOid = -1;
drawable = false;
buildStatus = true;
vertcount_fresh = 0;
texcoords_enabled = true;
normals_enabled = true;
}
public boolean getBuildStatus(){
return this.buildStatus;
}
public boolean getBufferStatus(){
if(this.VBO == null || this.VBO.position() == 0) {
return true;
}
else {
return false;
}
}
public Vec3f getCenter(){
return this.center_draw;
}
public void addEntityToChunk(Entity ent){
float rad,x,y,z;
float vertice[] = new float[8];
rad = (float)Math.toRadians(ent.getRot().y);
for(int entVBOindex=0; entVBOindex<ent.model.VBO.capacity(); entVBOindex=entVBOindex+8){
ent.model.VBO.get(vertice, 0, 8);
// X,Y,Z
x = (float)(vertice[0]*Math.cos(rad) - vertice[2]*Math.sin(rad))+ent.getPos().x;
y = vertice[1]+ent.getPos().y;
z = (float)(vertice[0]*Math.sin(rad) + vertice[2]*Math.cos(rad))+ent.getPos().z;
this.center_fresh.set(this.center_fresh.x+vertice[0]+ent.getPos().x, this.center_fresh.y+vertice[1]+ent.getPos().y, this.center_fresh.z+vertice[2]+ent.getPos().z);
if(this.vertcount_fresh != 0){
this.bounds_fresh[0] = Math.max(this.bounds_fresh[0], x);
this.bounds_fresh[1] = Math.max(this.bounds_fresh[1], y);
this.bounds_fresh[2] = Math.max(this.bounds_fresh[2], z);
this.bounds_fresh[3] = Math.min(this.bounds_fresh[3], x);
this.bounds_fresh[4] = Math.min(this.bounds_fresh[4], y);
this.bounds_fresh[5] = Math.min(this.bounds_fresh[5], z);
}
else{
this.bounds_fresh[0] = x;
this.bounds_fresh[1] = y;
this.bounds_fresh[2] = z;
this.bounds_fresh[3] = x;
this.bounds_fresh[4] = y;
this.bounds_fresh[5] = z;
}
this.VBO.put(x);
this.VBO.put(y);
this.VBO.put(z);
// U,V
this.VBO.put(vertice[3]);
this.VBO.put(vertice[4]);
// NX, NY, NZ
this.VBO.put((float)(vertice[5]*Math.cos(rad) - vertice[7]*Math.sin(rad)));
this.VBO.put(vertice[6]);
this.VBO.put((float)(vertice[5]*Math.sin(rad) + vertice[7]*Math.cos(rad)));
}
ent.model.VBO.position(0);
this.vertcount_fresh += ent.model.tri_vertcount;
}
public void createFloatBuffer(int size){
if(this.VBO != null){
this.VBO.clear();
// this.VBO = new Vector<>();
}
this.VBO = BufferUtils.createFloatBuffer(size);
this.buildStatus = false;
}
public void clearFloatBuffer(){
if(this.VBO != null){
this.VBO.clear();
}
this.buildStatus = true;
this.vertcount_fresh = 0;
}
public void reset(){
ARBVertexArrayObject.glDeleteVertexArrays(this.VAOid);
ARBVertexBufferObject.glDeleteBuffersARB(this.VBOid);
this.VAOid = -1;
this.VBOid = -1;
this.clearFloatBuffer();
this.drawable = false;
}
@Override
protected void bindBuffer(){
// Generate & bind VAO for attribs
this.VAOid = this.genVAOId();
ARBVertexArrayObject.glBindVertexArray(this.VAOid);
// Generate & bind VBO for vertices,texcoords,etc.
this.VBOid = this.genVBOId();
ARBVertexBufferObject.glBindBufferARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, this.VBOid);
// Set data in to VAO
int stride = (3 + 2 + 3) * 4;
int offset = 0;
GL20.glVertexAttribPointer(0, 3, GL_FLOAT, false, stride, offset);
offset = 3 * 4;
GL20.glVertexAttribPointer(1, 2, GL_FLOAT, false, stride, offset);
offset += 2*4;
GL20.glVertexAttribPointer(2, 3, GL_FLOAT, false, stride, offset);
// Set interleaved data in to VBO
ARBVertexBufferObject.glBufferDataARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, this.VBO, ARBVertexBufferObject.GL_STATIC_DRAW_ARB);
// Unbind VAO & VBO
ARBVertexArrayObject.glBindVertexArray(0);
ARBVertexBufferObject.glBindBufferARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, 0);
}
private void refreshBuffer(){
ARBVertexBufferObject.glBindBufferARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, this.VBOid);
ARBVertexBufferObject.glBufferDataARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, this.VBO, ARBVertexBufferObject.GL_STATIC_DRAW_ARB);
ARBVertexBufferObject.glBindBufferARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, 0);
}
public void swap(){
this.VBO.flip();
if(this.VBOid == -1){
this.bindBuffer();
}
else{
this.refreshBuffer();
}
this.center_draw.set(this.center_fresh.x/this.vertcount_fresh, this.center_fresh.y/this.vertcount_fresh, this.center_fresh.z/this.vertcount_fresh);
this.bounds_draw = this.bounds_fresh.clone();
this.bounds_fresh = new float[6];
/*
System.out.println(this.center_draw.x+","+this.center_draw.y+","+this.center_draw.z);
System.out.println(this.bounds_draw[0]+","+this.bounds_draw[1]+","+this.bounds_draw[2]);
System.out.println(this.bounds_draw[3]+","+this.bounds_draw[4]+","+this.bounds_draw[5]);
*/
this.size.set(
Math.abs(this.bounds_draw[0]-this.bounds_draw[3])*0.707f,
Math.abs(this.bounds_draw[1]-this.bounds_draw[4])*0.707f,
Math.abs(this.bounds_draw[2]-this.bounds_draw[5])*0.707f
);
this.tri_vertcount = this.vertcount_fresh;
this.drawable = true;
this.center_fresh.set(0f);
}
private void updateRotMatrix(){
double rad = Math.toRadians(45f);
this.rotMatrix[0][0] = (float)Math.cos(rad);
this.rotMatrix[0][1] = 0f;
this.rotMatrix[0][2] = (float)Math.sin(rad);
this.rotMatrix[1][0] = 0f;
this.rotMatrix[1][1] = 1f;
this.rotMatrix[1][2] = 0f;
this.rotMatrix[2][0] = this.rotMatrix[0][2];
this.rotMatrix[2][1] = 0;
this.rotMatrix[2][2] = this.rotMatrix[0][0];
}
public float getSphereRadius(){
return Math.max(this.size.x, Math.max(this.size.y, this.size.z));
}
public void draw(Material mat){
if(this.drawable == false) {
return;
}
this.draw_glsl(mat, this.getModelMatrix());
}
public Matrix4f getModelMatrix() {
Matrix4f mat4 = new Matrix4f();
mat4.setIdentity();
mat4.translate(new Vector3f(0,0,0));
mat4.scale(new Vector3f(1,1,1));
return mat4;
}
public void drawBoundingBox(){
this.updateRotMatrix();
//glDisable(GL_DEPTH_TEST);
glColor3f(1f, 0f, 0f);
glBegin(GL_LINE_STRIP);
glVertex3f(bounds_draw[0], bounds_draw[4], bounds_draw[2]);
glVertex3f(bounds_draw[0], bounds_draw[1], bounds_draw[2]);
glVertex3f(bounds_draw[0], bounds_draw[1], bounds_draw[5]);
glVertex3f(bounds_draw[0], bounds_draw[4], bounds_draw[5]);
glVertex3f(bounds_draw[0], bounds_draw[4], bounds_draw[2]);
glVertex3f(bounds_draw[3], bounds_draw[4], bounds_draw[2]);
glVertex3f(bounds_draw[3], bounds_draw[1], bounds_draw[2]);
glVertex3f(bounds_draw[0], bounds_draw[1], bounds_draw[2]);
glEnd();
glBegin(GL_LINE_STRIP);
glVertex3f(bounds_draw[3], bounds_draw[4], bounds_draw[5]);
glVertex3f(bounds_draw[3], bounds_draw[1], bounds_draw[5]);
glVertex3f(bounds_draw[0], bounds_draw[1], bounds_draw[5]);
glVertex3f(bounds_draw[0], bounds_draw[4], bounds_draw[5]);
glVertex3f(bounds_draw[3], bounds_draw[4], bounds_draw[5]);
glVertex3f(bounds_draw[3], bounds_draw[4], bounds_draw[2]);
glVertex3f(bounds_draw[3], bounds_draw[1], bounds_draw[2]);
glVertex3f(bounds_draw[3], bounds_draw[1], bounds_draw[5]);
glEnd();
float length = (float)Math.abs(Math.sqrt(this.size.x*this.size.x + this.size.y*this.size.y + this.size.z*this.size.z));
float crossSize = 10*((this.size.x+this.size.y+this.size.z)/3)/length;
glBegin(GL_LINES);
glColor3f(0f, 1f, 0f);
glVertex3f(this.center_draw.x-crossSize,this.center_draw.y,this.center_draw.z);
glVertex3f(this.center_draw.x+crossSize,this.center_draw.y,this.center_draw.z);
glColor3f(0f, 0f, 1f);
glVertex3f(this.center_draw.x,this.center_draw.y+crossSize,this.center_draw.z);
glVertex3f(this.center_draw.x,this.center_draw.y-crossSize,this.center_draw.z);
glColor3f(1f, 0f, 0f);
glVertex3f(this.center_draw.x,this.center_draw.y,this.center_draw.z+crossSize);
glVertex3f(this.center_draw.x,this.center_draw.y,this.center_draw.z-crossSize);
glEnd();
//glEnable(GL_DEPTH_TEST);
glColor3f(1f, 1f, 1f);
}
}