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(); }
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(); }
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); } } }
// 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); } }
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; }
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++) }