int PointSet::AddVolume ( Vector3DF min, Vector3DF max, float spacing ) { Vector3DF pos; Point* p; float dx, dy, dz; dx = max.x-min.x; dy = max.y-min.y; dz = max.z-min.z; int cnt = 0; for (float z = max.z; z >= min.z; z -= spacing ) { for (float y = min.y; y <= max.y; y += spacing ) { for (float x = min.x; x <= max.x; x += spacing ) { p = GetPoint ( AddPointReuse () ); pos.Set ( x, y, z); //pos.x += -0.05 + float( rand() * 0.1 ) / RAND_MAX; //pos.y += -0.05 + float( rand() * 0.1 ) / RAND_MAX; //pos.z += -0.05 + float( rand() * 0.1 ) / RAND_MAX; p->pos = pos; p->type = 0; p->clr = COLORA( (x-min.x)/dx, (y-min.y)/dy, (z-min.z)/dz, 1); cnt++; } } } sphPoints = cnt ; return sphPoints; }
float Camera3D::calculateLOD ( Vector3DF pnt, float minlod, float maxlod, float maxdist ) { Vector3DF vec = pnt; vec -= from_pos; float lod = minlod + (vec.Length() * (maxlod-minlod) / maxdist ); lod = (lod < minlod) ? minlod : lod; lod = (lod > maxlod) ? maxlod : lod; return lod; }
void PointSet::AddVolume ( Vector3DF min, Vector3DF max, float spacing ) { Vector3DF pos; Point* p; float dx, dy, dz; dx = max.x-min.x; dy = max.y-min.y; dz = max.z-min.z; for (float z = max.z; z >= min.z; z -= spacing ) { for (float y = min.y; y <= max.y; y += spacing ) { for (float x = min.x; x <= max.x; x += spacing ) { p = GetPoint ( AddPointReuse () ); pos.Set ( x, y, z); p->pos = pos; p->clr = COLORA( (x-min.x)/dx, (y-min.y)/dy, (z-min.z)/dz, 1); } } } }
Vector3DF PointSet::GetGradient ( float x, float y, float z ) { Vector3DF norm; float dx, dy, dz, dsq; float sum; int pndx; Point* pcurr; float R2 = (m_GridCellsize/2.0)*(m_GridCellsize/2.0); Grid_FindCells ( Vector3DF(x,y,z), m_GridCellsize/2.0 ); int cnt = 0; sum = 0.0; norm.Set (0,0,0); for (int cell=0; cell < 8; cell++ ) { if ( m_GridCell[cell] != -1 ) { pndx = m_Grid [ m_GridCell[cell] ]; while ( pndx != -1 ) { pcurr = (Point*) (mBuf[0].data + pndx*mBuf[0].stride); dx = x - pcurr->pos.x; dy = y - pcurr->pos.y; dz = z - pcurr->pos.z; dsq = dx*dx+dy*dy+dz*dz; if ( dsq > 0 && dsq < R2 ) { dsq = 2.0*R2 / (dsq*dsq); norm.x += dx * dsq; norm.y += dy * dsq; norm.z += dz * dsq; } pndx = pcurr->next; } } } norm.Normalize (); return norm; }
DWORD PointSet::GetColor ( float x, float y, float z ) { Vector3DF clr; float dx, dy, dz, dsq; float sum; int pndx; Point* pcurr; float R2 = (m_GridCellsize/2.0)*(m_GridCellsize/2.0); Grid_FindCells ( Vector3DF(x,y,z), m_GridCellsize/2.0 ); int cnt = 0; sum = 0.0; clr.Set (0,0,0); for (int cell=0; cell < 8; cell++ ) { if ( m_GridCell[cell] != -1 ) { pndx = m_Grid [ m_GridCell[cell] ]; while ( pndx != -1 ) { pcurr = (Point*) (mBuf[0].data + pndx*mBuf[0].stride); dx = x - pcurr->pos.x; dy = y - pcurr->pos.y; dz = z - pcurr->pos.z; dsq = dx*dx+dy*dy+dz*dz; if ( dsq < R2 ) { dsq = 2.0*R2 / (dsq*dsq); clr.x += RED(pcurr->clr) * dsq; clr.y += GRN(pcurr->clr) * dsq; clr.z += BLUE(pcurr->clr) * dsq; } pndx = pcurr->next; } } } clr.Normalize (); return COLORA(clr.x, clr.y, clr.z, 1.0); }
void PointSet::AddControlVolume ( std::vector<glm::vec3> *allvertices ) { Vector3DF pos; Point* p; int dimx=5; int dimy=5; float dimz=10; int ccnt=0; //vec3 a = myvertices. ; glm::vec3 startpoint(0,0.0,-5.0); glm::vec3 direction(0,0,1.0); glm::vec3 vertex1(0,1.0,2.0); glm::vec3 vertex2(-1.0,-1.0,0); glm::vec3 vertex3(1.0,-1.0,0); glm::vec3 v1,v2,v3; int a = allvertices->size(); double value=0; value=PointSet::Test_RayPolyIntersect(startpoint,direction,vertex1,vertex2,vertex3); int count=0; float var=1.0; //glm::vec3 *a = myvertices; for (float x = -5; x < 18; x += 1.0) { for (float y = -5; y <= 14; y += 1.0) { for (float z = -5; z <= 25; z += var ) { /*if(z>=-5.0 && z <2.0) var =1.0; else if(z>=2.0 && z < 8.0) var =0.70; else if(z>=8.0 && z < 15.0) var =0.6; else if(z >= 15.0 && z <=25.0) var =0.3;*/ count = 0 ; startpoint=glm::vec3((float)x,(float)y,(float)z); direction=glm::vec3(1.0,0.1,0); for(int v=0 ;v < a ; v+=3) { //checking each vertex in the grid with all the 192 triangles of mesh v1=(*allvertices)[v]; v2=(*allvertices)[v+1]; v3=(*allvertices)[v+2]; vertex1= vec3(v1[0],v1[1],v1[2]); vertex2= vec3(v2[0],v2[1],v2[2]); vertex3= vec3(v3[0],v3[1],v3[2]); value=PointSet::Test_RayPolyIntersect(startpoint,direction,vertex1,vertex2,vertex3); if(value != -1.0) { count++; } } //odd if( count % 2 == 1) { //inside the mesh p = GetPoint ( AddPointReuse () ); pos.Set ( x,y,z+10.0f); p->pos = pos; p->type = 1; p->clr = COLORA( 1.0,0.3,0.3, 0); /// 0.1,0.3,1.0,1.0 ccnt++; } //var=var-0.1; } // var = 1.0; } } }
void Camera3D::draw_gl () { Vector3DF pnt; int va, vb; if ( !mOps[0] ) return; // Box testing // // NOTES: This demonstrates AABB box testing against the frustum // Boxes tested are 10x10x10 size, spaced apart from each other so we can see them. if ( mOps[5] ) { glPushMatrix (); glEnable ( GL_LIGHTING ); glColor3f ( 1, 1, 1 ); Vector3DF bmin, bmax, vmin, vmax; int lod; for (float y=0; y < 100; y += 10.0 ) { for (float z=-100; z < 100; z += 10.0 ) { for (float x=-100; x < 100; x += 10.0 ) { bmin.Set ( x, y, z ); bmax.Set ( x+8, y+8, z+8 ); if ( boxInFrustum ( bmin, bmax ) ) { lod = (int) calculateLOD ( bmin, 1, 5, 300.0 ); //rendGL->drawCube ( bmin, bmax, Vector3DF(1,1,1) ); } } } } glPopMatrix (); } glDisable ( GL_LIGHTING ); glLoadMatrixf ( getViewMatrix().GetDataF() ); // Frustum planes (world space) // // NOTE: The frustum planes are drawn as discs because // they are boundless (infinite). The minimum information contained in the // plane equation is normal direction and distance from plane to origin. // This sufficiently defines infinite planes for inside/outside testing, // but cannot be used to draw the view frustum without more information. // Drawing is done as discs here to verify the frustum plane equations. if ( mOps[2] ) { glBegin ( GL_POINTS ); glColor3f ( 1, 1, 0 ); Vector3DF norm; Vector3DF side, up; for (int n=0; n < 6; n++ ) { norm.Set ( frustum[n][0], frustum[n][1], frustum[n][2] ); glColor3f ( n/6.0, 1.0- (n/6.0), 0.5 ); side = Vector3DF(0,1,0); side.Cross ( norm ); side.Normalize (); up = side; up.Cross ( norm ); up.Normalize(); norm *= frustum[n][3]; for (float y=-50; y < 50; y += 1.0 ) { for (float x=-50; x < 50; x += 1.0 ) { if ( x*x+y*y < 1000 ) { //pnt = side * x + up * y - norm; pnt = side; Vector3DF tv = up; tv *= y; pnt *= x; pnt += tv; pnt -= norm; glVertex3f ( pnt.x, pnt.y, pnt.z ); } } } } glEnd (); } // Inside/outside testing // // NOTES: This code demonstrates frustum clipping // tests on individual points. if ( mOps[4] ) { glColor3f ( 1, 1, 1 ); glBegin ( GL_POINTS ); for (float z=-100; z < 100; z += 4.0 ) { for (float y=0; y < 100; y += 4.0 ) { for (float x=-100; x < 100; x += 4.0 ) { if ( pointInFrustum ( x, y, z) ) { glVertex3f ( x, y, z ); } } } } glEnd (); } // Inverse rays (world space) // // NOTES: This code demonstrates drawing // inverse camera rays, as might be needed for raytracing or hit testing. if ( mOps[3] ) { glBegin ( GL_LINES ); glColor3f ( 0, 1, 0); for (float x = 0; x <= 1.0; x+= 0.5 ) { for (float y = 0; y <= 1.0; y+= 0.5 ) { pnt = inverseRay ( x, y, mFar ); pnt += from_pos; glVertex3f ( from_pos.x, from_pos.y, from_pos.z ); // all inverse rays originate at the camera center glVertex3f ( pnt.x, pnt.y, pnt.z ); } } glEnd (); } // Projection // // NOTES: This code demonstrates // perspective projection _without_ using the OpenGL pipeline. // Projection is done by the camera class. A cube is drawn on the near plane. // Cube geometry Vector3DF pnts[8]; Vector3DI edge[12]; pnts[0].Set ( 0, 0, 0 ); pnts[1].Set ( 10, 0, 0 ); pnts[2].Set ( 10, 0, 10 ); pnts[3].Set ( 0, 0, 10 ); // lower points (y=0) pnts[4].Set ( 0, 10, 0 ); pnts[5].Set ( 10, 10, 0 ); pnts[6].Set ( 10, 10, 10 ); pnts[7].Set ( 0, 10, 10 ); // upper points (y=10) edge[0].Set ( 0, 1, 0 ); edge[1].Set ( 1, 2, 0 ); edge[2].Set ( 2, 3, 0 ); edge[3].Set ( 3, 0, 0 ); // 4 lower edges edge[4].Set ( 4, 5, 0 ); edge[5].Set ( 5, 6, 0 ); edge[6].Set ( 6, 7, 0 ); edge[7].Set ( 7, 4, 0 ); // 4 upper edges edge[8].Set ( 0, 4, 0 ); edge[9].Set ( 1, 5, 0 ); edge[10].Set ( 2, 6, 0 ); edge[11].Set ( 3, 7, 0 ); // 4 vertical edges // -- White cube is drawn using OpenGL projection if ( mOps[6] ) { glBegin ( GL_LINES ); glColor3f ( 1, 1, 1); for (int e = 0; e < 12; e++ ) { va = edge[e].x; vb = edge[e].y; glVertex3f ( pnts[va].x, pnts[va].y, pnts[va].z ); glVertex3f ( pnts[vb].x, pnts[vb].y, pnts[vb].z ); } glEnd (); } //---- Draw the following in camera space.. // NOTES: // The remainder drawing steps are done in // camera space. This is done by multiplying by the // inverse_rotation matrix, which transforms from camera to world space. // The camera axes, near, and far planes can now be drawn in camera space. glPushMatrix (); glLoadMatrixf ( getViewMatrix().GetDataF() ); glTranslatef ( from_pos.x, from_pos.y, from_pos.z ); glMultMatrixf ( invrot_matrix.GetDataF() ); // camera space --to--> world space // -- Red cube is drawn on the near plane using software projection pipeline. See Camera3D::project if ( mOps[6] ) { glBegin ( GL_LINES ); glColor3f ( 1, 0, 0); Vector4DF proja, projb; for (int e = 0; e < 12; e++ ) { va = edge[e].x; vb = edge[e].y; proja = project ( pnts[va] ); projb = project ( pnts[vb] ); if ( proja.w > 0 && projb.w > 0 && proja.w < 1 && projb.w < 1) { // Very simple Z clipping (try commenting this out and see what happens) glVertex3f ( proja.x, proja.y, proja.z ); glVertex3f ( projb.x, projb.y, projb.z ); } } glEnd (); } // Camera axes glBegin ( GL_LINES ); float to_d = (from_pos - to_pos).Length(); glColor3f ( .8,.8,.8); glVertex3f ( 0, 0, 0 ); glVertex3f ( 0, 0, -to_d ); glColor3f ( 1,0,0); glVertex3f ( 0, 0, 0 ); glVertex3f ( 10, 0, 0 ); glColor3f ( 0,1,0); glVertex3f ( 0, 0, 0 ); glVertex3f ( 0, 10, 0 ); glColor3f ( 0,0,1); glVertex3f ( 0, 0, 0 ); glVertex3f ( 0, 0, 10 ); glEnd (); if ( mOps[1] ) { // Near plane float sy = tan ( mFov * DEGtoRAD / 2.0); float sx = sy * mAspect; glColor3f ( 0.8, 0.8, 0.8 ); glBegin ( GL_LINE_LOOP ); glVertex3f ( -mNear*sx, mNear*sy, -mNear ); glVertex3f ( mNear*sx, mNear*sy, -mNear ); glVertex3f ( mNear*sx, -mNear*sy, -mNear ); glVertex3f ( -mNear*sx, -mNear*sy, -mNear ); glEnd (); // Far plane glBegin ( GL_LINE_LOOP ); glVertex3f ( -mFar*sx, mFar*sy, -mFar ); glVertex3f ( mFar*sx, mFar*sy, -mFar ); glVertex3f ( mFar*sx, -mFar*sy, -mFar ); glVertex3f ( -mFar*sx, -mFar*sy, -mFar ); glEnd (); // Subview Near plane float l, r, t, b; l = -sx + 2.0*sx*mTile.x; // Tile is in range 0 <= x,y <= 1 r = -sx + 2.0*sx*mTile.z; t = sy - 2.0*sy*mTile.y; b = sy - 2.0*sy*mTile.w; glColor3f ( 0.8, 0.8, 0.0 ); glBegin ( GL_LINE_LOOP ); glVertex3f ( l * mNear, t * mNear, -mNear ); glVertex3f ( r * mNear, t * mNear, -mNear ); glVertex3f ( r * mNear, b * mNear, -mNear ); glVertex3f ( l * mNear, b * mNear, -mNear ); glEnd (); // Subview Far plane glBegin ( GL_LINE_LOOP ); glVertex3f ( l * mFar, t * mFar, -mFar ); glVertex3f ( r * mFar, t * mFar, -mFar ); glVertex3f ( r * mFar, b * mFar, -mFar ); glVertex3f ( l * mFar, b * mFar, -mFar ); glEnd (); } glPopMatrix (); }