void ScreenMVCullVisitor::apply(Projection& node) { // push the culling mode. pushCurrentMask(); // push the node's state. StateSet* node_state = node.getStateSet(); if(node_state) pushStateSet(node_state); // record previous near and far values. float previous_znear = _computed_znear; float previous_zfar = _computed_zfar; // take a copy of the current near plane candidates DistanceMatrixDrawableMap previousNearPlaneCandidateMap; previousNearPlaneCandidateMap.swap(_nearPlaneCandidateMap); _computed_znear = FLT_MAX; _computed_zfar = -FLT_MAX; ref_ptr < RefMatrix > matrix = createOrReuseMatrix(node.getMatrix()); pushProjectionMatrix(matrix.get()); //OSG_NOTIFY(osg::INFO)<<"Push projection "<<*matrix<<std::endl; // note do culling check after the frustum has been updated to ensure // that the node is not culled prematurely. bool status = _cullingStatus; bool firstStatus = _firstCullStatus; if(!isCulled(node)) { handle_cull_callbacks_and_traverse(node); } _firstCullStatus = firstStatus; _cullingStatus = status; popProjectionMatrix(); //OSG_NOTIFY(osg::INFO)<<"Pop projection "<<*matrix<<std::endl; _computed_znear = previous_znear; _computed_zfar = previous_zfar; // swap back the near plane candidates previousNearPlaneCandidateMap.swap(_nearPlaneCandidateMap); // pop the node's state off the render graph stack. if(node_state) popStateSet(); // pop the culling mode. popCurrentMask(); }
void rasterize() { // Put your main rasterization loop here // It should go over the point model and call drawPoint for every point in it Vector3 normal; int count = 0; Matrix4 newM; Vector3 lightpoint(1, -1, 1); if (fkey == 1) pointmodel = &hop; else pointmodel = &draco; projection.resetMatrix(60, double(window_width) / (double)window_height, 1.0, 1000.0); vp.resetMatrix(0, window_width, 0, window_height); newM = projection.getMatrix() * cam.getMatrix() * pointmodel->getMatrix(); // Clear the zbuffer for (int index = 0; index < (window_width * window_height * 3); index++) { zbuffer[index] = 1.0; } for (int row = 0; row < pointmodel->xyzrows; row++) { Vector4 pt(pointmodel->v_xyz[count], pointmodel->v_xyz[count + 1], pointmodel->v_xyz[count + 2], 1); Vector3 pointmodelpt(pointmodel->v_xyz[count], pointmodel->v_xyz[count + 1], pointmodel->v_xyz[count + 2]); Vector3 light = lightpoint - pointmodelpt; light.normalize(); Vector4 v4_light(light.getX(), light.getY(), light.getZ(), 0); v4_light = projection.getMatrix() * v4_light; Vector3 v3_light(v4_light.getX(), v4_light.getY(), v4_light.getZ()); normal.setX(pointmodel->v_xyz[count + 3]); normal.setY(pointmodel->v_xyz[count + 4]); normal.setZ(pointmodel->v_xyz[count + 5]); normal.normalize(); // Keep light source relative to the world Vector4 v4_normal(normal.getX(), normal.getY(), normal.getZ(), 0); v4_normal = pointmodel->getMatrix() * v4_normal; Vector3 v3_normal(v4_normal.getX(), v4_normal.getY(), v4_normal.getZ()); double nominator = v3_light.dot(v3_normal); // Find the distance between point model point and light point double distx = lightpoint.getX() - pointmodelpt.getX(); double disty = lightpoint.getY() - pointmodelpt.getY(); double distz = lightpoint.getZ() - pointmodelpt.getZ(); double r = sqrt(distx*distx + disty*disty + distz*distz); double denominator = r*r*M_PI; double result = (nominator / denominator) * 200; Vector3 lightcolor(1.0, 0.0, 1.0); Vector3 pointcolor(0.75, 0, 1); Vector3 lightrgb; lightcolor.scale(result); lightrgb = lightcolor.cross(pointcolor); if (shading == 1) { rasterizeVertex(pointmodel->v_xyz[count], pointmodel->v_xyz[count + 1], pointmodel->v_xyz[count + 2], newM, lightrgb.getX(), lightrgb.getY(), lightrgb.getZ()); } else { rasterizeVertex(pointmodel->v_xyz[count], pointmodel->v_xyz[count + 1], pointmodel->v_xyz[count + 2], newM, 1, 1, 1); } count = count + 6; } }
int main(int argc,char* argv[]) { /* Set up the volumetric grid: */ Box gridBox=Box(Point(-32.0,-64.0,16.0),Point(32.0,0.0,80.0)); Index gridSize(256,256,256); Grid grid(gridSize); /* Initialize the grid: */ for(Grid::iterator gIt=grid.begin();gIt!=grid.end();++gIt) *gIt=Voxel(255); /* Carve away the n-th facade from each depth stream file listed on the command line: */ unsigned int facadeIndex=atoi(argv[1]); for(int depthFileIndex=2;depthFileIndex<argc;++depthFileIndex) { try { /* Open the depth file: */ IO::AutoFile depthFile(IO::openFile(argv[depthFileIndex])); depthFile->setEndianness(IO::File::LittleEndian); /* Read the facade projection matrix and the projector transformation: */ Projection depthTransform; depthFile->read<double>(depthTransform.getMatrix().getEntries(),4*4); OGTransform projectorTransform=Misc::Marshaller<OGTransform>::read(*depthFile); /* Calculate the joint projective transformation from 3D world space into depth image space: */ Projection proj=Geometry::invert(Projection(projectorTransform)*depthTransform); /* Create a depth frame reader: */ DepthFrameReader depthFrameReader(*depthFile); /* Read the n-th facade: */ FrameBuffer frame; for(unsigned int i=0;i<facadeIndex;++i) frame=depthFrameReader.readNextFrame(); /* Run a sequence of morphological open and close operators on the frame to fill holes: */ #if 1 for(int i=0;i<8;++i) frame=open(frame); #endif #if 1 for(int i=0;i<8;++i) frame=close(frame); #endif /* Carve the facade out of the grid: */ std::cout<<"Processing depth file "<<argv[depthFileIndex]<<std::flush; double fmax[2]; for(int i=0;i<2;++i) fmax[i]=double(frame.getSize(i)); unsigned short* frameBuffer=static_cast<unsigned short*>(frame.getBuffer()); Size cellSize; for(int i=0;i<3;++i) cellSize[i]=(gridBox.max[i]-gridBox.min[i])/double(gridSize[i]); Index index; Point gridp; gridp[0]=gridBox.min[0]+0.5*cellSize[0]; for(index[0]=0;index[0]<gridSize[0];++index[0],gridp[0]+=cellSize[0]) { gridp[1]=gridBox.min[1]+0.5*cellSize[1]; for(index[1]=0;index[1]<gridSize[1];++index[1],gridp[1]+=cellSize[1]) { gridp[2]=gridBox.min[2]+0.5*cellSize[2]; for(index[2]=0;index[2]<gridSize[2];++index[2],gridp[2]+=cellSize[2]) { /* Project the grid point into the depth frame: */ Point fp=proj.transform(gridp); /* Check if the projected grid point is inside the depth frame: */ if(fp[0]>=0.0&&fp[0]<fmax[0]&&fp[1]>=0.0&&fp[1]<fmax[1]) { /* Check if the grid point is outside the facade: */ int x=int(fp[0]); int y=int(fp[1]); unsigned short depth=frameBuffer[y*frame.getSize(0)+x]; if(fp[2]<double(depth)) grid(index)=Voxel(0); } else grid(index)=Voxel(0); } } std::cout<<'.'<<std::flush; } std::cout<<"done"<<std::endl; } catch(std::runtime_error err) { std::cerr<<"Ignoring depth file "<<argv[depthFileIndex]<<" due to exception "<<err.what()<<std::endl; } catch(...) { std::cerr<<"Ignoring depth file "<<argv[depthFileIndex]<<" due to spurious exception"<<std::endl; } } /* Save the result grid to a volume file: */ IO::AutoFile volFile(IO::openFile("SpaceCarverOut.vol",IO::File::WriteOnly)); volFile->setEndianness(IO::File::BigEndian); for(int i=0;i<3;++i) volFile->write<int>(int(gridSize[i])); volFile->write<int>(0); for(int i=0;i<3;++i) volFile->write<float>((gridBox.max[i]-gridBox.min[i])*double(gridSize[i]-1)/double(gridSize[i])); volFile->write<Voxel>(grid.getArray(),grid.getNumElements()); return 0; }