void TestOctree() { std::vector<vgl_point_3d<double> > Points; Points.push_back(vgl_point_3d<double>(1.0, 0.0, 0.0)); Points.push_back(vgl_point_3d<double>(0.0, 0.0, 0.0)); Points.push_back(vgl_point_3d<double>(0.0, 1.0, 0.0)); std::vector<std::vector<unsigned int> > VertexLists; std::vector<unsigned int> VertexList; VertexList.push_back(0); VertexList.push_back(1); VertexList.push_back(2); VertexLists.push_back(VertexList); Octree Tree; Tree.Build(Points, VertexLists); OrientedPoint Intersection; Ray R(vgl_point_3d<double>(0.5, 0.5, -1.0), vgl_vector_3d<double> (0.0, 0.0, 1.0)); bool intersect = Tree.IntersectRay(R, Intersection); std::cout << "Intersect? " << intersect << std::endl; if(intersect) std::cout << "Intersection: " << Intersection << std::endl; }
void TestOctree(const std::string &Filename) { vtkSmartPointer<vtkXMLPolyDataReader> reader = vtkSmartPointer<vtkXMLPolyDataReader>::New(); reader->SetFileName(Filename.c_str()); reader->Update(); vtkSmartPointer<vtkPolyData> polydata = reader->GetOutput(); Octree Tree; Tree.Build(polydata); OrientedPoint Intersection; //Ray R(vgl_point_3d<double>(0.5, 0.5, -1.0), vgl_vector_3d<double> (0.0, 0.0, 1.0)); Ray R(vgl_point_3d<double>(10.0, 0.0, 0.0), vgl_vector_3d<double> (-1.0, 0.0, 0.0)); bool intersect = Tree.IntersectRay(R, Intersection); std::cout << "Intersect? " << intersect << std::endl; if(intersect) std::cout << "Intersection: " << Intersection << std::endl; }
void Processor::Process(void) { for (int n = 0 ; n < 1 && this->ProcessFrame() ; ++n) { std::cout << "Computing visible voxels..." << std::endl; // Update the visible voxels this->m_Reconstructor.Update(); std::cout << "Computed visible voxels" << std::endl; const unsigned int numVisibleVoxels = this->m_Reconstructor.GetNumVisibleVoxels(); VisibleVoxel* visibleVoxels = this->m_Reconstructor.GetVisibleVoxels(); std::cout << "Number of visible voxels: " << numVisibleVoxels << std::endl; std::cout << "Memory usage: " << (numVisibleVoxels * sizeof(VisibleVoxel)) / 1000000 << "MB" << std::endl; std::cout << "Determining boundaries..." << std::endl; // Find bounds glm::vec3 min = {0.0f, 0.0f, 0.0f}; glm::vec3 max = {0.0f, 0.0f, 0.0f}; glm::vec3 cellSize = {1.0f, 1.0f, 1.0f}; for (int i = 0 ; i < numVisibleVoxels ; ++i) { VisibleVoxel &v = visibleVoxels[i]; min[0] = v.X < min[0] ? v.X : min[0]; max[0] = v.X > max[0] ? v.X : max[0]; min[1] = v.X < min[1] ? v.X : min[1]; max[1] = v.X > max[1] ? v.X : max[1]; min[2] = v.X < min[2] ? v.X : min[2]; max[2] = v.X > max[2] ? v.X : max[2]; } std::cout << "Boundaries are: (" << min[0] << ", " << min[1] << ", " << min[2] << ") -> (" << max[0] << ", " << max[1] << ", " << max[2] << ")" << std::endl; std::cout << "Adding voxels to octree..." << std::endl; Octree *octree = new Octree(glm::vec3(0, 0, 0), max); octree->SetVoxels(visibleVoxels); octree->SetNumVoxels(numVisibleVoxels); std::cout << "Building octree..." << std::endl; std::chrono::system_clock::time_point start = std::chrono::high_resolution_clock::now(); octree->Build(); std::chrono::duration<float> b = std::chrono::system_clock::now().time_since_epoch(); std::chrono::system_clock::time_point end = std::chrono::high_resolution_clock::now(); std::chrono::duration<double> diff = end - start; std::cout << "Spent " << diff.count() * 1000 << " milliseconds" << std::endl; std::cout << "Number of nodes: " << octree->GetNumNodes() << std::endl; std::cout << "Memory usage: " << float(octree->GetNumNodes() * sizeof(OctreeNode)) / 1000000 << "MB" << std::endl; std::cout << "Compressing..." << std::endl; this->m_Compressor->Compress(octree); delete octree; std::cout << "Done, next frame!" << std::endl; } std::cout << "Done processing!" << std::endl; }
void AmbientOcclusionApp::BuildVertexAmbientOcclusion( std::vector<Vertex::AmbientOcclusion>& vertices, const std::vector<UINT>& indices) { UINT vcount = vertices.size(); UINT tcount = indices.size()/3; std::vector<XMFLOAT3> positions(vcount); for(UINT i = 0; i < vcount; ++i) positions[i] = vertices[i].Pos; Octree octree; octree.Build(positions, indices); // For each vertex, count how many triangles contain the vertex. std::vector<int> vertexSharedCount(vcount); for(UINT i = 0; i < tcount; ++i) { UINT i0 = indices[i*3+0]; UINT i1 = indices[i*3+1]; UINT i2 = indices[i*3+2]; XMVECTOR v0 = XMLoadFloat3(&vertices[i0].Pos); XMVECTOR v1 = XMLoadFloat3(&vertices[i1].Pos); XMVECTOR v2 = XMLoadFloat3(&vertices[i2].Pos); XMVECTOR edge0 = v1 - v0; XMVECTOR edge1 = v2 - v0; XMVECTOR normal = XMVector3Normalize(XMVector3Cross(edge0, edge1)); XMVECTOR centroid = (v0 + v1 + v2)/3.0f; // Offset to avoid self intersection. centroid += 0.001f*normal; const int NumSampleRays = 32; float numUnoccluded = 0; for(int j = 0; j < NumSampleRays; ++j) { XMVECTOR randomDir = MathHelper::RandHemisphereUnitVec3(normal); // TODO: Technically we should not count intersections that are far // away as occluding the triangle, but this is OK for demo. if( !octree.RayOctreeIntersect(centroid, randomDir) ) { numUnoccluded++; } } float ambientAccess = numUnoccluded / NumSampleRays; // Average with vertices that share this face. vertices[i0].AmbientAccess += ambientAccess; vertices[i1].AmbientAccess += ambientAccess; vertices[i2].AmbientAccess += ambientAccess; vertexSharedCount[i0]++; vertexSharedCount[i1]++; vertexSharedCount[i2]++; } // Finish average by dividing by the number of samples we added. for(UINT i = 0; i < vcount; ++i) { vertices[i].AmbientAccess /= vertexSharedCount[i]; } }