Exemple #1
0
void ORRKdTree::extendTreeByOneLevel(char* extdir)
{
	int i, newaxis, dim = this->getDimension();
	Box newbox(dim);
	KdTreeNode *newroot = NULL, *newchild = NULL;
	double boxsize;

	for ( i = 0 ; i < dim ; ++i )
	{
		newaxis = mRoot->getPreviousAxis();
		newbox.copyfrom(mRoot->getSpace());
		boxsize = newbox.getDiameter(newaxis);

		if ( extdir[newaxis] == -1 )
		{
			// Fix the box of the new root and create the root. Extend the lower bound of the box
			newbox.mIntervals[newaxis][0] -= boxsize;
			newroot = new KdTreeNode(newaxis, NULL/*no parent*/, newbox, NULL);
			// Fix the box of the new child and create the new child
			newbox.mIntervals[newaxis][1] = mRoot->getLowerBoxBound(newaxis);
			newchild = new KdTreeNode(mRoot->getAxis(), newroot/*the parent*/, newbox, NULL);
			// Now fix the children of the new root
			newroot->setChildren(newchild, mRoot);
		}
		else if ( extdir[newaxis] == 1 )
		{
			// Fix the box of the new root and create the root. Extend the upper bound of the box
			newbox.mIntervals[newaxis][1] += boxsize;
			newroot = new KdTreeNode(newaxis, NULL/*no parent*/, newbox, NULL);
			// Fix the box of the new child and create the new child
			newbox.mIntervals[newaxis][0] = mRoot->getUpperBoxBound(newaxis);
			newchild = new KdTreeNode(mRoot->getAxis(), newroot/*the parent*/, newbox, NULL);
			// Now fix the children of the new root
			newroot->setChildren(mRoot, newchild);
		}
		else
		{
			fprintf(stderr, "ERROR in 'ORRKdTree::%s()': extension direction for the %i-th axis is %i! Can not extend the tree!\n",
					__func__, newaxis, extdir[newaxis]);
			fflush(stdout);
			return;
		}

		// Set the new root as the parent of the old one
		mRoot->setParent(newroot);
		// Save the new root
		mRoot = newroot;
	}

	// Now we have one level more
	++mNumOfTreeLevels;
}
Exemple #2
0
void dumpKdTreeInfo( KdTree* tree)
{
    std::ofstream out("./output/kdtree.txt");
    if(! out.is_open() )
    {
        cerr<<"Cannot open file kdtree.txt"<<endl;
        return;
    }
    if( !tree )
    {
        cerr<<"Tree is not initialized"<<endl;
        return;
    }
    KdTreeNode* root = tree->getRoot();
    AABB extends = root->getAABB();
    out<<"Extends: "<<endl<<extends.getPos().x<<" "<<extends.getPos().y<<" "
      <<extends.getPos().z<<endl;
    out<<(extends.getPos()+extends.getSize()).x<<" "
      <<(extends.getPos()+extends.getSize()).y<<" "
        <<(extends.getPos()+extends.getSize()).z<<endl;

    dumpKdTreeInfoLeaf( root, out, 0 );
}
Exemple #3
0
void ireon::kd_tree::KdTree<T>::subdivide( KdTreeNode<T>* node, const aabb& box, int depth, int a_Prims )
{
	// recycle used split list nodes
	//add sPool_ at end sList_
	if (sList_)
	{
		SplitList* list = sList_;
		while (list->next) 
			list = list->next;
		list->next = sPool_;
		sPool_ = sList_, sList_ = 0;
	}

	// determine split axis
	Vector3 s = box.getSize();
	if ((s.x >= s.y) && (s.x >= s.z)) 
		node->setAxis( 0 );
	else if ((s.y >= s.x) && (s.y >= s.z))
		node->setAxis( 1 );
	
	int axis = node->getAxis();
	
	// make a list of the split position candidates
	ObjectList<T>* l = node->getList();
	real p1, p2;
	real pos1 = box.getPos().val[axis];
	real pos2 = box.getPos().val[axis] + box.getSize().val[axis];
	bool* pright = new bool[a_Prims];
	float* eleft = new float[a_Prims], *eright = new float[a_Prims];
	T** parray = new T*[a_Prims];
	
	real etleft, etright;
	int aidx = 0;
	while (l)
	{
		T* p = parray[aidx] = l->getPrimitive();
		pright[aidx] = true;

		etleft =  eleft[aidx];
		etright = eright[aidx];
		p->calculateRange( etleft, etright, axis );
		eleft[aidx] = (float)etleft;
		eright[aidx] = (float)etright;
		aidx++;
		for ( int i = 0; i < 3; i++ )
		{
			p1 = (float)p->vertice( i )->cell[axis];
			if ((p1 >= pos1) && (p1 <= pos2)) 
				insertSplitPos( p1 );
		}
		
		l = l->getNext();
	}
	// determine n1count / n2count for each split position
	aabb b1, b2, b3 = box, b4 = box;
	SplitList* splist = sList_;
	float b3p1 = b3.getPos().val[axis];
	float b4p2 = b4.getPos().val[axis] + b4.getSize().val[axis];
	Vector3 foo;
	while (splist)
	{
		foo = b4.getPos();
		foo.val[axis] = splist->splitpos;
		b4.setPos(foo);
		foo = b4.getSize();
		foo.val[axis] = pos2 - splist->splitpos;
		b4.setSize(foo);
		foo = b3.getSize();
		foo.val[axis] = splist->splitpos - pos1;
		b3.setSize(foo);
		
		float b3p2 = b3.getPos().val[axis] + b3.getSize().val[axis];
		float b4p1 = b4.getPos().val[axis];
		for ( int i = 0; i < a_Prims; i++ ) if (pright[i])
		{
			T* p = parray[i];
			if ((eleft[i] <= b3p2) && (eright[i] >= b3p1))
				if (p->intersectBox( b3 )) splist->n1count++;
			if ((eleft[i] <= b4p2) && (eright[i] >= b4p1))
				if (p->intersectBox( b4 )) splist->n2count++; else pright[i] = false;
		}
		else splist->n1count++;
		splist = splist->next;
	}
	delete[] pright;
	// calculate surface area for current node
	real SAV = 0.5f / (box.w() * box.d() + box.w() * box.h() + box.d() * box.h());
	// calculate cost for not splitting
	real Cleaf = a_Prims * 1.0f;
	// determine optimal split plane position
	splist = sList_;
	real lowcost = 10000;
	real bestpos = 0;
	while (splist)
	{
		// calculate child node extends
		foo = b4.getPos();
		foo.val[axis] = splist->splitpos;
		b4.setPos(foo);
		foo = b4.getSize();
		foo.val[axis] = pos2 - splist->splitpos;
		b4.setSize(foo);
		foo = b3.getSize();
		foo.val[axis] = splist->splitpos - pos1;
		b3.setSize(foo);

		// calculate child node cost
		real SA1 = 2 * (b3.w() * b3.d() + b3.w() * b3.h() + b3.d() * b3.h());
		real SA2 = 2 * (b4.w() * b4.d() + b4.w() * b4.h() + b4.d() * b4.h());
		real splitcost = 0.3f + 1.0f * (SA1 * SAV * splist->n1count + SA2 * SAV * splist->n2count);
		// update best cost tracking variables
		if (splitcost < lowcost)
		{
			lowcost = splitcost;
			bestpos = splist->splitpos;
			b1 = b3, b2 = b4;
		}
		splist = splist->next;
	}
	if (lowcost > Cleaf) 
	{
		delete[] eleft;
		delete[] eright;
		delete[] parray;
		return;
	}
		node->setSplitPos( bestpos );
	// construct child nodes
	KdTreeNode<T>* left = s_MManager->NewKdTreeNodePair();
	int n1count = 0, n2count = 0, total = 0;
	// assign primitives to both sides
	float b1p1 = b1.getPos().val[axis];
	float b2p2 = b2.getPos().val[axis] + b2.getSize().val[axis];
	float b1p2 = b1.getPos().val[axis] + b1.getSize().val[axis];
	float b2p1 = b2.getPos().val[axis];
	for ( int i = 0; i < a_Prims; i++ )
	{
		T* p = parray[i];
		total++;
		if ((eleft[i] <= b1p2) && (eright[i] >= b1p1)) if (p->intersectBox( b1 )) 
		{
			left->add( p );
			n1count++;
		}
		if ((eleft[i] <= b2p2) && (eright[i] >= b2p1)) if (p->intersectBox( b2 )) 
		{
			(left + 1)->add( p );
			n2count++;
		}
	}
	delete[] eleft;
	delete[] eright;
	delete[] parray;
	
	s_MManager->FreeObjectList( node->getList() );
	
	node->setLeft( left );
	node->setLeaf( false );
	if (depth < MAXTREEDEPTH)
	{
		if (n1count > 2) subdivide( left, b1, depth + 1, n1count );
		if (n2count > 2) subdivide( left + 1, b2, depth + 1, n2count );
	}
}
Exemple #4
0
//------------------------------------------------------------------------
bool KdTreeNode::intersect(const Ray& ray, float min, float max, float* pDistance, const Sphere** ppSphere) const
{
	ASSERT(pDistance != nullptr && ppSphere != nullptr);

	// Case 1: leaf has been reached
	if (isLeaf())
	{
		if (m_Spheres->size() == 0)
		{
			return false;
		}

		*pDistance = std::numeric_limits<float>::max();
		bool success = false;

		for (auto it = m_Spheres->begin(); it != m_Spheres->end(); it++)
		{
			const Sphere& s = **it;
			float d;

			if (s.intersect(ray, &d))
			{
				if (d < *pDistance && d < max)
				{
					success = true;
					*pDistance = d;
					*ppSphere = &s;
				}
			}
		}

		return success;
	}
	
	float dirAxis = ray.getDirection().get(m_Axis);
	float tSplit = ray.planeIntersectionDistance(m_SplitDistance, m_Axis);

	KdTreeNode* minNode; // Node the closest  to the ray origin
	KdTreeNode* maxNode; // Node the furthest to the ray origin
	if (dirAxis > 0)
	{
		minNode = getA();
		maxNode = getB();
	}
	else
	{
		minNode = getB();
		maxNode = getA();
	}

	// Case 2: ray is parallel to split plane
	if (dirAxis == 0)
	{
		float originPlane = ray.getOrigin().get(m_Axis);

		if (originPlane < m_SplitDistance)
		{
			return getA()->intersect(ray, min, max, pDistance, ppSphere);
		}
		if (m_SplitDistance < originPlane)
		{
			return getB()->intersect(ray, min, max, pDistance, ppSphere);
		}

		return false;
	}

	// Case 3: ray only crosses min node
	if (max < tSplit)
	{
		return minNode->intersect(ray, min, max, pDistance, ppSphere);
	}

	// Case 4: ray only crosses max node
	if (tSplit < min)
	{
		return maxNode->intersect(ray, min, max, pDistance, ppSphere);
	}

	// Case 5: ray crosses both nodes
	if (minNode->intersect(ray, min, tSplit, pDistance, ppSphere))
	{
		return true;
	}

	return maxNode->intersect(ray, tSplit, max, pDistance, ppSphere);
}
Exemple #5
0
void KdTree::subdivide( KdTreeNode *node, AABB aabb, int depth, int objCount )
{
    // recycle used split nodes
    if (m_splitList)
    {
        SplitNode* list = m_splitList;
        while (list->next)
            list = list->next;
        list->next = m_splitPool;
        m_splitPool = m_splitList;
        // Reset the split list
        m_splitList = 0;
    }

    // Find the split axis, we split the aixs of maximum size
    Vector3 s = aabb.getSize(); // Get the size
    int axis;
    if ( (s.x >= s.y) && (s.x >= s.z) ) // Split x
        axis = 0;
    else if ( (s.y >= s.x) && (s.y >= s.z) ) // Split y
       axis = 1; // y axis
    else // Split z
        axis = 2;  // z axis
    node->setAxis( axis );

    // make a list of the split position candidates
    ObjectNode* objNodes = node->getObjectList();

    float posStart = aabb.getPos().xyz[axis];
    float posEnd = aabb.getPos().xyz[axis] + aabb.getSize().xyz[axis];
    float* eleft = new float[objCount];
    float* eright = new float[objCount];
    SceneObject** parray = new SceneObject*[objCount];
    int id = 0;
    while (objNodes)
    {
        SceneObject* p = parray[id] = objNodes->getObject();
        calculateAABBRange( p->m_boundingBox, eleft[id], eright[id], axis );

        // Insert all of the split positions
        if( eleft[id] >= posStart && eleft[id] <= posEnd )
            insertSplitPos( eleft[id] );
        if( eright[id] >= posStart && eright[id] <= posEnd )
            insertSplitPos( eright[id] );
        id++;
        // Get next one
        objNodes = objNodes->getNext();
    }
    // Calculate left count and right count for each split choice
    AABB leftAABB, rightAABB;
    // Need to do this to give the initial value of axis other than the axis we gonna split
    AABB leftAABBTmp = aabb, rightAABBTmp = aabb;
    SplitNode* splist = m_splitList;
    float leftAABBStartTmp = aabb.getPos().xyz[axis];
    float rightAABBEndTmp = aabb.getPos().xyz[axis] + aabb.getSize().xyz[axis];
    while ( splist )
    {
        rightAABBTmp.getPos().xyz[axis] = splist->splitPos;
        rightAABBTmp.getSize().xyz[axis] = posEnd - splist->splitPos;
        leftAABBTmp.getSize().xyz[axis] = splist->splitPos - posStart;

        //SUB: float leftAABBEndTmp =splist->splitPos;
        float leftAABBEndTmp = leftAABBTmp.getPos().xyz[axis] + leftAABBTmp.getSize().xyz[axis];
        //SUB:splist->splitPos;
        float rightAABBStartTmp = rightAABBTmp.getPos().xyz[axis];

        /*
         *Intersect problematic
         */
        for ( int i = 0; i < objCount; i++ )
        {
                SceneObject* p = parray[i];
                // SUB
                if ((eleft[i] <= leftAABBEndTmp) && (eright[i] >= leftAABBStartTmp))
                {
                    if (p->m_boundingBox.intersectAABB(  leftAABBTmp  ))
                        splist->leftCount++;
                }
                // SUB
                if ((eleft[i] <= rightAABBEndTmp) && (eright[i] >= rightAABBStartTmp ))
                {
                    if (p->m_boundingBox.intersectAABB( rightAABBTmp ))
                        splist->rightCount++;
                }
        }
        splist = splist->next;
    }
    // calculate surface area for current node
    float SAV = 1.f / calculateSA( aabb );
    // calculate cost for not splitting
    float costNoSplit = objCount;
    // determine optimal split plane position
    splist = m_splitList;
    float min = POS_INF;
    float bestpos = 0;

    leftAABBTmp = rightAABBTmp = aabb;
    while (splist)
    {
        // calculate child node extends
         rightAABBTmp.getPos().xyz[axis] = splist->splitPos;
         rightAABBTmp.getSize().xyz[axis] = posEnd - splist->splitPos;
        leftAABBTmp.getSize().xyz[axis] = splist->splitPos - posStart;
        // calculate child node cost
        float SA1 = calculateSA( leftAABBTmp );
        float SA2 = calculateSA( rightAABBTmp );
        float splitcost = 0.3f + 1.0f * (SA1 * SAV * splist->leftCount + SA2 * SAV * splist->rightCount );
        // update best cost tracking variables
        if (splitcost < min)
        {
            min = splitcost;
            bestpos = splist->splitPos;

            // Record the best left AABB and right AABB
            leftAABB = leftAABBTmp;
            rightAABB =  rightAABBTmp;
        }
        splist = splist->next;
    }

    if ( min > costNoSplit)
    {
        node->setLeaf( true );
        return;
    }

    node->setSplitPos( bestpos );
    // construct child nodes
    KdTreeNode* left = newKdTreeNodePair();
    KdTreeNode* right = left + 1;

    // COF: total, useless?
    int leftCount, rightCount, totalCount;
    leftCount = rightCount = totalCount = 0;
    // assign primitives to both sides
    float leftAABBStart = leftAABB.getPos().xyz[axis];
    float leftAABBEnd = leftAABB.getPos().xyz[axis] + leftAABB.getSize().xyz[axis];
    float rightAABBStart = rightAABB.getPos().xyz[axis];
    float rightAABBEnd = rightAABB.getPos().xyz[axis] + rightAABB.getSize().xyz[axis];

    for ( int i = 0; i < objCount; i++ )
    {
        SceneObject* p = parray[i];
        totalCount++;

        // TIG
        if ((eleft[i] <= leftAABBEnd) && (eright[i] >=  leftAABBStart))
        {
            if (p->m_boundingBox.intersectAABB( leftAABB ))
            {
                left->add( p, this );
                leftCount++;
            }
        }

        // TIG
        if ((eleft[i] <=  rightAABBEnd) && (eright[i] >= rightAABBStart ))
        {
            if (p->m_boundingBox.intersectAABB( rightAABB ))
            {
                right->add( p, this );
                rightCount++;
            }
        }
    }

    // Release
    if( eleft )
        delete []eleft;
    if( eright )
        delete []eright;
    if( parray )
        delete []parray;

    left->setAABB( leftAABB );
    right->setAABB( rightAABB );
    node->setLeft( left );
    node->setRight(right);
    node->setLeaf( false );
    if (depth < MAX_TREE_DEPTH)
    {
        if (leftCount > 2)
            subdivide( left, leftAABB, depth + 1, leftCount);
        if (rightCount > 2)
            subdivide( right, rightAABB, depth + 1, rightCount );
    }
}
Exemple #6
0
/*
inline float getAxisElem4( cl_float4 vec, int axis )
{
    if( axis == 0 )
        return vec.x;
    else if( axis == 1 )
        return vec.y;
    else if( axis == 2 )
        return vec.z;
    else
        return -1;
}

bool checkRange( const cl_float4 intersect, const cl_float4 range, const int axis )
{
    bool result = false;
    switch( axis )
    {
    case 0: // X axis range
        if( intersect.y >= range.x && intersect.y <= range.y &&
                intersect.z >= range.z && intersect.z <= range.w )
          result = true;
        break;
    case 1: // Y axis range
        if( intersect.x >= range.x && intersect.x <= range.y &&
                intersect.z >= range.z && intersect.z <= range.w )
          result = true;
        break;
    case 2: // Z axis range
        if( intersect.x >= range.x && intersect.x <= range.y &&
                intersect.y >= range.z && intersect.y <= range.w )
          result = true;
        break;
    default:
        break;
    }
    return result;
}

float dot( cl_float3 f1, cl_float3 f2 )
{
    return f1.x*f2.x + f1.y*f2.y + f1.z*f2.z;
}

float doIntersectPlane( cl_float3 point, cl_float3 norm, cl_float4 eyePos, cl_float4 d)
{

    float t = -1;
    float denominator = (norm.x*d.x+norm.y*d.y+norm.z*d.z);
    if(fabs(denominator)>EPSILON)
    {
        cl_float3 eye3;
        eye3.x  =eyePos.x;
        eye3.y = eyePos.y;
        eye3.z = eyePos.z;
        t = (dot(norm, point)-dot(norm, eye3))/(denominator);
    }

    return t;
}

void doIntersectRayKdBox2(
        const cl_float4 eyePos,
        const cl_float4 d,
        float* near,
        float* far,
        const cl_float3 boxStart,
        const cl_float3 boxSize
    )
{
    *near = -1;
    *far = -1;
    cl_float3 start = boxStart;
    cl_float3 end;
    end .x = boxStart.x + boxSize.x;
    end .y = boxStart.y + boxSize.y;
    end .z = boxStart.z + boxSize.z;

    cl_float3 norm[3];
//    = {(cl_float3)(1,0,0), (cl_float3)(0,1,0), (cl_float3)(0,0,1) };
    norm[0].x = 1, norm[0].y = 0, norm[0].z = 0;
    norm[1].x = 0, norm[1].y = 1, norm[1].z = 0;
    norm[2].x = 0, norm[2].y = 0, norm[2].z = 1;

    cl_float4 range[3];
    range[0].x = start.y, range[0].y = end.y, range[0].z = start.z, range[0].w = end.z;
     range[1].x = start.x, range[1].y = end.x, range[1].z = start.z, range[1].w = end.z;
      range[2].x = start.x, range[2].y = end.x, range[2].z = start.y, range[2].w = end.y;
    float t[6];
    t[0] = doIntersectPlane( start, norm[0], eyePos, d );
    t[1] = doIntersectPlane( end, norm[0], eyePos, d );
    t[2] = doIntersectPlane( start, norm[1], eyePos, d );
    t[3] = doIntersectPlane( end, norm[1], eyePos, d );
    t[4] = doIntersectPlane( start, norm[2], eyePos, d );
    t[5] = doIntersectPlane( end, norm[2], eyePos, d );

    cl_float4 intersectPoint[6];
    float min = POS_INF;
    float max = -POS_INF;
    for( int i = 0; i < 6; i++ )
    {
        intersectPoint[i].x = eyePos.x + t[i]*d.x;
        intersectPoint[i].y = eyePos.y + t[i]*d.y;
        intersectPoint[i].z = eyePos.z + t[i]*d.z;
        intersectPoint[i].w = eyePos.w + t[i]*d.w;
        if( t[i] > 0 && checkRange( intersectPoint[i], range[i/2], i/2 ) && min > t[i] )
        {
            min = t[i];
            *near = t[i];
        }
        if( t[i] > 0 && checkRange( intersectPoint[i], range[i/2], i/2 ) && max < t[i] )
        {
            max = t[i];
            *far = t[i];
        }
    }
}

bool boxContain( const cl_float3 start, const cl_float3 size, const cl_float3 pos )
{
    cl_float3 v1 = start;
    cl_float3 v2;
    v2.x  = start.x  + size.x;
    v2.y  = start.y  + size.y;
    v2.z  = start.z  + size.z;
        return ((pos.x >= v1.x) && (pos.x <= v2.x) &&
                (pos.y >= v1.y) && (pos.y <= v2.y) &&
                (pos.z >= v1.z) && (pos.z <= v2.z));
}

cl_float4 add4( cl_float4 v1, cl_float4 v2 )
{
    cl_float4 result;
    result.x = v1.x + v2.x;
    result.y = v1.y + v2.y;
    result.z = v1.z + v2.z;
    result.w = v1.w + v2.w;
    return result;
}

cl_float3 add3( cl_float3 v1, cl_float3 v2 )
{
    cl_float3 result;
    result.x = v1.x + v2.x;
    result.y = v1.y + v2.y;
    result.z = v1.z + v2.z;
    return result;
}

cl_float3 mult3( float s,  cl_float3 v )
{
    cl_float3 result;
    result.x = s*v.x;
    result.y = s*v.y;
    result.z = s*v.z;
    return result;
}

cl_float4 mult4( float s,  cl_float4 v )
{
    cl_float4 result;
    result.x = s*v.x;
    result.y = s*v.y;
    result.z = s*v.z;
    result.w = s*v.w;
    return result;
}

*/
REAL
intersect( const Vector4& eyePos,
           const QVector<SceneObject>& objects,
           const Vector4& d,
           int& objectIndex,
           int& faceIndex,
           KdTree* tree,
           AABB extends,
           bool refract
           )
{
        REAL minT = POS_INF;
        REAL resultT = -1;
        int tempFaceIndex = -1;
        if( settings.useKdTree && tree && !refract )
        {
            assert( EQ( eyePos.w, 1) && EQ(d.w, 0) );

            REAL near, far;
            doIntersectRayKdBox( eyePos, d, near, far, extends );
            if( near <= 0&&far <= 0 )
                return -1;

            QVector<KdTreeNode*> nodeStack;
            KdTreeNode* current = tree->getRoot();
            while( current )
            {
                while( !current->isLeaf() )
                {
                    AABB curBox = current->getAABB();
                    REAL near, far;
                    doIntersectRayKdBox( eyePos, d, near, far, curBox );
                    int axis = current->getAxis();
                    float splitPos = current->getSplitPos();
                    if( near == far )  // inside the box
                        near = 0;
                    Vector4 nearPos = eyePos + d*near;
                    Vector4 farPos = eyePos + d*far;
                    if( nearPos.data[axis] <= splitPos  )
                    {
                        if( farPos.data[axis] <= splitPos )
                        {
                            current = current->getLeft();
                            continue;
                        }
                        KdTreeNode* right = current->getRight();
                        current = current->getLeft();

                        // Preserve the right
                        nodeStack.push_back( right );
                    }
                    else
                    {
                        if( farPos.data[axis] > splitPos )
                        {
                            current=current->getRight();
                            continue;
                        }
                        KdTreeNode* left = current->getLeft();
                        current = current->getRight();
                        nodeStack.push_back( left );
                    }
                }

                // Then we found an near leaf, find if there is intersect
                ObjectNode* objList = current->getObjectList();
                minT = POS_INF;
                while( objList )
                {
                    SceneObject* curObj =objList->getObject();
                    Matrix4x4 invCompMat = (*curObj).m_invTransform;

                    Vector4 eyePosObjSpace = invCompMat*eyePos;
                    Vector4 dObjSpace = invCompMat*d;

                    REAL t = doIntersect( *curObj, eyePosObjSpace, dObjSpace, tempFaceIndex);
                    if( t>0 && t < minT )
                    {
                        minT = t;
                        objectIndex = curObj->m_arrayID;
                        faceIndex = tempFaceIndex;
                    }
                    objList = objList->getNext();
                }
                Vector4 dst = (eyePos + minT*d);
                // Here we need to enlarge the bounding box a little bit
                AABB curBox = AABB( current->getAABB().getPos() - Vector3( EPSILON, EPSILON, EPSILON ),
                               current->getAABB().getSize() + 2*Vector3( EPSILON, EPSILON, EPSILON ));
                if( minT != POS_INF && curBox.contains(Vector3(dst.x, dst.y, dst.z ) ) )
                {
                    resultT = minT;
                    break;
                }
                // Else we need to get one node from the stack
                if( nodeStack.empty() )
                {
                    // No more nodes, meaning there is no intersect
                    break;
                }
                else
                {
                    current = nodeStack.at(nodeStack.size()-1);
                    nodeStack.pop_back();
                }
            }
            /**
                GPU code, preserve for future test
              **/
            /*
            float near, far;
            KdTreeNodeHost root = kdnode_test[0];
            cl_float4 eye4;
            eye4.x = eyePos.x;
            eye4.y = eyePos.y;
            eye4.z = eyePos.z;
            eye4.w = eyePos.w;
            cl_float4 d4;
            d4.x = d.x;
            d4.y = d.y;
            d4.z = d.z;
            d4.w = d.w;
            doIntersectRayKdBox2( eye4, d4, &near, &far, root.boxBegin, root.boxSize );
            if( near <= 0 && far <= 0 )
                return -1;
        //    else
         //      return 1;
            int nodeStack[1024];
            int stackTop = 0;
            int nextIndex = 0;

            while( nextIndex != -1 )
            {
                KdTreeNodeHost current = kdnode_test[nextIndex];

                while( !current.leaf )
                {
                    cl_float3 curBoxStart = current.boxBegin;
                    cl_float3 curBoxSize = current.boxSize;
                    float near, far;
                    doIntersectRayKdBox2( eye4, d4, &near, &far, curBoxStart, curBoxSize );
                    int axis = current.axis;
                    float splitPos = current.split;
                    if( near == far )  // inside the box
                        near = 0;
                    cl_float4 nearPos = add4(eye4, mult4(near, d4));
                    cl_float4 farPos = add4(eye4, mult4(far, d4));
                    if( getAxisElem4(nearPos, axis) <= splitPos  )
                    {
                        if( getAxisElem4(farPos, axis) <= splitPos )
                        {
                            //nextIndex = current.leftIndex;
                            current = kdnode_test[current.leftIndex];
                            continue;
                        }
                        nodeStack[stackTop++] = current.rightIndex;
                        current = kdnode_test[current.leftIndex];

                        // Preserve the right

                    }
                    else
                    {
                        if( getAxisElem4(farPos, axis) > splitPos )
                        {
                         //   nextIndex = current.rightIndex;
                            current = kdnode_test[current.rightIndex];
                            continue;
                        }
                        //KdTreeNodeHost left = kdnode_test[current.leftIndex];
                        nodeStack[stackTop++] = current.leftIndex;
                        current = kdnode_test[current.rightIndex];

                    }
                }

                // Then we found an near leaf, find if there is intersect
                int objIndex = current.objIndex;

                minT = POS_INF;

                while( objIndex != -1 )
                {
                    ObjectNodeHost objList = objnode_test[objIndex];
                    int sceneObjIndex = objList.objectIndex;

                    const SceneObject& curSceneObj = objects[sceneObjIndex];

                    Matrix4x4 invCompMat = curSceneObj.m_invTransform;

                    Vector4 eyePosObjSpace = invCompMat*eyePos;
                    Vector4 dObjSpace = invCompMat*d;

                    REAL t = doIntersect( curSceneObj, eyePosObjSpace, dObjSpace, tempFaceIndex);

                    if( t>0 && t < minT )
                    {
                        minT = t;
                        objectIndex = sceneObjIndex;
                        faceIndex = tempFaceIndex;
                    }
                    objIndex = objList.nextNodeIndex;
                  }


                //cl_float4 dst = add4(eye4,  mult4(minT, d4));
                Vector4 dst = eyePos + minT*d;
                // Here we need to enlarge the bounding box a little bit
                cl_float3 ep1;
                ep1.x = -EPSILON; ep1.y = -EPSILON; ep1.z = -EPSILON;
                cl_float3 ep2;
                ep2.x = 2*EPSILON; ep2.y = 2*EPSILON; ep2.z = 2*EPSILON;
                cl_float3 boxStart = add3(current.boxBegin , ep1);
                cl_float3 boxSize = add3(current.boxSize, ep2 );
                cl_float3 dst3;
                dst3.x = dst.x;
                dst3.y = dst.y;
                dst3.z = dst.z;

                if( minT != POS_INF && boxContain( boxStart, boxSize, dst3 ) )
                {
                    resultT = minT;
                    //resultT = 1;
                    break;
                }
                // Else we need to get one node from the stack
                if( stackTop == 0 )
                {
                    // No more nodes, meaning there is no intersect
                    int a = 0;
                    break;
                }
                else
                {
                    nextIndex = nodeStack[--stackTop];
                }
            }*/
        }
        else
        {
            for( int i = 0; i < objects.size(); i++ )
            {
                const SceneObject& curObj = objects[i];
                Matrix4x4 invCompMat = curObj.m_invTransform;

                Vector4 eyePosObjSpace = invCompMat*eyePos;
                Vector4 dObjSpace = invCompMat*d;

                REAL t = doIntersect( curObj, eyePosObjSpace, dObjSpace, tempFaceIndex);
                if( t>0 && t < minT )
                {
                    minT = t;
                    objectIndex = i;
                    faceIndex = tempFaceIndex;
                }
            }
            if( minT != POS_INF  )
            {
                resultT = minT;
            }
        }
        return resultT;
}