static unsigned int compute_subdivisions(const BezierPath::Point& p0, const BezierPath::Point& p1, const BezierPath::Point& p2, const BezierPath::Point& p3, BezierPath::Coord flat) { vector2d<BezierPath::Coord> d01(p1.x() - p0.x(), p1.y() - p0.y()); vector2d<BezierPath::Coord> d12(p2.x() - p1.x(), p2.y() - p1.y()); vector2d<BezierPath::Coord> d23(p3.x() - p2.x(), p3.y() - p2.y()); vector2d<BezierPath::Coord> d03(p3.x() - p0.x(), p3.y() - p0.y()); vector2d<BezierPath::Coord> d01_12 = d12 - d01; vector2d<BezierPath::Coord> d12_23 = d23 - d12; double dist = norm(d03); double dist2; if (dist != 0) { dist2 = __myabs(cross(d01_12, d03) / dist); double tmp = __myabs(cross(d12_23, d03) / dist); if (tmp > dist2) { dist2 = tmp; } } else { vector2d<BezierPath::Coord> d0(p0.x(), p0.y()); dist2 = norm(vector2d<BezierPath::Coord>(d01_12 - d0)); double tmp = norm(vector2d<BezierPath::Coord>(d12_23 - d0)); if (tmp > dist2) { dist2 = tmp; } } unsigned int subdivisions = 0; if (dist2 > 0) { subdivisions = log4(long((3.0 / 4.0) * dist2 / flat + 0.5)); } return subdivisions; }
void render() { glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); zviewpointSetupView(); const int MAX_TRIS = 1000000; static Triangle tris[MAX_TRIS]; int triCount = 0; const int steps = 60; const float stepsf = (float)steps; Rod r0( FVec3(-0.3f,0.f,0.f), FVec3(+0.f,0.f,0.f), Cloud_r ); Rod r1( FVec3(0.f,0.f,0.f), FVec3(0.2f,0.5f,0.f), Cloud_r ); Sphere s0( FVec3(-.5f, -.5f, 0.f), 0.25f ); Surface *surfaces[] = { (Surface *)&r0, (Surface *)&r1, (Surface *)&s0 }; int surfacesCount = sizeof(surfaces) / sizeof(surfaces[0]); float f[steps][steps][steps]; for( int xi=0; xi<steps; xi++ ) { for( int yi=0; yi<steps; yi++ ) { for( int zi=0; zi<steps; zi++ ) { FVec3 p( 2.f*(float)xi/stepsf-1.f, 2.f*(float)yi/stepsf-1.f, 2.f*(float)zi/stepsf-1.f ); f[xi][yi][zi] = 0.f; for( int i=0; i<surfacesCount; i++ ) { f[xi][yi][zi] += surfaces[i]->surface( p ); } } } } for( int xi=0; xi<steps-1; xi++ ) { for( int yi=0; yi<steps-1; yi++ ) { for( int zi=0; zi<steps-1; zi++ ) { GridCell g; float x0 = 2.f*(float)(xi+0)/stepsf-1.f; float x1 = 2.f*(float)(xi+1)/stepsf-1.f; float y0 = 2.f*(float)(yi+0)/stepsf-1.f; float y1 = 2.f*(float)(yi+1)/stepsf-1.f; float z0 = 2.f*(float)(zi+0)/stepsf-1.f; float z1 = 2.f*(float)(zi+1)/stepsf-1.f; g.p[0] = FVec3( x0, y0, z0 ); g.p[1] = FVec3( x1, y0, z0 ); g.p[2] = FVec3( x1, y1, z0 ); g.p[3] = FVec3( x0, y1, z0 ); g.p[4] = FVec3( x0, y0, z1 ); g.p[5] = FVec3( x1, y0, z1 ); g.p[6] = FVec3( x1, y1, z1 ); g.p[7] = FVec3( x0, y1, z1 ); g.val[0] = f[xi+0][yi+0][zi+0]; g.val[1] = f[xi+1][yi+0][zi+0]; g.val[2] = f[xi+1][yi+1][zi+0]; g.val[3] = f[xi+0][yi+1][zi+0]; g.val[4] = f[xi+0][yi+0][zi+1]; g.val[5] = f[xi+1][yi+0][zi+1]; g.val[6] = f[xi+1][yi+1][zi+1]; g.val[7] = f[xi+0][yi+1][zi+1]; triCount += polygonise( g, Cloud_r, &tris[triCount] ); assert( triCount < MAX_TRIS ); } } } DiscWarp dw( FVec3(-0.2f,0.f,0.f), FVec3(1.f,0.f,0.f) ); for( int i=0; i<triCount; i++ ) { tris[i].p[0] = dw.warp( tris[i].p[0] ); tris[i].p[1] = dw.warp( tris[i].p[1] ); tris[i].p[2] = dw.warp( tris[i].p[2] ); } dw.draw(); static unsigned int triList[MAX_TRIS*3]; static FVec3 normals[MAX_TRIS*3]; ZGLLight light0; light0.resetToDefaults(); light0.active = 1; light0.ambient[0] = 0.05f; light0.ambient[1] = 0.05f; light0.ambient[2] = 0.05f; light0.diffuse[0] = 0.8f; light0.diffuse[1] = 0.2f; light0.diffuse[2] = 0.2f; light0.dir[0] = 10.f; light0.dir[1] = 0.f; light0.dir[2] = 0.f; light0.makeDirectional(); light0.setLightNumber( 0 ); ZGLLight light1; light1.resetToDefaults(); light1.active = 1; light1.ambient[0] = 0.05f; light1.ambient[1] = 0.05f; light1.ambient[2] = 0.05f; light1.diffuse[0] = 0.2f; light1.diffuse[1] = 0.2f; light1.diffuse[2] = 0.8f; light1.dir[0] = -10.f; light1.dir[1] = -10.f; light1.dir[2] = 0.f; light1.makeDirectional(); light1.setLightNumber( 1 ); glEnable( GL_COLOR_MATERIAL ); glEnable( GL_LIGHTING ); glEnable( GL_LIGHT0 ); glEnable( GL_LIGHT1 ); glEnable( GL_DEPTH_TEST ); glEnable( GL_NORMALIZE ); light0.setGL(); light1.setGL(); for( int i=0; i<triCount; i++ ) { FVec3 d10( tris[i].p[1] ); d10.sub( tris[i].p[0] ); FVec3 d20( tris[i].p[2] ); d20.sub( tris[i].p[0] ); normals[i*3+0] = d20; normals[i*3+0].cross( d10 ); FVec3 d01( tris[i].p[0] ); d01.sub( tris[i].p[1] ); FVec3 d21( tris[i].p[2] ); d21.sub( tris[i].p[1] ); normals[i*3+1] = d01; normals[i*3+1].cross( d21 ); FVec3 d02( tris[i].p[0] ); d02.sub( tris[i].p[2] ); FVec3 d12( tris[i].p[1] ); d12.sub( tris[i].p[2] ); normals[i*3+2] = d12; normals[i*3+2].cross( d02 ); triList[i*3+0] = i*3+0; triList[i*3+1] = i*3+1; triList[i*3+2] = i*3+2; } glColor3ub( 255, 255, 255 ); glEnableClientState( GL_VERTEX_ARRAY ); glVertexPointer( 3, GL_FLOAT, 0, &tris[0] ); glEnableClientState( GL_NORMAL_ARRAY ); glNormalPointer( GL_FLOAT, 0, &normals[0] ); glDrawElements( GL_TRIANGLES, triCount*3, GL_UNSIGNED_INT, &triList[0] ); }