Beispiel #1
0
  void BSPTree::init(const TriMesh* mesh, Mat4x4f transform, 
             vector<int> &trilist, 
             int _max_objects, int _max_level) 
  {
    trimesh.push_back(mesh);
    transforms.push_back(transform);
    // Loop through all triangles and add them to intersection structure
    for(unsigned int j=0;j<trilist.size();j++) 
    {
      Vec3i face = mesh->geometry.face(trilist[j]);
      ISectTri new_tri;
      new_tri.point0 = transform.mul_3D_point(mesh->geometry.vertex(face[0]));
      new_tri.point1 = transform.mul_3D_point(mesh->geometry.vertex(face[1]));
      new_tri.point2 = transform.mul_3D_point(mesh->geometry.vertex(face[2]));
      new_tri.edge0 = new_tri.point1 - new_tri.point0;
      new_tri.edge1 = new_tri.point2 - new_tri.point0;
      new_tri.mesh_id = 0;
      new_tri.tri_id = trilist[j];
      isecttris.push_back(new_tri);
      TriAccel ta;
      create_tri_accel(new_tri.point0, new_tri.point1, new_tri.point2, ta);
      ta.mesh_id = 0;
      ta.tri_id = trilist[j];
      triaccel.push_back(ta);
    }

    max_objects = _max_objects;
    max_level = _max_level;
    init();
  }
Beispiel #2
0
	void Sphere::transform(const Mat4x4f& m)
	 {
	   Vec3f radius_vec = m.mul_3D_point(Vec3f(radius,0,0)+position);
	   position = m.mul_3D_point(position); 
	   // The radius is scaled by the X scaling factor.
	   // Not ideal, but the best we can do without elipsoids
	   radius_vec -= position;
	   radius = radius_vec.length();
	 }
Beispiel #3
0
void truncated_cone(const Mat4x4f& m, float l, float w0, float w1, vector<Vec3f>& strip)
{
    float len = sqrt(l*l + sqr(w0-w1));
    float a = l/len;
    float b = (w0-w1)/len;
    const int N = 10;
    for(int i=0;i<=N;++i)
    {
        float alpha = 2.0*M_PI*float(i)/N;
        Vec3f p0 = m.mul_3D_point(Vec3f(w0*cos(alpha), w0*sin(alpha), 0));
        Vec3f p1 = m.mul_3D_point(Vec3f(w1*cos(alpha), w1*sin(alpha), l));
        Vec3f n = m.mul_3D_vector(a*Vec3f(cos(alpha), sin(alpha), b));
        if(i==0){
            strip.push_back(n);
            strip.push_back(p0);
        }
        strip.push_back(n);
        strip.push_back(p0);
        strip.push_back(n);
        strip.push_back(p1);
        if(i==N){
            strip.push_back(n);
            strip.push_back(p1);
        }
    }
}
Beispiel #4
0
// Produce the mesh for a truncated cone
void truncated_cone(const Mat4x4f& m,           // transformation matrix used for the points
                    float l,                    // length of truncated cone
                    float w0,                   // width at base
                    float w1,                   // width at top
                    vector<Vec3f>& triangles,   // triangles (out)
                    vector<Vec3f>& normals)     // normals (out)
{
    float len = sqrt(l*l + sqr(w0-w1));
    float a = l/len;
    float b = (w0-w1)/len;
    const int N = 10;
    for(int i=0;i<=N;++i)
    {
        float alpha = 2.0*M_PI*float(i)/N;
        Vec3f p0 = m.mul_3D_point(Vec3f(w0*cos(alpha), w0*sin(alpha), 0));
        Vec3f p1 = m.mul_3D_point(Vec3f(w1*cos(alpha), w1*sin(alpha), l));
        Vec3f n0 = m.mul_3D_vector(a*Vec3f(cos(alpha), sin(alpha), b));
        Vec3f n1 = n0;

        alpha = 2.0*M_PI*float(i+1)/N;
        Vec3f p2 = m.mul_3D_point(Vec3f(w0*cos(alpha), w0*sin(alpha), 0));
        Vec3f p3 = m.mul_3D_point(Vec3f(w1*cos(alpha), w1*sin(alpha), l));
        Vec3f n2 = m.mul_3D_vector(a*Vec3f(cos(alpha), sin(alpha), b));
        Vec3f n3 = n2;

        normals.push_back(n0);
        triangles.push_back(p0);

        normals.push_back(n1);
        triangles.push_back(p1);

        normals.push_back(n3);
        triangles.push_back(p3);

        normals.push_back(n3);
        triangles.push_back(p3);

        normals.push_back(n2);
        triangles.push_back(p2);

        normals.push_back(n0);
        triangles.push_back(p0);
    }
}
Beispiel #5
0
	bool LDILayer::convert_to_points(const Mat4x4f& itransf, 
																	 vector<PointRecord>& points)
	{
		int points_num = 0;
		for(int j=0;j<normal_buffer.get_ydim();++j)
			for(int i=0;i<normal_buffer.get_xdim();++i)
				{
					float z = depth_buffer(i,j);
					if(z > 0.0f && z < 1.0f)
						{
							Vec3f n = 2.0f*(normal_buffer(i,j) - Vec3f(0.5));
							float x = (i+0.5f)/float(normal_buffer.get_xdim());
							float y = (j+0.5f)/float(normal_buffer.get_ydim());
							Vec3f p = itransf.mul_3D_point(Vec3f(x,y,1-z));
							Vec4f c = colour_buffer(i,j);
							PointRecord r = {c,n,p};
							points.push_back(r);
							++points_num;
						}
				}
		return points_num>0;
	}
Beispiel #6
0
  void mesh(vector<MyVertex*> inv, 
	    vector<MyPolygon*> inp, 
	    vector<MyVertex*> &outv, 
	    vector<MyPolygon*> &outp, 
	    float _size, float lightsize) {
		
    for (int i=0;i<inp.size();i++) {

      float size = _size;
			
      int vertices = inp[i]->vertices;
      
      // setup basis
      
      Vec3f opoint[4];
      
      {
	for (int j=0;j<vertices;j++) {
	  opoint[j] = inv[inp[i]->vertex[j]]->position;
	}
      }		
      
      Vec3f basisu = opoint[1] - opoint[0];
      Vec3f basisv = opoint[vertices-1] - opoint[0];
      
      basisu.normalize();
      basisv.normalize();
			
      Vec3f basisw = cross(basisu, basisv);
      Vec3f newbasisv = cross(basisw, basisu);

      Vec3f normal = basisw;
      normal.normalize();
				
      Mat4x4f mat = identity_Mat4x4f();
      
      identity_Mat4x4f();

      { for (int q=0;q<3;q++) {	mat[q][0] = basisu[q]; } }
      { for (int q=0;q<3;q++) {	mat[q][1] = newbasisv[q]; } }
      { for (int q=0;q<3;q++) {	mat[q][2] = basisw[q]; } }
      
      Mat4x4f imat = invert(mat);

      Vec3f point[4];
      
      // transform to 2D and find AABB
			
      float minx, miny, maxx, maxy;
      minx = miny = +1e+30f;
      maxx = maxy = -1e+30f;
				
      {
	for (int j=0;j<vertices;j++) {
	  
	  point[j] = imat.mul_3D_point(opoint[j]);
	  
	  if (point[j][0] < minx ) minx = point[j][0];
	  if (point[j][0] > maxx ) maxx = point[j][0];

	  if (point[j][1] < miny ) miny = point[j][1];
	  if (point[j][1] > maxy ) maxy = point[j][1];
	  
	}
      }

      // calculate imaginary "texture coordinates"
      
      int inverts = vertices;
      int outverts=0;
			
      int ymin, xmin, xmax, ymax;

      int max_subdivx = 10;
      int max_subdivy = 10;
			
      Vec3f crapx = opoint[1] - opoint[0];
      Vec3f crapy = opoint[vertices-1] - opoint[0];		
			
      if (0 != inp[i]->emissive.length()) {
	size = lightsize;
      }
			
      max_subdivx = (int)( crapy.length() / size +0.5f);
      max_subdivy = (int)( crapx.length() / size +0.5f);

      xmin = ymin = 0;
      xmax = max_subdivx;		
      ymax = max_subdivy;		
			
      Vec3f unclipped[10];  // unclipped polygon
      Vec3f clipped[10];

      float scalex = (1.0f/(maxx-minx));
      float scaley = (1.0f/(maxy-miny));
			
      {
	for (int j=0;j<vertices;j++) {				
	  unclipped[j][0] = (point[j][0] - minx) * scalex;
	  unclipped[j][1] = (point[j][1] - miny) * scaley;
	  unclipped[j][2] = point[j][2] ;
	  
	}
      }		
									
      // adjust bounding box (just to be sure every element is accounted for )
      ymin--; if (ymin<0) ymin = 0;
      xmin--; if (xmin<0) xmin = 0;
      xmax++; if (xmax>max_subdivx) xmax = max_subdivx; if (xmax<=0) xmax=1;
      ymax++; if (ymax>max_subdivy) ymax = max_subdivy; if (ymax<=0) ymax=1;
      
      Vec3f emissive = inp[i]->emissive;
      Vec3f diffuse  = inp[i]->diffuse;
      
      {
				
	MyPolygon* p;
	
	int vertexoffset = outv.size()-1; 
	if (vertexoffset<0) vertexoffset=0;
	
	for (int i=ymin;i<ymax;i++) {
	  for (int j=xmin;j<xmax;j++) {					
	    
	    Vec3f texel[10];  // texel boundary
	    Vec3f* pin = texel;
	    
	    float deltax = 1  *  1.0f/(float)max_subdivy;
	    float deltay = 1  *  1.0f/(float)max_subdivx;
	    float xx= 1  *  (float)i/(float)max_subdivy;
	    float yy= 1  *  (float)j/(float)max_subdivx;
	    
	    *pin++ = Vec3f(xx, yy, unclipped[0][2]);
	    *pin++ = Vec3f(xx+deltax,yy, unclipped[0][2]);
	    *pin++ = Vec3f(xx+deltax,yy+deltay, unclipped[0][2]);
	    *pin++ = Vec3f(xx,yy+deltay, unclipped[0][2]);
							
	    SutherlandHodgmanClipper clipper;
	    clipper.ClipToMyPolygon(unclipped, clipped, inverts, &outverts, texel, 4);
	    
	    // create polygon & vertices 
	    
	    p = NULL;
	    int verts = outverts;
	    Vec3f* vpoly = clipped;
	    int first=1;							
	    MyPolygonSplitter psplit;	
	    
	    if (outverts) while (true) {		
	      
	      if (outverts>4) {	// larger polygons
		
		Vec3f A = clipped[0] - clipped[2];
		Vec3f B = clipped[1] - clipped[3];									

		float a = A.length();
		float b = B.length();
		
		cout << a << "," << b << endl;
		
		if (a>=b-b && a<=b+b && outverts==4) {  // check if square quad 
		  first = -1;
		} else {			// split non-square quad into triangles									
		  if (first) psplit.Split(clipped, outverts);
		  first=0;
		  vpoly = psplit.NextTriangle();
		  verts = 3;										
		  if (!vpoly) break;
		}
		
	      } else first = -1;	
	      
	      p = new MyPolygon();
	      p->diffuse = Vec3f(-1,-1,-1);
	      
	      for (int q=0;q<verts;q++) {
		
		vpoly[q][0] = (((vpoly[q][0]/scalex)) + minx);
		vpoly[q][1] = (((vpoly[q][1]/scaley)) + miny);
		vpoly[q] = mat.mul_3D_point(vpoly[q]);	// transform back to 3D
		
#define EQ(a,b) (a>=b-0.001f && a<=b+0.001f)
		
		int found = -1;
		for(int i=vertexoffset;i<outv.size();i++) {
		  if (EQ(outv[i]->position[0],vpoly[q][0]) && 
		      EQ(outv[i]->position[1],vpoly[q][1]) && 
		      EQ(outv[i]->position[2],vpoly[q][2]) ) {
		    found = i;
		    break;
		  }
		}
		
		if (-1!=found) {
		  p->vertex[q] = found;
		} else {
		  MyVertex* v = new MyVertex();
		  v->position = vpoly[q];
		  p->vertex[q] = outv.size();
		  outv.push_back(v);
		}
		
	      }
	      
	      
	      Vec3f center;
	      float area = 0;				
	      
	      calcMyPolygonAreaAndCenter(vpoly, verts, area, center);
	      
	      if (area>0.001f) outp.push_back(p);
	      else p=NULL;
	      
	      if (p) {
		
		p->center     = center;
		p->area       = area;
		p->normal     = normal;
		p->rad        = emissive;
		p->diffuse    = diffuse;
		p->unshot_rad = p->rad;
		p->color	  = diffuse;
		p->vertices   = verts;

        /*
        if( emissive[0] > 0 || emissive[1] > 0 || emissive[2] > 0)
		cerr << " emissive : " << emissive <<
        " area : " << area << endl;
        */

	    }
	      
	      if (-1==first) break;
	      
	      
	    } // end while (true)
	    
	  } // end for (int j=xmin;j<xmax;j++) 

	}	// end for (int i=ymin;i<ymax;i++) 
	
      }
      
    } // end for (int i=0;i<inp.size();i++)
    
  }