VisClient/org/hfbk/vis/visnode/VisObj.java

Go to the documentation of this file.
00001 package org.hfbk.vis.visnode;
00002 
00003 import java.io.BufferedReader;
00004 import java.io.IOException;
00005 import java.io.InputStreamReader;
00006 import java.net.URL;
00007 import java.util.ArrayList;
00008 import java.util.List;
00009 
00010 import org.dronus.gl.Convexiser;
00011 import org.dronus.gl.GLFont;
00012 import org.dronus.gl.GLUtil;
00013 import org.dronus.graph.Node;
00014 import org.hfbk.vis.Prefs;
00015 import org.lwjgl.opengl.GL11;
00016 import org.lwjgl.util.vector.Vector3f;
00017 
00031 public class VisObj extends VisNodeDraggable {
00032 
00033         int dl;  // DisplayList number
00034 
00035         Vector3f epicenter;
00036         
00037         class Line extends ArrayList<Vector3f>{}
00038         class Face extends ArrayList<Vector3f>{}
00039         class Group { 
00040                 String name;
00041                 List<Face> faces=new ArrayList<Face>();
00042                 List<Line> lines=new ArrayList<Line>();                 
00043         }
00044         
00045         
00046         List<Vector3f> verticies=new ArrayList<Vector3f>(); //store verticies
00047         List<Group> groups=new ArrayList<Group>();   
00048         
00049         List<List<Vector3f>> triangles=new ArrayList<List<Vector3f>>(); //all triangles for hit detection
00050         
00051         
00052         public VisObj(Node n, Vector3f position) {
00053                 super(n, position);
00054                 
00055                 try {
00056                         load(new URL("file:"+n.text));
00057                 } catch (IOException e) {
00058                         e.printStackTrace();
00059                 }
00060         }
00061         
00062         public VisObj(String ressource, Vector3f pos){
00063                 super(new Node(ressource), pos);
00064                 try {
00065                         URL r=ClassLoader.getSystemResource(ressource);
00066                         load(r);
00067                 } catch (IOException e) {
00068                         e.printStackTrace();
00069                 }
00070         }
00071         
00087         void load(URL url) throws  IOException{
00088                 BufferedReader r=new BufferedReader(new InputStreamReader(url.openStream()));
00089                 //r.mark((int)file.length()+1); //buffer whole file for vertex readahead
00090                 Vector3f scale=new Vector3f(1,1,1);
00091                 
00092                 Group currentGroup=new Group();
00093                 currentGroup.name="default";
00094                 groups.add(currentGroup);
00095                 
00096                 String line;            
00097                 while ((line=r.readLine())!=null){ //read file while lines left..
00098                         String[] params=line.split(" +"); //split line on (maybe mutliple) whitespaces
00099                         if (params.length==0) continue; //empty line
00100                         
00101                         String command=params[0];  //useful command is either v or f
00102                         
00103 
00104                         if (params[0].equals("v")){ //parse a vertex
00105                                 Vector3f vertex=new Vector3f(
00106                                                 Float.parseFloat(params[1])*scale.x, 
00107                             Float.parseFloat(params[2])*scale.y,
00108                             Float.parseFloat(params[3])*scale.z
00109                            );
00110                                 verticies.add(vertex);
00111                                 
00112                                 radius=Math.max(radius, vertex.length());
00113                                 
00114                         }       
00115                         
00116                         if (command.equals("center")){ //parse the center
00117                                 epicenter=new Vector3f(Float.parseFloat(params[1]), 
00118                                    Float.parseFloat(params[2]),
00119                                    Float.parseFloat(params[3])
00120                                    );
00121                                                                                 
00122                         }else if (command.equals("f")){ //parse a face
00123                                 Face f=new Face();
00124                                 for (int i=1; i<params.length; i++){
00125                                         String parts[]=params[i].split("/");
00126                                           //only care for verticie indicies
00127                                         //ignoring texture and normals
00128                                         
00129                                         Vector3f v=verticies.get(Integer.parseInt(parts[0])-1);
00130                                         f.add(v); 
00131                                 }
00132                                 currentGroup.faces.add(f); 
00133                         }else if (command.equals("l")){ //parse a line
00134                                 Line l=new Line();
00135                                 for (int i=1; i<params.length; i++){
00136                                         Vector3f v=verticies.get(Integer.parseInt(params[i])-1);
00137                                         l.add(v);   
00138                                 }
00139                                 currentGroup.lines.add(l);
00140                         }else if (command.equals("g") && params.length>1){
00141                                 currentGroup=new Group();
00142                                 currentGroup.name=params[1];
00143                                 groups.add(currentGroup);
00144                         }else if (command.equals("scale")){
00145                                 scale=new Vector3f(Float.parseFloat(params[1]), 
00146                             Float.parseFloat(params[2]),
00147                             Float.parseFloat(params[3])
00148                            );
00149                         }       
00150                 }
00151                 r.close();
00152 //              System.out.println(maxx+","+minx+","+maxz+","+minz);
00153         }
00154 
00155         void drawNormals(){
00156                 GL11.glLineWidth(2);
00157                 for (Group g: groups)
00158                         for (Face f: g.faces){
00159                                 if (f.size()<3) continue;
00160                         
00161                                 Vector3f normal=getNormal(f);
00162                                 normal.scale(10);
00163                                 
00164                                 Vector3f mid=getCenter(f);
00165                                 
00166                                 GL11.glBegin(GL11.GL_LINE_STRIP);
00167                                 GL11.glColor3f(0,0,1);
00168                                 GL11.glVertex3f(normal.x+mid.x, normal.y+mid.y,normal.z+mid.z);
00169                                 GL11.glColor3f(1,1,1);
00170                                 GL11.glVertex3f(mid.x,mid.y,mid.z);
00171                                 GL11.glColor3f(1,0,0);
00172                                 GL11.glVertex3f(-normal.x+mid.x, -normal.y+mid.y, -normal.z+mid.z);
00173                                 GL11.glEnd();
00174                         }
00175                                 
00176                 GL11.glLineWidth(1);
00177         }
00178         
00179         Vector3f getNormal(List<Vector3f> tri){
00180                 Vector3f n0=tri.get(0), n1=tri.get(1), n2=tri.get(2);
00181                 Vector3f d0=new Vector3f(), d2=new Vector3f();
00182                 Vector3f.sub(n0,n1, d0);
00183                 Vector3f.sub(n2,n1, d2);
00184                 Vector3f normal=new Vector3f();
00185                 Vector3f.cross(d0, d2, normal);
00186                 normal.normalise();             
00187                 return normal;
00188         }
00189         
00190         Vector3f getCenter(List<Vector3f> poly){
00191                 Vector3f c=new Vector3f();
00192                 for (Vector3f v: poly){
00193                         Vector3f.add(c, v, c);                  
00194                 }
00195                 c.scale(1f/poly.size());
00196                 return c;
00197         }
00198         
00199         void drawFaces(){
00200                 
00201                 for (Group g:groups){
00202                         if (!g.name.equals("default")) groupColor(g.name.hashCode()&0xFF);
00203                         for (Face f: g.faces){
00204                                 
00205                                 List<List<Vector3f>> convexPolys;                               
00206                                 if (f.size()<4){
00207                                         convexPolys=new ArrayList<List<Vector3f>>();
00208                                         convexPolys.add(f);
00209                                 }else{
00210                                         Convexiser bfec=new Convexiser();                               
00211                                         convexPolys=bfec.convexise(f);
00212                                 }
00213                                 
00214                                 for (List<Vector3f> t: convexPolys){
00215                                         GL11.glBegin(GL11.GL_POLYGON);  
00216                                         for (Vector3f v: t)
00217                                                 GL11.glVertex3f(v.x,v.y,v.z);
00218                                         GL11.glEnd();
00219                                         
00220                                         triangles.add(t);
00221                                 }
00222                         }
00223                 }
00224         }
00225         
00226         void groupColor(float g){
00227                 if (g>0) {
00228                         g=g*41;
00229                         GL11.glColor3f((g/3)%1f, (g/5)%1f, (g/7)%1f);
00230                 }
00231         }
00232         
00233         void drawWireframe(){
00234                 for (Group g: groups)
00235                         for (Face f: g.faces){
00236                                 GL11.glBegin(GL11.GL_LINE_LOOP);
00237                                 for (Vector3f v: f) 
00238                                         GL11.glVertex3f(v.x,v.y,v.z);                                   
00239                                 GL11.glEnd();
00240                         }               
00241         }
00242         
00243         void drawLines(){
00244                 for (Group g: groups)
00245                         for (Line l: g.lines){
00246                                 GL11.glBegin(GL11.GL_LINE_STRIP);
00247                                 for (Vector3f v: l)
00248                                         GL11.glVertex3f(v.x,v.y,v.z);
00249                                 GL11.glEnd();
00250                         }
00251         }
00252         
00256         void renderSelf() {
00257                 
00258                 //if we have a VisStructure, place us underneath to conveniently stay close
00259                 //to the user if he raises the floor via fetches.
00260                 if (parent instanceof VisRoot){
00261                         VisNode struct=parent.findNode(VisStructure.class);
00262                         if (struct!=null){
00263                                 parent.remove(this);
00264                                 struct.add(this);
00265                         }
00266                 }
00267                 
00268                 if (dl==0){ //display list already built? if not, compile it.
00269                         dl=GL11.glGenLists(1); 
00270                         GL11.glNewList(dl, GL11.GL_COMPILE);
00271                         
00272                         GL11.glDisable(GL11.GL_TEXTURE_2D);
00273                         
00274                         GL11.glPolygonOffset(1,1); //push back the surface in z buffer to allow clean wireframe drawing
00275                         GL11.glColor4f(.5f,.5f,.5f,.3f);
00276                         drawFaces();
00277                         GL11.glPolygonOffset(0,0);
00278                         
00279                         GL11.glColor3f(1,1,1);
00280                         drawWireframe();
00281 
00282                         drawLines();
00283                         
00284                         GL11.glEndList();
00285                         
00286                         if (epicenter!=null)
00287                                 getRoot().epicenter=epicenter;
00288                 }
00289                 
00290                 //draw compiled list
00291                 GL11.glCallList(dl);
00292                 
00293                 if (isHoovered) {
00294                         GL11.glColor3f(1,0,0);
00295                         drawWireframe();
00296                 } 
00297                 
00298                 if (Prefs.current.debug){
00299                         
00300                         drawNormals();
00301                         drawIndicies();
00302                         
00303 /*                      if (hitTri!=null){
00304                                 GL11.glColor3f(1,1,1);                          
00305                                 GL11.glBegin(GL11.GL_POLYGON);  
00306                                 for (Vector3f v: hitTri)
00307                                         GL11.glVertex3f(v.x,v.y,v.z);
00308                                 GL11.glEnd();                           
00309                         }*/                     
00310                         
00311                 }
00312         }
00313         
00314         void drawIndicies(){
00315                 GLFont.getDefault().render();
00316                 int index=0;
00317                 for (Vector3f v: verticies){
00318                         GL11.glPushMatrix();
00319                         GL11.glTranslatef(v.x, v.y, v.z);
00320                         GLUtil.billboardCylinder();
00321                         GL11.glColor3f(1,1,1);
00322                         GLFont.getDefault().print(""+index++);                                  
00323                         GL11.glPopMatrix();
00324                 }
00325                 
00326                 GL11.glDisable(GL11.GL_TEXTURE_2D);
00327         }
00328 
00329 
00333          boolean hitTriangle(Ray ray, List<Vector3f> polygon) {
00334         
00335                  final double EPSILON=0.000001;
00336                  
00337                  Vector3f vert0=polygon.get(0);
00338                  Vector3f vert1=polygon.get(1);
00339                  Vector3f vert2=polygon.get(2);
00340                  
00341                 Vector3f edge1=new Vector3f(), edge2=new Vector3f(), tvec=new Vector3f(), pvec=new Vector3f(), qvec=new Vector3f();
00342             
00343             Vector3f.sub(vert1, vert0, edge1);
00344             Vector3f.sub(vert2, vert0, edge2);
00345             
00346             Vector3f.cross(ray.dir, edge2, pvec);           
00347             
00348              // if determinant is near zero, ray lies in plane of triangle 
00349            double det =Vector3f.dot(edge1,pvec); 
00350            
00351             if (det > -EPSILON && det < EPSILON)
00352               return false;
00353         
00354             double inv_det = 1.0 / det;
00355 
00356             // calculate distance from vert0 to ray origin
00357             Vector3f.sub(ray.start, vert0, tvec);
00358             
00359             // calculate U parameter and test bounds 
00360             double u = Vector3f.dot(tvec, pvec) * inv_det;
00361             if (u < 0.0 || u > 1.0)
00362               return false;
00363 
00364             
00365             // calculate V parameter and test bounds 
00366             Vector3f.cross(tvec,edge1,qvec);        
00367             double v = Vector3f.dot(ray.dir, qvec) * inv_det;
00368             if (v < 0.0 || u + v > 1.0)
00369               return false;
00370             
00371             // calculate t for hit = ray.start + ray.dir * t
00372             // t = Vector3f.dor(edge2, qvec) * inv_det;
00373             
00374             return true;
00375          }
00376          
00383         boolean hit(Ray mouseray, Vector3f hit) {
00384                 float distance;
00385                 
00386                 if(handle==null)        distance=GLUtil.getPosition().length();
00387                 else                            distance=hitDepth;
00388                 Vector3f projector=(Vector3f)new Vector3f(mouseray.dir).scale(distance);  // / projectiveLength; 
00389                 Vector3f.add(mouseray.start, projector, hit);
00390 
00391                 //if (hit.length()>radius) return false;
00392                 
00393                 for (List<Vector3f> t:triangles)
00394                         if (hitTriangle(mouseray, t)) 
00395                                 return true;
00396                 
00397                 return false;                   
00398         }
00399 }

Generated on Tue Apr 7 17:57:22 2009 for visclient by  doxygen 1.5.1