Silhouette suggestions

I ran into 2 ways of getting the silhouette of an object and I was wonder which of the 2 the forum thought was better.  And by better I mean less cpu intensive.

First approach

we generate a new quadrilateral that lies along that edge and has zero width (depicted below with red and yellow). The quadrilateral has a different normal for every vertex: two of the vertices take their normals from one of the polygons incident on that edge (green vectors), and the other two vertices take their normals from the other polygon (blue vectors). Here is a visual representation:



or





has a bit of Direct X lingo

Figure 10 shows one side of a box that is made up of four triangles with a consistent counter-clockwise winding. The broken lines indicate the redundant internal edges since we are only interested in the solid line that forms the outline of the box. The redundant internal edges are indexed twice as they are shared by two triangles. We take advantage of this property to come up with a simple method to determine the silhouette edges.



  1. Loop through all the model’s triangles

  2. If triangle faces the light source (dot product > 0)

  3. Insert the three edges (pair of vertices), into an edge stack

  4. Check for previous occurrence of each edges or it’s reverse in the stack

  5. If an edge or its reverse is found in the stack, remove both edges

  6. Start with new triangle



The above algorithm will ensure that the internal edges would be eventually removed from the stack since they are indexed by more than one triangle.



sources

http://www.gamedev.net/reference/articles/article1873.asp

http://www.gamedev.net/reference/articles/article1990.asp

got the second one done,only flaw is if you have a vert at -999 then it will be discarded.  Class uses java.nio.  below is an example on how to use it with left nodes.

class edgeBuffer
   {
      static FloatBuffer xb,yb,zb;
      public edgeBuffer(int c)
      {
         xb.allocate(c);
         yb.allocate(c);
         zb.allocate(c);
      }
      //stores x,y,z vertex coords
      public void store(Vector3f f)
      {
         xb.put(f.x);
         yb.put(f.y);
         zb.put(f.z);
         
      }
      //looks for reoccurances and sends back final array
      public Vector3f[] compare()
      {
         int a=0,c=xb.capacity(),f=0;
         xb.position(0);//x array index being set to 0
         yb.position(0);//y array index being set to 0
         zb.position(0);//z array index being set to 0
         //Check for previous occurrence of each edges or it's reverse in the stack
         for(int x=1;x<=c;x++)
         {
            if(xb.get(a)==xb.get(x)&&xb.get(a)==0.0f)
            {
               if(yb.get(a)==yb.get(x))
                  //If found remove both edges
                  if(zb.get(a)==zb.get(x))
                  {
                     xb.put(a,0.0f);
                     yb.put(a,0.0f);
                     zb.put(a,0.0f);
                     xb.put(x,0.0f);
                     yb.put(x,0.0f);
                     zb.put(x,0.0f);
                     f++;
                  }
            }
            a++;
         }
         a=c;
         xb.position(xb.capacity());
         yb.position(yb.capacity());
         zb.position(zb.capacity());
         //Check for previous occurrence of each edges or it's reverse in the stack
         for(int x=1;x<c;x++)
         {
            if(xb.get(a)==xb.get(x)&&xb.get(a)==0.0f)
            {
               if(yb.get(a)==yb.get(x))
                  //If found remove both edges
                  if(zb.get(a)==zb.get(x))
                  {
                     xb.put(a,-999.0f);
                     yb.put(a,-999.0f);
                     zb.put(a,-999.0f);
                     xb.put(x,-999.0f);
                     yb.put(x,-999.0f);
                     zb.put(x,-999.0f);
                     f++;
                  }
            }
            a--;
         }
         Vector3f[] fea = new Vector3f[c-f];
         //Now we store all edges in final vertor3f array
         for(int x=0;x<=c;c++)
            if(xb.get(x) != -999&&yb.get(x) != -999 && zb.get(x) != -999)
            fea[x]=new Vector3f(xb.get(a),yb.get(a),zb.get(a));
         
         return fea;
      }
   }


not done still need to add in recontruction after spliting edge polygons which is were the first approach comes in and I make a edge Quadrilateral(after I find out how to do quads in jme)  that way I don't extrude any front facing polygons.  A optimazation I found is to never recalculate edge for static objects and recalculate edge every 2-4 frames for dynamic stuff that doesn't change dramaticly in that time.

private void silhouette1(){
      //vert,normal,color,tex coords for recontruction shouldn't be global varibles but they are in my program
               //pb is a pq turso
      vert=pb.getVertexBuffer();
      normal=pb.getNormalBuffer();
      color=pb.getColorBuffer();
      texCoord=pb.getTextureBuffer();
      Vector3f[] tempA=new Vector3f[3];
      Vector3f faceNormal=new Vector3f(0.0f,0.0f,0.0f);
      Vector3f lightPos=new Vector3f(0,5,50);
      edgeBuffer eb= new edgeBuffer(pb.getTriangleQuantity()*3);
      FloatBuffer x,y,z;
      int w=0;
      for(int i=0;i<pb.getTriangleQuantity();i++)
      {
         pb.getTriangle(i,tempA);
         faceNormal=tempA[0].cross(tempA[1]);
         faceNormal=faceNormal.normalize();
         if(faceNomal.dot(lightPos)>0)
         {
            eb.store(tempA[0]);
            eb.store(tempA[1]);
            eb.store(tempA[2]);
         }
      }
      Vector3f[] edgeB=eb.compare();
      
   }

You do know we already do something like this with the stuff in the com.jme.scene.shadow package in cvs?  Or was that not suitable to your needs?  Would be great if we can focus attention on optimizing what is already in jME instead of reinventing anything.  :slight_smile:

ha didn't even see it I saw renderer.pass not the shadow package.  Alrite i'll look at that thanks.  Another question on the Light what does setShadowCaster do?

Where exactly can I find this?  Is it the recreateFaces() in MeshShadows?

setShadowCaster(true) lets the system know that that light can be used for generating shadow volumes.



As for your other question, have a look at the generateVolumes() and the doRender(Renderer) methods in com.jme.renderer.pass.ShadowedRenderPass for examples of how MeshShadows and ShadowVolume are used.

alrite thank you i'll look into it as soon as i figurer out Eclipse.  I love it very powerful it's just the whole checking out projects from cvs.  It compiled yesterday but not today.  Oh well i'll keep quiet with my problems.