예제 #1
0
    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;
    }
예제 #2
0
    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;
    }
예제 #3
0
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
}
예제 #4
0
 // 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();
 }
예제 #5
0
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;
}
예제 #6
0
// 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);
}
예제 #7
0
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_);
}
예제 #8
0
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);
        }                                               
	}
}
예제 #9
0
 bool Point3::operator==(const Point3& rhs)
 {
     return this->X() == rhs.X() &&
         this->Y() == rhs.Y() &&
         this->Z() == rhs.Z();
 }
예제 #10
0
파일: BVH.cpp 프로젝트: PeterLValve/ENCORE
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
}