/*
*EERT = EERT enhanced rendering technology
*
*Copyright (C) [2008] [Robert "BuRnEr" Schadek]
*This program is free software; you can redistribute it and/or modify it under
*the terms of the GNU General Public License as published by the Free Software
*Foundation; either version 3 of the License,
*or (at your option) any later version.
*This program is distributed in the hope that it will be useful, but WITHOUT
*ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
*FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*You should have received a copy of the GNU General Public License along with
*this program; if not, see <http://www.gnu.org/licenses/>.
*/
package Types.Geometrie;
import Engine.Engine;
import Types.Illumination.PointLight;
import Util.Logic.Camera;
import Util.Logic.UHPT;
import java.io.IOException;
import javax.media.opengl.GL;
import Util.*;
import Util.Geometrie.VectorUtil;
import Util.Prelude.JObjParse;
import java.util.LinkedList;
import javax.media.opengl.glu.GLU;
public class Obj {
public int number;
public LinkedList<Vector[]> vec = null;
public LinkedList<Vector[]> nor = null;
public LinkedList<TexCoor[]> tex = null;
public LinkedList<Face[]> fac = null;
public LinkedList<ObjIns> objIns = null;
public String name;
public Vector origin; //Object origin
private float xR = 0.0f; //Object rotation
private float yR = 0.0f;
private float zR = 0.0f;
public float bR = 0.0f; //bounding Sphere radius
private Camera cam;
private GL gl;
public int[] facNum;
public int facesRendered;
public Engine engine;
public String[] textures;
private ETexture image[];
private int[] listHandles;
private int[] textureHandles;
ETexture texImage0;
ETexture texImage1;
ETexture texImage2;
ETexture texImage3;
ETexture texImage4;
ETexture texImage5;
//Shadow stuff below
public LinkedList<Face> cap;
public LinkedList<Edge> edgesToExtrude;
public Obj(Camera cam, String[] file, int number, GL gl, Engine engine) throws IOException {
this.image = new ETexture[6];
this.textures = new String[6];
this.engine = engine;
this.facNum = new int[6];
this.vec = new LinkedList<Vector[]>();
this.nor = new LinkedList<Vector[]>();
this.tex = new LinkedList<TexCoor[]>();
this.fac = new LinkedList<Face[]>();
this.cap = new LinkedList<Face>();
this.objIns = new LinkedList<ObjIns>();
this.gl = gl;
this.cam = cam;
this.origin = new Vector(0.0f, 0.0f, 0.0f);
this.number = number;
for (int i = 0; i < file.length; i++) {
JObjParse parse = new JObjParse(file[i]);
this.vec.add(parse.getVector());
this.nor.add(parse.getNormal());
this.tex.add(parse.getTex());
this.fac.add(parse.getFace());
}
makeBoundingSphere();
//makeFaceNormals();
this.facNum[0] = this.fac.get(0).length;
this.facNum[1] = this.fac.get(1).length;
this.facNum[2] = this.fac.get(2).length;
this.facNum[3] = this.fac.get(3).length;
this.facNum[4] = this.fac.get(4).length;
this.facNum[5] = this.fac.get(5).length;
this.listHandles = new int[6];
this.listHandles[0] = gl.glGenLists(1);
this.listHandles[1] = gl.glGenLists(1);
this.listHandles[2] = gl.glGenLists(1);
this.listHandles[3] = gl.glGenLists(1);
this.listHandles[4] = gl.glGenLists(1);
this.listHandles[5] = gl.glGenLists(1);
this.textures = this.engine.textures;
this.textureHandles = new int[6];
gl.glGenTextures(6, this.textureHandles, 0);
this.texImage0 = new ETexture(this.textures[0]);
gl.glBindTexture(GL.GL_TEXTURE_2D, this.textureHandles[0]);
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP);
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP);
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER,
GL.GL_NEAREST);
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER,
GL.GL_NEAREST);
gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGBA, this.texImage0.getWidth(), this.texImage0.getHeight(),
0, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, this.texImage0.getBuffer());
this.texImage1 = new ETexture(this.textures[1]);
gl.glBindTexture(GL.GL_TEXTURE_2D, this.textureHandles[1]);
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP);
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP);
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER,
GL.GL_NEAREST);
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER,
GL.GL_NEAREST);
gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGBA, this.texImage1.getWidth(), this.texImage1.getHeight(),
0, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, this.texImage1.getBuffer());
this.texImage2 = new ETexture(this.textures[2]);
gl.glBindTexture(GL.GL_TEXTURE_2D, this.textureHandles[2]);
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP);
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP);
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER,
GL.GL_NEAREST);
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER,
GL.GL_NEAREST);
gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGBA, this.texImage2.getWidth(), this.texImage2.getHeight(),
0, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, this.texImage2.getBuffer());
this.texImage3 = new ETexture(this.textures[3]);
gl.glBindTexture(GL.GL_TEXTURE_2D, this.textureHandles[3]);
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP);
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP);
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER,
GL.GL_NEAREST);
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER,
GL.GL_NEAREST);
gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGBA, this.texImage3.getWidth(), this.texImage3.getHeight(),
0, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, this.texImage3.getBuffer());
this.texImage4 = new ETexture(this.textures[4]);
gl.glBindTexture(GL.GL_TEXTURE_2D, this.textureHandles[4]);
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP);
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP);
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER,
GL.GL_NEAREST);
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER,
GL.GL_NEAREST);
gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGBA, this.texImage4.getWidth(), this.texImage4.getHeight(),
0, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, this.texImage4.getBuffer());
this.texImage5 = new ETexture(this.textures[5]);
gl.glBindTexture(GL.GL_TEXTURE_2D, this.textureHandles[5]);
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP);
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP);
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER,
GL.GL_NEAREST);
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER,
GL.GL_NEAREST);
gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGBA, this.texImage5.getWidth(), this.texImage5.getHeight(),
0, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, this.texImage5.getBuffer());
gl.glEnable(GL.GL_TEXTURE_2D);
//Build the six display lists
for (int j = 0; j < this.fac.size(); j++) {
gl.glNewList(this.listHandles[j], GL.GL_COMPILE);
this.gl.glBegin(GL.GL_TRIANGLES);
//gl.glColor3f(1.0f, 1.0f, 1.0f);
for (int i = 0; i < this.fac.get(j).length - 1; i++) {
Face tmpFace = this.fac.get(j)[i];
if (tmpFace.vn1 != null) {
gl.glNormal3f(tmpFace.vn1.x, tmpFace.vn1.y, tmpFace.vn1.z);
} else {
System.out.println("vn1");
}
if (tmpFace.vt1 != null) {
gl.glTexCoord2f(tmpFace.vt1.s, tmpFace.vt1.t);
} else {
System.out.println("vt1");
}
gl.glVertex3f(tmpFace.v1.x, tmpFace.v1.y, tmpFace.v1.z);
if (tmpFace.vn2 != null) {
gl.glNormal3f(tmpFace.vn2.x, tmpFace.vn2.y, tmpFace.vn2.z);
} else {
System.out.println("vn2");
}
if (tmpFace.vt2 != null) {
gl.glTexCoord2f(tmpFace.vt2.s, tmpFace.vt2.t);
} else {
System.out.println("vt2");
}
gl.glVertex3f(tmpFace.v2.x, tmpFace.v2.y, tmpFace.v2.z);
if (tmpFace.vt3 != null) {
gl.glTexCoord2f(tmpFace.vt3.s, tmpFace.vt3.t);
} else {
System.out.println("vn3");
}
if (tmpFace.vn3 != null) {
gl.glNormal3f(tmpFace.vn3.x, tmpFace.vn3.y, tmpFace.vn3.z);
} else {
System.out.println("vt3");
}
gl.glVertex3f(tmpFace.v3.x, tmpFace.v3.y, tmpFace.v3.z);
}
this.gl.glEnd();
this.gl.glEndList();
}
}
public void conMove(float x, float y, float z) {
this.origin.x += x * UHPT.getETime() / 1000000000;
this.origin.y += y * UHPT.getETime() / 1000000000;
this.origin.z += z * UHPT.getETime() / 1000000000;
}
public void conRotate(float rX, float rY, float rZ) {
this.xR += rX * UHPT.getETime() / 1000000000;
this.yR += rY * UHPT.getETime() / 1000000000;
this.zR += rZ * UHPT.getETime() / 1000000000;
}
public void setPos(float x, float y, float z) {
this.origin.x = x;
this.origin.y = y;
this.origin.z = z;
}
public void setRot(float xR, float yR, float zR) {
this.xR = xR;
this.yR = yR;
this.zR = zR;
}
public void render(int number, float dis) {
//dis = (float) Math.abs(Math.sqrt(Math.pow(this.cam.loc.x - this.origin.x, 2) + Math.pow(this.cam.loc.y - this.origin.y, 2) + Math.pow(this.cam.loc.z - this.origin.z, 2)));
gl.glPushMatrix();
this.engine.eInfo.drawObj++;
//get ObjIns
ObjIns tmp = this.objIns.get(number);
//Translate to position
gl.glTranslatef(tmp.origin.x, tmp.origin.y, tmp.origin.z);
//Rotate
gl.glRotatef(tmp.rotation.x, 1.0f, 0.0f, 0.0f);
gl.glRotatef(tmp.rotation.y, 0.0f, 1.0f, 0.0f);
gl.glRotatef(tmp.rotation.z, 0.0f, 0.0f, 1.0f);
//Call the right list according
//to the distance from cam location
if (dis < 10.0f) {
gl.glBindTexture(GL.GL_TEXTURE_2D, this.textureHandles[0]);
gl.glCallList(this.listHandles[0]);
this.facesRendered += this.facNum[0];
} else if (dis < 20.0f) {
gl.glBindTexture(GL.GL_TEXTURE_2D, this.textureHandles[1]);
gl.glCallList(this.listHandles[1]);
this.facesRendered += this.facNum[1];
} else if (dis < 40.0f) {
gl.glBindTexture(GL.GL_TEXTURE_2D, this.textureHandles[2]);
gl.glCallList(this.listHandles[2]);
this.facesRendered += this.facNum[2];
} else if (dis < 60.0f) {
gl.glBindTexture(GL.GL_TEXTURE_2D, this.textureHandles[3]);
gl.glCallList(this.listHandles[3]);
this.facesRendered += this.facNum[3];
} else if (dis < 120.0f) {
gl.glBindTexture(GL.GL_TEXTURE_2D, this.textureHandles[4]);
gl.glCallList(this.listHandles[4]);
this.facesRendered += this.facNum[4];
} else {
gl.glBindTexture(GL.GL_TEXTURE_2D, this.textureHandles[5]);
gl.glCallList(this.listHandles[5]);
this.facesRendered += this.facNum[5];
}
gl.glPopMatrix();
}
/* public void renderShadow(int obNumb) {
//draw stuff
makeSilhouette();
drawShadowVolume(obNumb);
//clean up so next objIns finds anything clear
this.cap = new LinkedList<Face>();
}*/
private void makeFaceNormals() {
Face face;
for (int i = 0; i < 6; i++) {
int facCount = this.fac.get(i).length;
for (int j = 0; j < facCount; j++) {
face = this.fac.get(i)[j];
//Crossprodukt
face.faceNormal = new Vector(face.v2.y * face.v3.z - face.v2.z * face.v3.y,
face.v2.z * face.v3.x - face.v2.x * face.v3.z,
face.v1.x * face.v3.y - face.v2.y * face.v2.x);
//Normalize to later use acos
//to get angle between face and lightvec
//angle = acos(v1 dotProduct v2)
face.faceNormal.normalize();
}
}
}
/* public void findFacesFacingLight(float dis, int numberOfObjIns) {
//transform and rotate the
//according to the modelviewMatrix
gl.glPushMatrix();
//get ObjIns
ObjIns tmp = this.objIns.get(numberOfObjIns);
//Translate to position
gl.glTranslatef(tmp.origin.x, tmp.origin.y, tmp.origin.z);
//Rotate
gl.glRotatef(tmp.rotation.x, 1.0f, 0.0f, 0.0f);
gl.glRotatef(tmp.rotation.y, 0.0f, 1.0f, 0.0f);
gl.glRotatef(tmp.rotation.z, 0.0f, 0.0f, 1.0f);
//extract matrix
float[] mvMatrix = new float[16];
gl.glGetFloatv(GL.GL_MODELVIEW_MATRIX, mvMatrix, 0);
gl.glPopMatrix();
//make sphere coord
//need to make the rotation
//of the object to appear in the light
PointLight toLight = new PointLight(this.engine.lights.lights.get(0));
float[] inverseModel = VectorUtil.invertModelView(mvMatrix);
toLight.origin = VectorUtil.multWithGLMatrix(inverseModel, toLight.origin);
int res;
if (dis < 10.0f) {
res = 0;
} else if (dis < 20.0f) {
res = 1;
} else if (dis < 40.0f) {
res = 2;
} else if (dis < 60.0f) {
res = 3;
} else if (dis < 120.0f) {
res = 4;
} else {
res = 5;
}
Face[] forTest = this.fac.get(res);
for (Face toTest : forTest) {
if (0f < VectorUtil.dotProduct(toTest.faceNormal, toLight.origin) / this.origin.getLength() * toTest.faceNormal.getLength()) {
this.cap.add(toTest);
toTest.lit = true;
} else {
toTest.lit = false;
}
}
}*/
public void makeSilhouette() {
this.edgesToExtrude = new LinkedList<Edge>();
/* if a friend is not lit add the Edge to the
* list to be extruded*/
for (Face toTest : this.cap) {
//if(toTest.fr1 != null) {
if (!toTest.fr1.lit) {
this.edgesToExtrude.add(toTest.ed1);
}//}
//if(toTest.fr2 != null) {
if (!toTest.fr2.lit) {
this.edgesToExtrude.add(toTest.ed2);
}//}
//if(toTest.fr3 != null) {
if (!toTest.fr3.lit) {
this.edgesToExtrude.add(toTest.ed3);
}//}
}
}
private void makeBoundingSphere() {
float dis = 0f;
Vector[] points = this.vec.get(0);
for (Vector toTest : points) {
float newDis = (float) Math.sqrt(Math.pow(toTest.x - this.origin.x, 2) +
Math.pow(toTest.y - this.origin.y, 2) +
Math.pow(toTest.z - this.origin.z, 2));
if (newDis > dis) {
dis = newDis;
}
}
this.bR = dis;
}
/* private void drawShadowVolume(int number) {
this.gl.glPushMatrix();
ObjIns tmp = this.objIns.get(number);
//Translate to position
gl.glTranslatef(tmp.origin.x, tmp.origin.y, tmp.origin.z);
//Rotate
gl.glRotatef(tmp.rotation.x, 1.0f, 0.0f, 0.0f);
gl.glRotatef(tmp.rotation.y, 0.0f, 1.0f, 0.0f);
gl.glRotatef(tmp.rotation.z, 0.0f, 0.0f, 1.0f);
//Extrude the Silhouette
for (Edge extrude : this.edgesToExtrude) {
//make vertex who form
//quads of shadowcone
Vector lightEx1 = new Vector(extrude.x1.subR(this.engine.lights.lights.get(0).origin));
lightEx1.normalize();
lightEx1.mult(this.engine.lights.lights.get(0).radius);
Vector lightEx2 = new Vector(extrude.x2.subR(this.engine.lights.lights.get(0).origin));
lightEx2.normalize();
lightEx2.mult(this.engine.lights.lights.get(0).radius);
//Draw the quad
this.gl.glBegin(GL.GL_QUADS);
this.gl.glVertex3f(lightEx2.x, lightEx2.y, lightEx2.z);
this.gl.glVertex3f(lightEx1.x, lightEx1.y, lightEx1.z);
this.gl.glVertex3f(extrude.x1.x, extrude.x1.y, extrude.x1.z);
this.gl.glVertex3f(extrude.x2.x, extrude.x2.y, extrude.x2.z);
this.gl.glEnd();
}
//Draw cap
this.gl.glBegin(GL.GL_TRIANGLES);
for (Face capFace : this.cap) {
//draw frontcap
this.gl.glVertex3f(capFace.v1.x, capFace.v1.y, capFace.v1.z);
this.gl.glVertex3f(capFace.v2.x, capFace.v2.y, capFace.v2.z);
this.gl.glVertex3f(capFace.v3.x, capFace.v3.y, capFace.v3.z);
//make corresponding
//back face
Vector backCap1 = new Vector(capFace.v1.subR(this.engine.lights.lights.get(0).origin));
Vector backCap2 = new Vector(capFace.v2.subR(this.engine.lights.lights.get(0).origin));
Vector backCap3 = new Vector(capFace.v3.subR(this.engine.lights.lights.get(0).origin));
backCap1.normalize();
backCap2.normalize();
backCap3.normalize();
backCap1.mult(200f);
backCap2.mult(200f);
backCap3.mult(200f);
//draw backcap
this.gl.glVertex3f(backCap3.x, backCap3.y, backCap3.z);
this.gl.glVertex3f(backCap2.x, backCap2.y, backCap2.z);
this.gl.glVertex3f(backCap1.x, backCap1.y, backCap1.z);
}
this.gl.glEnd();
this.gl.glPopMatrix();
}*/
}