Point3 Point3::operator-(const Point3& rhs) const { Point3 difference; difference.X() = this->X() - rhs.X(); difference.Y() = this->Y() - rhs.Y(); difference.Z() = this->Z() - rhs.Z(); return difference; }
Point3 Point3::operator+(const Point3& rhs) const { Point3 sum; sum.X() = this->X() + rhs.X(); sum.Y() = this->Y() + rhs.Y(); sum.Z() = this->Z() + rhs.Z(); return sum; }
void Kdtree::setGPUParameters( CShader& shader, GPUAccelerationStructureData& accelStructData ) { #ifndef STUB CGparameter& cell_info = shader.GetNamedParameter("cellData0", true); cgGLSetTextureParameter(cell_info, accelStructData.m_CellTexture[0]); //accelStructData.SaveTextureData(); CGparameter& v0 = shader.GetNamedParameter("v0t", true); cgGLSetTextureParameter(v0, accelStructData.m_VertexTexture[0]); CGparameter& v1 = shader.GetNamedParameter("v1t", true); cgGLSetTextureParameter(v1, accelStructData.m_VertexTexture[1]); CGparameter& v2 = shader.GetNamedParameter("v2t", true); cgGLSetTextureParameter(v2, accelStructData.m_VertexTexture[2]); /* CGparameter& maxDepth = shader.GetNamedParameter("maxDepth"); cgGLSetParameter1f( maxDepth, (float) m_MaxDepth ); */ Point3 minPt = m_Bounds.getPos(); Point3 maxPt = minPt + m_Bounds.getSize(); CGparameter& minPoint = shader.GetNamedParameter("gmin"); cgGLSetParameter3f( minPoint, minPt.X(), minPt.Y(), minPt.Z() ); CGparameter& maxPoint = shader.GetNamedParameter("gmax"); cgGLSetParameter3f( maxPoint, maxPt.X(), maxPt.Y(), maxPt.Z() ); CGparameter& maxloop = shader.GetNamedParameter("maxloop"); cgGLSetParameter1f( maxloop, 1000 ); #endif }
// construct a floatVector3 from two 3-dimensional points // vector = end - start Vector3::Vector3(const Point3& start, const Point3& end) { this->X() = end.X() - start.X(); this->Y() = end.Y() - start.Y(); this->Z() = end.Z() - start.Z(); }
int LandmarkCapturePlugin::findScreenNearest(MeshModel &m, int screenX, int screenY) { int idx = 0; double min_dist = 9999; GLdouble resCoords[3]; GLdouble mvMatrix_f[16]; GLdouble prMatrix_f[16]; GLint viewpSize[4]; // GLfloat *dFloat = new GLfloat[depthTexArea]; glGetDoublev(GL_MODELVIEW_MATRIX, mvMatrix_f); glGetDoublev(GL_PROJECTION_MATRIX, prMatrix_f); glGetIntegerv(GL_VIEWPORT, viewpSize); //glReadPixels(0, 0, depthTexSize, depthTexSize, GL_DEPTH_COMPONENT, GL_FLOAT, dFloat); // vector< CMeshO::VertexPointer > vertics = vcg::tri::HalfEdgeTopology<CMeshO> :: getVertices (curFacePtr); // for (int i=0; i<vertics.size(); ++i) // { // // CMeshO::VertexPointer vp = vertics[i]; //// gluProject(vp->P()[0], vp->P()[1], vp->P()[2], //// (const GLdouble *) mvMatrix_f, (const GLdouble *) prMatrix_f, (const GLint *) viewpSize, //// &resCoords[0], &resCoords[1], &resCoords[2] ); //// int x = floor(resCoords[0]); //// int y = floor(resCoords[1]); //// double dist = sqrt(double((x-screenX)*(x-screenX)+(y-screenY)*(y-screenY))); //// if(dist < min_dist){ //// min_dist=dist; //// idx = i; //// } // } //m.cm.selVertVector.push_back(vertics[ret]); for (int i=0; i<3; ++i) { //Point3<CMeshO::ScalarType> &vp = m.cm.vert[i].P(); Point3<float>* pp = &curFacePtr->P(i); gluProject(pp->X(), pp->Y(), pp->Z(), (const GLdouble *) mvMatrix_f, (const GLdouble *) prMatrix_f, (const GLint *) viewpSize, &resCoords[0], &resCoords[1], &resCoords[2] ); int x = floor(resCoords[0]); int y = floor(resCoords[1]); double dist = sqrt(double((x-screenX)*(x-screenX)+(y-screenY)*(y-screenY))); if(dist < min_dist){ min_dist=dist; idx = i; } } int ret = tri::Index(m.cm,curFacePtr->V(idx)); return ret; }
// recursive construction algorithm //void Kdtree::construct(unsigned int fn, const AABB& box, const std::list<unsigned int>& triList, AABB * bounds, unsigned int depth) //void Kdtree::construct(unsigned int fn, AABB& box, std::list<IPrimitive*>& primList, AABB * bounds, unsigned int depth) void Kdtree::construct(unsigned int fn, AABB& box, unsigned int size, unsigned int depth, bool isLeft, unsigned int rIndex, unsigned int pre_size, bool dsize, int tries) { //BSPNode *node = &m_pTree[fn]; //printf("max num: %i\n", m_pTree.max_size()); //m_pTree.assign(BSPNode(), fn); BSPNode *node = &m_pTree[fn]; //unsigned int size = (unsigned int)primList.size(); //std::list<IPrimitive*>::iterator p; //printf("."); // if end condition met // if(abs(previous size - size) <= 3 ... if((int)abs((int)(pre_size-size)) <= 3) { dsize = true; tries++; } else { dsize = false; tries = 0; } if(size <= m_MaxItemPerNode || depth >= m_MaxDepth || (dsize && tries == 3)) { IPrimitive** myList = 0; if(size > 0) myList = new IPrimitive*[size]; //std::list<IPrimitive*>* myList = new std::list<IPrimitive*>; if(depth == 0) { std::list<IPrimitive*>::iterator tit; int i = 0; for(tit = m_PrimList.begin(); tit != m_PrimList.end(); tit++, i++) myList[i] = (*tit); } else if(isLeft) { for(unsigned int i = 0; i < size; i++) myList[i] = leftBOX[i]; } else { for(unsigned int i = 0; i < size; i++) myList[i] = rightBOX[rIndex+i]; } node->initLeaf(size, myList); // increment counts m_TotalTreeTri += size; totalLeaf++; return; // leaf with triangle } // each node must have a split axis and split position int axis = 0; float splitpos = 0; unsigned int i; #ifdef SAH AABB tbox; // build up information of bounding box and edges if(depth == 0) { i = 0; std::list<IPrimitive*>::iterator tit; for(tit = m_PrimList.begin(); tit != m_PrimList.end(); tit++, i++) { tbox = (*tit)->getAABB(); AABB* mybox = &(box.Intersection(tbox)); // get intersection of triangle box + bounding box of this node Point3 minp = mybox->getPos(); Point3 maxp = minp + mybox->getSize(); // add x position to the list edge[0][i*2].set(minp.X(), (*tit), true); edge[0][i*2+1].set(maxp.X(), (*tit), false); // add y edge[1][i*2].set(minp.Y(), (*tit), true); edge[1][i*2+1].set(maxp.Y(), (*tit), false); // add z edge[2][i*2].set(minp.Z(), (*tit), true); edge[2][i*2+1].set(maxp.Z(), (*tit), false); } } else if(isLeft) { for(i = 0; i < size; i++) { tbox = leftBOX[i]->getAABB(); AABB* mybox = &(box.Intersection(tbox)); // get intersection of triangle box + bounding box of this node Point3 minp = mybox->getPos(); Point3 maxp = minp + mybox->getSize(); // add x position to the list edge[0][i*2].set(minp.X(), 0, true); edge[0][i*2+1].set(maxp.X(), 0, false); // add y edge[1][i*2].set(minp.Y(), 0, true); edge[1][i*2+1].set(maxp.Y(), 0, false); // add z edge[2][i*2].set(minp.Z(), 0, true); edge[2][i*2+1].set(maxp.Z(), 0, false); } } else { for(i = 0; i < size; i++) { unsigned int tIndex = rIndex + i; tbox = rightBOX[tIndex]->getAABB(); AABB* mybox = &(box.Intersection(tbox)); // get intersection of triangle box + bounding box of this node Point3 minp = mybox->getPos(); Point3 maxp = minp + mybox->getSize(); // add x position to the list edge[0][i*2].set(minp.X(), 0, true); edge[0][i*2+1].set(maxp.X(), 0, false); // add y edge[1][i*2].set(minp.Y(), 0, true); edge[1][i*2+1].set(maxp.Y(), 0, false); // add z edge[2][i*2].set(minp.Z(), 0, true); edge[2][i*2+1].set(maxp.Z(), 0, false); } } // calculate SAH and split position float cost = INFINITY; sahSplit(axis, splitpos, cost, size, box, edge); // figure out best split /* // old stuff if(!bounds) bounds = new AABB[size]; // create a container for all triangle bbox for( i = 0; i < 3; i++ ) { edge[i] = new boundedge[2*size]; } AABB tbox; // build up information of bounding box and edges for(p = primList.begin(), i = 0; p != primList.end(); p++, i++) { //AABB* tbox = &(*p)->getAABB(); if(depth == 0) { //unsigned int index = (*uit); //unsigned int model = getTrueIndex(index); //Triangle tt = myScene->getModel(model)->getTriangle(index); // tbox = new AABB(tt); // bounds[i] = (*tbox); //IPrimitive p; tbox = (*p)->getAABB(); bounds[i] = tbox; } else { tbox = bounds[i]; } AABB* mybox = &(box.Intersection(tbox)); // get intersection of triangle box + bounding box of this node Point3 minp = mybox->getPos(); Point3 maxp = minp + mybox->getSize(); // add x position to the list edge[0][i*2] = boundedge(minp.X(), (*p), true); edge[0][i*2+1] = boundedge(maxp.X(), (*p), false); // add y edge[1][i*2] = boundedge(minp.Y(), (*p), true); edge[1][i*2+1] = boundedge(maxp.Y(), (*p), false); // add z edge[2][i*2] = boundedge(minp.Z(), (*p), true); edge[2][i*2+1] = boundedge(maxp.Z(), (*p), false); } // calculate SAH and split position float cost = INFINITY; sahSplit(axis, splitpos, cost, size, box, edge); // figure out best split */ // no good(better) split position can be found if(cost == INFINITY) { IPrimitive** myList = 0; if(size > 0) myList = new IPrimitive*[size]; //std::list<IPrimitive*>* myList = new std::list<IPrimitive*>; if(depth == 0) { std::list<IPrimitive*>::iterator tit; int i = 0; for(tit = m_PrimList.begin(); tit != m_PrimList.end(); tit++, i++) myList[i] = (*tit); } else if(isLeft) { for(unsigned int i = 0; i < size; i++) myList[i] = leftBOX[i]; } else { for(unsigned int i = 0; i < size; i++) myList[i] = rightBOX[rIndex+i]; } node->initLeaf(size, myList); // increment counts m_TotalTreeTri += size; totalLeaf++; return; // leaf with triangle } #else axis = depth % 3; Point3 minp = box.getPos(); Point3 maxp = minp + box.getSize(); splitpos = (minp[axis] + maxp[axis])/2; #endif // a split position was calculated, // so create left and right nodes m_NodeUsed += 2; //if(m_NodeUsed == 21) // printf("what"); //m_pTree.push_back(BSPNode()); //m_pTree.push_back(BSPNode()); // if we need more node if(m_NodeUsed >= m_MaxNode/* || rSize >= m_MaxNode*3*/) { try { BSPNode *tt = new BSPNode[m_MaxNode*2]; memcpy(tt, m_pTree, m_MaxNode*sizeof(BSPNode)); free(m_pTree); m_pTree = tt; node = &m_pTree[fn]; m_MaxNode *= 2; } catch(std::bad_alloc&) { deleteTree(); printf("no memory\n"); return; } } // figure out left voxel and right voxel Point3 rminp = box.getPos(); Point3 lmaxp = box.getPos() + box.getSize(); rminp[axis] = splitpos; lmaxp[axis] = splitpos; AABB lvoxel( box.getPos(), lmaxp ); AABB rvoxel( rminp, box.getPos() + box.getSize() ); int a,b; int rcIndex; // right index pass down to child bool hit = false; a = b = 0; if(depth == 0) // special case at depth 0, triangle information are still in the list { std::list<IPrimitive*>::iterator tit; for(tit = m_PrimList.begin(); tit != m_PrimList.end(); tit++) { if( lvoxel.Intersect( (*tit)->getAABB() ) ) { leftBOX[a] = (*tit);//.push_back(&(*tit)); a++; hit = true; } if( rvoxel.Intersect( (*tit)->getAABB() ) ) { rightBOX.push_back((*tit)); //rightBOX[rSize+b] = &(*tit);//.push_back(&(*tit)); b++; hit = true; } if(!hit) { leftBOX[a] = (*tit); a++; rightBOX.push_back((*tit)); b++; } hit = false; } rcIndex = rSize; rSize += b; } else { if(isLeft) // use left BOX , so data is overwritten { for(i = 0; i < size; i++) { if( lvoxel.Intersect( leftBOX[i]->getAABB() ) ) { leftBOX[a] = leftBOX[i];//.push_back(&(*tit)); hit = true; a++; } if( rvoxel.Intersect( leftBOX[i]->getAABB() ) ) { rightBOX.push_back(leftBOX[i]); //rightBOX[rSize+b] = primList[i];//.push_back(&(*tit)); b++; hit = true; } if(!hit) { leftBOX[a] = leftBOX[i]; a++; rightBOX.push_back(leftBOX[i]); b++; } hit = false; } } else // use right BOX, so data is appended { unsigned int tSize = rIndex+size; for(i = rIndex; i < tSize; i++) { if( lvoxel.Intersect( rightBOX[i]->getAABB() ) )//primList[i]->getAABB() ) ) { leftBOX[a] = rightBOX[i];//primList[i];//.push_back(&(*tit)); a++; hit = true; } if( rvoxel.Intersect( rightBOX[i]->getAABB()/*primList[i]->getAABB()*/ ) ) { rightBOX.push_back(rightBOX[i]); //rightBOX[rSize+b] = rightBOX[i];//primList[i];//.push_back(&(*tit)); b++; hit = true; } if(!hit) { leftBOX[a] = rightBOX[i]; a++; rightBOX.push_back(rightBOX[i]); b++; } hit = false; } } rcIndex = rSize; rSize += b; } // old stuff /* // distribute primitives std::list<IPrimitive*> leftList; std::list<IPrimitive*> rightList; for(p = primList.begin(); p != primList.end(); p++) { //i/f(fn == 20) // printf("why\n"); if( lvoxel.Intersect( (*p)->getAABB() ) ) { leftList.push_back(*p); } if( rvoxel.Intersect( (*p)->getAABB() ) ) { rightList.push_back(*p); } } */ // produce branch node->initNode(axis, splitpos); node->leftChild = m_NodeUsed-2; unsigned int left = node->leftChild; construct(left, lvoxel, a, depth+1, 1, 0, size, dsize, tries); construct(left+1, rvoxel, b, depth+1, 0, rcIndex, size, dsize, tries); }
BoundingBox BoundingBox::Translate(Point3 const& point) const { return BoundingBox(point.X() + minX_, point.X() + maxX_, point.Y() + minY_, point.Y() + maxY_, point.Z() + minZ_, point.Z() + maxZ_); }
void PhotonMap::GetNearestNPhotons( const int N, float rSquared, const Point3& location, const Vector3& normal, const int minIndex, const int maxIndex, vector<PhotonDistPair>& nearest) { if(maxIndex - minIndex >= 0) { int nodeIndex = (maxIndex + minIndex) / 2; // CONSIDER ADDING THIS NODE TO PHOTON HEAP const Photon* p = &m_photons[nodeIndex]; float x = location.X() - p->Position().X(); float y = location.Y() - p->Position().Y(); float z = location.Z() - p->Position().Z(); float distSquared = (x*x)+(y*y)+(z*z); if(distSquared < rSquared && (IGNORE_NORMAL || p->SurfNormal() == normal)) { if((int)nearest.size() < N - 1) { nearest.push_back(PhotonDistPair(p, distSquared)); } else if((int)nearest.size() == N - 1) { nearest.push_back(PhotonDistPair(p, distSquared)); std::make_heap(nearest.begin(), nearest.end()); rSquared = nearest[0].m_Distance; } else { nearest.push_back(PhotonDistPair(p, distSquared)); std::make_heap(nearest.begin(), nearest.end()); if(nearest.size() > N) { std::pop_heap(nearest.begin(), nearest.end()); nearest.pop_back(); } rSquared = nearest[0].m_Distance; } } AXIS plane = m_photons[nodeIndex].Plane(); float distanceToPlane = location[plane] - m_photons[nodeIndex].Position()[plane]; //// SEARCH PHOTON MAP if(distanceToPlane*distanceToPlane > rSquared) { if(distanceToPlane > 0) { // check right tree GetNearestNPhotons(N, rSquared, location, normal, nodeIndex+1, maxIndex, nearest); } else { // check left tree GetNearestNPhotons(N, rSquared, location, normal, minIndex, nodeIndex-1, nearest); } } else { // check both GetNearestNPhotons(N, rSquared, location, normal, minIndex, nodeIndex-1, nearest); GetNearestNPhotons(N, rSquared, location, normal, nodeIndex+1, maxIndex, nearest); } } }
bool Point3::operator==(const Point3& rhs) { return this->X() == rhs.X() && this->Y() == rhs.Y() && this->Z() == rhs.Z(); }
void Bvh::buildGPU(std::list<IModel*> &modelList, std::list<Triangle*> &triangleList, GPUAccelerationStructureData& l_pASD ) { #ifndef STUB l_pASD.setTraversalShaderFilename( "shaders\\BVH.cg" ); #ifdef USEUPDATE if(bTree) update(modelList); else build(modelList); #else build( modelList ); #endif // need enough room for the nodes and the triangles l_pASD.setVertexCount( m_NodeUsed * 3 ); l_pASD.setNormalCount( m_NodeUsed * 3 ); l_pASD.setMaterialCount( m_NodeUsed * 3 ); float* pV0 = l_pASD.m_pVertex0Array; float* pV1 = l_pASD.m_pVertex1Array; float* pV2 = l_pASD.m_pVertex2Array; float* pN0 = l_pASD.m_pNormal0Array; float* pN1 = l_pASD.m_pNormal1Array; float* pN2 = l_pASD.m_pNormal2Array; float* pM = l_pASD.m_pMaterial0Array; std::deque<bvhNode*> todo; bvhNode* current = NULL; todo.push_back( &bTree[0] ); int nProcessedNodes = 0; // while( nProcessedNodes < ( m_NodeUsed + triangleList.size() ) ) while ( !todo.empty() ) // while there are nodes to process { // get the first node to process and then remove it from the queue current = todo[0]; todo.pop_front(); if( current->extra == 1 ) // is leaf { std::list< Triangle* >* pTris = current->pTris->getNewTesselation(); std::list< Triangle* >::iterator t; for ( t = pTris->begin(); t != pTris->end(); t++ ) { Triangle* tri = *t; Point3 v0 = tri->getVertex0()->getCoordinates(); Point3 v1 = tri->getVertex1()->getCoordinates(); Point3 v2 = tri->getVertex2()->getCoordinates(); Vector3 n0 = tri->getVertex0()->getNormal(); Vector3 n1 = tri->getVertex1()->getNormal(); Vector3 n2 = tri->getVertex2()->getNormal(); // vertices *pV0 = v0.X(); ++pV0; *pV0 = v0.Y(); ++pV0; *pV0 = v0.Z(); ++pV0; *pV0 = 0.0f; ++pV0; // 0 = triangle node *pV1 = v1.X(); ++pV1; *pV1 = v1.Y(); ++pV1; *pV1 = v1.Z(); ++pV1; *pV1 = 1.0f; ++pV1;// just go to the next index *pV2 = v2.X(); ++pV2; *pV2 = v2.Y(); ++pV2; *pV2 = v2.Z(); ++pV2; *pV2 = 0; ++pV2; // TODO: Material Pointer // normals *pN0 = n0.X(); ++pN0; *pN0 = n0.Y(); ++pN0; *pN0 = n0.Z(); ++pN0; *pN0 = 0.0f; ++pN0; *pN1 = n1.X(); ++pN1; *pN1 = n1.Y(); ++pN1; *pN1 = n1.Z(); ++pN1; *pN1 = 0.0f; ++pN1; *pN2 = n2.X(); ++pN2; *pN2 = n2.Y(); ++pN2; *pN2 = n2.Z(); ++pN2; *pN2 = 0.0f; ++pN2; encore::Color diffuse = tri->getMaterial()->GetDiffuse(); float spec = tri->getMaterial()->GetSpecularExponent(); *pM = diffuse.R(); ++pM; *pM = diffuse.G(); ++pM; *pM = diffuse.B(); ++pM; *pM = spec; ++pM; delete *t; *t = NULL; // increase node count ++nProcessedNodes; } pTris->clear(); if(pTris) delete pTris; pTris = NULL; } else // is node { unsigned int left = current->leftChild; unsigned int right = left+1; // add child nodes to the queue // todo.push_back( &bTree[left] ); // todo.push_back( &bTree[right] ); // push the right one first so that we pop the left one first todo.push_front( &bTree[right] ); todo.push_front( &bTree[left] ); Point3 bMin = current->bound.getPos(); Point3 bMax = bMin + current->bound.getSize(); *pV0 = bMin.X(); ++pV0; *pV0 = bMin.Y(); ++pV0; *pV0 = bMin.Z(); ++pV0; *pV0 = 1; ++pV0; // this is an intermediate node *pV1 = bMax.X(); ++pV1; *pV1 = bMax.Y(); ++pV1; *pV1 = bMax.Z(); ++pV1; *pV1 = (float)current->escapeOffset; ++pV1;//TODO just go to the next node or exit? // if we miss the bounding box, we might just quit... *pV2 = 0; ++pV2; // No data stored here *pV2 = 0; ++pV2; *pV2 = 0; ++pV2; *pV2 = 0; ++pV2; // still need to write out fake normals to keep index aligned *pN0 = 0.0f; ++pN0; *pN0 = 0.0f; ++pN0; *pN0 = 0.0f; ++pN0; *pN0 = 0.0f; ++pN0; *pN1 = 0.0f; ++pN1; *pN1 = 0.0f; ++pN1; *pN1 = 0.0f; ++pN1; *pN1 = 0.0f; ++pN1; *pN2 = 0.0f; ++pN2; *pN2 = 0.0f; ++pN2; *pN2 = 0.0f; ++pN2; *pN2 = 0.0f; ++pN2; *pM = 0.0f; ++pM; *pM = 0.0f; ++pM; *pM = 0.0f; ++pM; *pM = 0.0f; ++pM; // increase node count ++nProcessedNodes; } } m_NodeUsed = nProcessedNodes; #endif }