Example #1
0
// Checks all neighbours
void AstarExe::CheckNeighbours(Node * _node) {
	//up
	CheckNode(_node->column, _node->line - 1, _node->cost+1, _node);
	//down
	CheckNode(_node->column, _node->line + 1, _node->cost+1, _node);
	//left
	CheckNode(_node->column - 1, _node->line, _node->cost+1, _node);
	//right
	CheckNode(_node->column + 1, _node->line, _node->cost+1, _node);
}
Example #2
0
int
MaxMem(int nprocs, int imrow, int imcol, int nmat, int *mval, int *nval, int nbmat, int *mbval,
       int *nbval, int ngrids, int *npval, int *nqval, long *maxMem) {
  int nprow, npcol, myrow, mycol;
  int j, ierr[1];
  long curMem;

  *maxMem = 0;
  for (j = 0; j < ngrids; ++j) {
    nprow = npval[j];
    npcol = nqval[j];

/*        Make sure grid information is correct */

    ierr[0] = 0;
    if (nprow < 1) {
     ierr[0] = 1;
    } else if (npcol < 1) {
      ierr[0] = 1;
    } else if (nprow * npcol > nprocs) {
      ierr[0] = 1;
    }

    if (ierr[0] > 0) {
      continue;
    }
    for (myrow = 0; myrow < nprow; myrow++)
      for (mycol = 0; mycol < npcol; mycol++) {
        CheckNode( imrow, imcol, nmat, mval, nval, nbmat, mbval, nbval, myrow, mycol, nprow,
                   npcol, &curMem );
        if (*maxMem < curMem) *maxMem = curMem;
      }
  }
  return 0;
}
Example #3
0
/*
	FindNodeByIndex()

	Cerca il nodo relativo all'indice.
*/
CNode* CNodeList::FindNodeByIndex(int index)
{
	CNode* pNode = m_pFirstNode;

	// scorre la lista
	while(pNode!=(CNode*)NULL)
	{
#ifdef _DEBUG
		// controlla la signature
		if(!CheckNode(pNode))
		{
			pNode = (CNode*)NULL;
			break;
		}
#endif
		if(pNode->status==USED_NODE)
		{
			if(pNode->index==index)
				break;
		}
		
		pNode = pNode->next;
	}

	return(pNode);
}
Example #4
0
void OctreeBodyAttraction()
{
    for (unsigned int i = 0; i < Bodies.size(); i++)
    {
        CheckNode(&GlobalNode, Bodies[i]);
    }
}
Example #5
0
int
main(int argc, char *argv[]) {
  int n, nb, nprow, npcol, ng, lcm;
  int nval[1], nbval[1];
  long maxMem;

  if (argc <= 1) {
    printf( "Usage:\n%s n nb nprow npcol\n", argv[0] );
  }

  if (argc <= 1 || sscanf( argv[1], "%d", &n  ) != 1 || n < 1)  n = 50000;
  if (argc <= 2 || sscanf( argv[2], "%d", &nb ) != 1 || nb < 1) nb = 80;
  if (argc <= 3 || sscanf( argv[3], "%d", &nprow ) != 1 || nprow < 1) nprow = 8;
  if (argc <= 4 || sscanf( argv[4], "%d", &npcol ) != 1 || npcol < 1) npcol = nprow;

  nval[0] = n;
  nbval[0] = nb;

  CheckNode( 0, 0, 1, nval, nval, 1, nbval, nbval, 0, 0, nprow, npcol, &maxMem );

  printf( "n=%d nb=%d nprow=%d npcol=%d lcm(nprow,npcol)=%d\n%ld\n", n, nb, nprow, npcol,
          ilcm_(&nprow, &npcol), maxMem );

  ng = iceil_(&n, &nb);
  lcm = ilcm_(&nprow, &npcol);
  printf( "%d %d %d\n", ng, lcm, (iceil_(&ng, &lcm) << 1) * nb * iceil_(&ng, &lcm) * nb );
  printf( "%d %d\n", (iceil_(&ng, &lcm) << 1), iceil_(&ng, &lcm) );

  return 0;
}
Example #6
0
// /////////////////////
// Trace
// /////////////////////
TraceResult Trace(
        const Bsp::CollisionBsp &bsp,
        const Bounds &bounds)
{
    // TODO: Deal with point tests (ray with length of 0).

    // Find the maximum distance per axis from the bounds.
    Vec3 extents =
    {
        std::abs(bounds.boxMin.data[0]) > std::abs(bounds.boxMax.data[0]) ?
        std::abs(bounds.boxMin.data[0]) :
        std::abs(bounds.boxMax.data[0]),

        std::abs(bounds.boxMin.data[1]) > std::abs(bounds.boxMax.data[1]) ?
        std::abs(bounds.boxMin.data[1]) :
        std::abs(bounds.boxMax.data[1]),

        std::abs(bounds.boxMin.data[2]) > std::abs(bounds.boxMax.data[2]) ?
        std::abs(bounds.boxMin.data[2]) :
        std::abs(bounds.boxMax.data[2]),
    };    

    // Create an Axis Aligned Bounding Box (AABB)
    // along the path of the trace, taking into
    // consideration the sphere radius and the
    // bounds extents.
    auto aabbMin = Min(bounds.start, bounds.end);
    aabbMin = aabbMin + -bounds.sphereRadius;
    aabbMin = aabbMin - extents;

    auto aabbMax = Max(bounds.start, bounds.end);
    aabbMax = aabbMax + bounds.sphereRadius;
    aabbMax = aabbMax + extents;

    return CheckNode(
                0,
                0.0f,
                1.0f,
                bounds.start,
                bounds.end,
                extents,
                {
                    bounds,
                    aabbMin,
                    aabbMax,
                },
                {
                    nullptr,
                    1.0f,
                    PathInfo::OutsideSolid
                },
                bsp);
}
Example #7
0
CVector3 CQuake3BSP::Trace(CVector3 vStart, CVector3 vEnd)
{
    // Initially we set our trace ratio to 1.0f, which means that we don't have
    // a collision or intersection point, so we can move freely.
    m_traceRatio = 1.0f;

    // We start out with the first node (0), setting our start and end ratio to 0 and 1.
    // We will recursively go through all of the nodes to see which brushes we should check.
    CheckNode(0, 0.0f, 1.0f, vStart, vEnd);

    // If the traceRatio is STILL 1.0f, then we never collided and just return our end position
    if(m_traceRatio == 1.0f)
    {
        return vEnd;
    }
    else	// Else COLLISION!!!!
    {
        // Set our new position to a position that is right up to the brush we collided with
        CVector3 vNewPosition = vStart + ((vEnd - vStart) * m_traceRatio);

        // Get the distance from the end point to the new position we just got
        CVector3 vMove = vEnd - vNewPosition;

        // Get the distance we need to travel backwards to the new slide position.
        // This is the distance of course along the normal of the plane we collided with.
        float distance = Dot(vMove, m_vCollisionNormal);

        // Get the new end position that we will end up (the slide position).
        CVector3 vEndPosition = vEnd - m_vCollisionNormal*distance;

        // Since we got a new position for our sliding vector, we need to check
        // to make sure that new sliding position doesn't collide with anything else.
        vNewPosition = Trace(vNewPosition, vEndPosition);


/////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// *

        //
        if(m_vCollisionNormal.y > 0.2f || m_bGrounded)
            m_bGrounded = true;
        else
            m_bGrounded = false;

/////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// *


        // Return the new position to be used by our camera (or player)
        return vNewPosition;
    }
}
Example #8
0
inline void CheckNode(Node* pNode, Body* pBody)
{
    if (pNode->Bodies.size() != 0)
    {
        float diffX = (pNode->CenterOfMassx - pBody->posX);
        float diffY = (pNode->CenterOfMassy - pBody->posY);

        float distance = sqrt((diffX) * (diffX) + (diffY) * (diffY));   //Distance from the node to the object

        if ((pNode->width / distance) < (_NODE_THRESHOLD) || (pNode->HasChildren == false))     //if sufficently far away or has no children (external node) group node and calculate force
        {
            CalculateForceNode(pBody, pNode, Softener);
            pNode->IsUsed = true;
        }
        else                                                                                    //if not, repeat function with children
        {
            CheckNode(pNode->Child[0], pBody);
            CheckNode(pNode->Child[1], pBody);
            CheckNode(pNode->Child[2], pBody);
            CheckNode(pNode->Child[3], pBody);
        }
    }
}
Example #9
0
NODE* GetCircleNode(){
	NODE * p = gHeadNode.pNext;
	for(uint i = 1; i <= gLinkLength; ++i){
		AddElem(p, p->hashVal);
		if(p->pNext && CheckNode(p->pNext, p->pNext->hashVal)){
			Destroy();
			return p->pNext;
		}
		p = p->pNext;
	}

	Destroy();
	return NULL;

}
Example #10
0
void Collision::traceRay(vec3f start, vec3f end)
{
  mInputStart = start;
  mInputEnd = end;
  mOutputFraction = 1.0f;
  mGoodPos = true;
  mTraceType = TT_RAY;

  CheckNode( 0, 0.0f, 1.0f, mInputStart, mInputEnd );

  if (mGoodPos)
  {
    mOutputEnd = mInputEnd;
  }
  else
  {
    mOutputEnd = mInputStart + mOutputFraction*(mInputEnd - mInputStart);
  }
}
Example #11
0
/*
	EnumerateNodes()

	Rinumera i nodi (occupati) presenti nella lista.
*/
void CNodeList::EnumerateNodes(void)
{
	int i = 0;
	CNode* pNode = m_pFirstNode;

	// scorre la lista
	while(pNode!=(CNode*)NULL)
	{
#ifdef _DEBUG
		// controlla la signature
		if(!CheckNode(pNode))
			break;
#endif
		// controlla lo status
		if(pNode->status==USED_NODE)
			pNode->index = i++;

		// passa al nodo successivo
		pNode = pNode->next;
	}
}
Example #12
0
/*
	ReleaseNodeList()

	Rilascia la lista dei nodi.
*/
void CNodeList::ReleaseNodeList(int nMode)
{
	CNode* pNode = m_pFirstNode;
	CNode* pNextNode;

	// scorre la lista
	while(pNode!=(CNode*)NULL)
	{
#ifdef _DEBUG
		// controlla la signature
		if(!CheckNode(pNode))
		{
			pNode = (CNode*)NULL;
			break;
		}
#endif
		// salva l'indirizzo del nodo successivo
		pNextNode = pNode->next;

		// rilascia le risorse associate al nodo ed il nodo
		ReleaseNode(pNode,nMode);
		if(nMode==RELEASE_DELETE_MODE || nMode==RELEASE_ERASE_MODE)
			delete pNode;

		// passa al nodo successivo
		if(nMode==RELEASE_DELETE_MODE || nMode==RELEASE_ERASE_MODE)
			m_pFirstNode = pNode = pNextNode;
		else
			pNode = pNode->next;
	}

	// azzera il numero di elementi presenti
	if(nMode==RELEASE_DELETE_MODE || nMode==RELEASE_ERASE_MODE)
		m_nTot = 0;

	// resetta la lista
	if(nMode==RELEASE_DELETE_MODE || nMode==RELEASE_ERASE_MODE)
		m_pFirstNode = m_pLastNode = (CNode*)NULL;
}
Example #13
0
BOOL
MT::CheckNode (GiSTpath path, MTentry *parentEntry)
{
	MTnode *node = (MTnode *) ReadNode (path);
	BOOL ret = TRUE;

	for (int i=0; i<node->NumEntries() && ret; i++) {
	    MTentry *nextEntry = (MTentry *) (*node)[i].Ptr();
	    if (parentEntry!=NULL && (nextEntry->Key()->distance+nextEntry->MaxRadius() > parentEntry->MaxRadius() || nextEntry->Key()->distance != nextEntry->object().distance(parentEntry->object()))) {
			cout << "Error with entry " << nextEntry << "in " << node;
			ret = FALSE;
		}
		if (!node->IsLeaf()) {
			path.MakeChild (nextEntry->Ptr());
			ret &= CheckNode (path, nextEntry);
			path.MakeParent ();
		}
	}

	delete node;
	return ret;
}
Example #14
0
/*
	CountNodes()

	Conta i nodi (occupati) presenti nella lista.
*/
int CNodeList::CountNodes(void)
{
	int tot = 0;
	CNode* pNode = m_pFirstNode;

	// scorre la lista
	while(pNode!=(CNode*)NULL)
	{
#ifdef _DEBUG
		// controlla la signature
		if(!CheckNode(pNode))
			break;
#endif
		// controlla lo status ed incrementa il totale dei nodi occupati
		if(pNode->status==USED_NODE)
			tot++;

		// passa al nodo successivo
		pNode = pNode->next;
	}

	return(tot);
}
Example #15
0
void Collision::trace()
{		
  int numTries = 0;

  while (numTries < 3)
  {		
    mOutputFraction = 1.0f;
    mGoodPos = true;
    CheckNode( 0, 0.0f, 1.0f, mInputStart, mInputEnd );
    if (mGoodPos)
    {
      mOutputEnd = mInputEnd;
      return;
    }
    else
    {
      mInputEnd = mInputEnd + mCollisionNormal*(-mEndDistance + EPSILON);
      numTries++;
    }		
  }
  // did not find a good position
  mOutputEnd = mInputStart;	
}
Example #16
0
/*
	FindNextNode()

	Restituisce il puntatore al successivo nodo (occupato) della lista.
	Passare il puntatore al corrente, restituisce il puntatore al seguente.
*/
CNode* CNodeList::FindNextNode(CNode* pNode)
{
	// scorre la lista (a partire dall'elemento corrente, ossia quello ricevuto come parametro)
	while(pNode!=(CNode*)NULL)
	{
#ifdef _DEBUG
		// controlla la signature
		if(!CheckNode(pNode))
		{
			pNode = (CNode*)NULL;
			break;
		}
#endif
		// posiziona sul nodo seguente (il puntatore sta' puntando al nodo corrente del chiamante)
		if((pNode = pNode->next)!=(CNode*)NULL)
		{
			// controlla lo status
			if(pNode->status==USED_NODE)
				break;
		}
	}

	return(pNode);
}
Example #17
0
/*
	FindFirstNode()

	Cerca il primo nodo della lista con lo status uguale a quello specificato.
*/
CNode* CNodeList::FindFirstNode(int status)
{
	CNode* pNode = m_pFirstNode;

	// scorre la lista
	while(pNode!=(CNode*)NULL)
	{
#ifdef _DEBUG
		// controlla la signature
		if(!CheckNode(pNode))
		{
			pNode = (CNode*)NULL;
			break;
		}
#endif
		// se lo status e' diverso da quello specificato, passa al nodo successivo
		if(pNode->status!=status)
			pNode = pNode->next;
		else
			break;
	}

	return(pNode);
}
Example #18
0
void CHeap1::Free( void* mem ) {
	Node* Tofree = (Node*)( (char*)mem - sizeof(Node) );
	mem = NULL;

	if ( !CheckNode( Tofree ) ) {
		// This is not a vilide node, something wrong
		return;
	}

	// because sentinel is always exsit as a free node, so any node in freelist will at least has one p*Free != NULL
#define ISFREE( node ) ( CheckNode( node ) && node->pPrevFree != NULL || node->pNextFree != NULL )
	Node* Prev = Tofree->pPrevMem;
	Node* Next = Tofree->pNextMem;
	Node* node = Tofree;

	if ( Prev == pSentinel ) {
		if ( ISFREE( Next ) ) {
			node->pPrevFree = Next->pPrevFree;
			node->pNextFree = Next->pNextFree;

			Next->pPrevFree->pNextFree = node;
			if ( Next->pNextFree ) Next->pNextFree->pPrevFree = node;

			node->pNextMem = Next->pNextMem;
			if ( Next->pNextMem <= pHeapEnd ) node->pNextMem->pPrevMem = node;
		}
		else {
			Tofree->pNextFree = pSentinel->pNextFree;
			Tofree->pPrevFree = pSentinel;
			if ( pSentinel->pNextFree ) pSentinel->pNextFree->pPrevFree = Tofree;
			pSentinel->pNextFree = Tofree;
		}
		return;
	}

	if ( ISFREE( Prev ) && ISFREE( Next ) ) {
		// Prev and Next both in FreeList
		Next->pPrevFree->pNextFree = Next->pNextFree;
		if ( Next->pNextFree ) Next->pNextFree->pPrevFree = Next->pPrevFree;

		Prev->pNextMem = Next->pNextMem;
		if ( Next->pNextMem <= pHeapEnd ) Next->pNextMem->pPrevMem = Prev;
	}
	else if ( ISFREE( Prev ) ) {
		Prev->pNextMem = node->pNextMem;
		if ( node->pNextMem <= pHeapEnd ) node->pNextMem->pPrevMem = Prev;
	}
	else if ( ISFREE( Next ) ) {
		node->pPrevFree = Next->pPrevFree;
		node->pNextFree = Next->pNextFree;

		Next->pPrevFree->pNextFree = node;
		if ( Next->pNextFree ) Next->pNextFree->pPrevFree = node;

		node->pNextMem = Next->pNextMem;
		if ( Next->pNextMem <= pHeapEnd ) node->pNextMem->pPrevMem = node;
	}
	else {
		// merge failed
		Tofree->pNextFree = pSentinel->pNextFree;
		Tofree->pPrevFree = pSentinel;
		if ( pSentinel->pNextFree ) pSentinel->pNextFree->pPrevFree = Tofree;
		pSentinel->pNextFree = Tofree;
	}
	return;
#undef ISFREE
}
Example #19
0
int main(int argc, char const *argv[])
{
	// rng stuff
	std::random_device rd; // device entropy
    std::mt19937 m_rng(rd()); // initialize our mersenne twister with a random seed
    std::uniform_real_distribution<double> double_gen(1e-300,38);

	// ---------------------------------- check correctness of checkNodes computations in VariableNode --------------------------
	for(int a = 0; a < 111; ++a) {
		for(int b = 0; b < 293; ++b) {
			VariableNode node(a, b);
			for(int i = 0; i < 7; ++i) { // a*slope +    c  		
				if( ((a*slopes[node.getCheckNodes()[i].first]  + node.getCheckNodes()[i].second)%293 != b) || node.getCheckNodes()[i].second < 0) {
					if (!(node.getCheckNodes()[i].second < 0 && reverseModulo((int)ALL_COLUMNS, a*slopes[i], b) == 292)) { // c = 292 -> c = -1
						std::cout << "a = " << a << " b = " << b << " s_index = " << node.getCheckNodes()[i].first << " c = " << node.getCheckNodes()[i].second << "\n";
					}
				}

			}
		}
	}

	// ------------------------------------------- test phiTilde function for large values ----------------------------------------
	for(int i = 30; i < 40; ++i) {
		std::cout << "i = " << i << " phiTilde = " << phiTilde(i) << " isNaN? " << isnan(phiTilde(i)) << "\n";
	}

	// ----------------------------------------- test phiTilde function for very small values -------------------------------------
	for(int i = 300; i < 320; i++) {
		std::cout << "10^{-" << i << "} = " << std::pow(10, -i) << " phiTilde = " << phiTilde(std::pow(10, -i)) << "\n";
	}

	// ------------------------------------------------------ test infinity sum ---------------------------------------------------
	std::cout << "Expecting inf -> " << phiTilde(std::pow(10, -400)) + 2 << "\n";
	std::cout << "Expecting -inf -> " << -phiTilde(std::pow(10, -400)) + 2 << "\n";
	std::cout << "Expecting 2 -> " <<  phiTilde(phiTilde(std::pow(10, -400))) + 2 << "\n";

	// ---------------------------------------------------- phiTilde performances -------------------------------------------------
	const int N = 1e6;
	// create N random values
	std::array<double, N> random_array;
	for(int i = 0; i < N; ++i) {
		random_array[i] = double_gen(m_rng);
	}

	std::chrono::time_point<std::chrono::system_clock> begin = std::chrono::system_clock::now();
	double val;
	for(int i = 0; i < N; ++i) {
		val = phiTilde(random_array[i]);
	}
	std::chrono::nanoseconds duration = std::chrono::system_clock::now() - begin;
	std::cout << "Average time to compute phiTilde(x) " << (double)duration.count()/N << " ns\n";

	// ----------------------------------------- test the update LLR function on variableNode --------------------------------------
	int a = 1;
	int b = 0;
	VariableNode node(a, b);
	for(int i = 0; i < 7; ++i) {
		std::cout << slopes[node.getCheckNodes()[i].first] << " c " << node.getCheckNodes()[i].second << "\n";
	}
	// set channel LLR and propagate it
	node.setChannelLLR(6);
	for(int i = 0; i < PC_ROWS + 1; ++i) {
		std::cout << "LLR = " << node.getLLRat(i) << "\n";
	}
	
	// create checkNodesVector
	std::vector<CheckNode> *checkNodesVector = new std::vector<CheckNode>(2051);
	for(int slope_index = 0; slope_index < (int)PC_ROWS - 1; ++slope_index) { // init the first six blocks
		for(int c = 0; c < (int)ALL_COLUMNS - 1; ++c) { // with 292 valid nodes each
			checkNodesVector->at(slope_index*(int)ALL_COLUMNS + c).setLine(line(slope_index, c));
		}
	}
	// init the last block
	for(int c = 0; c < (int)ALL_COLUMNS; ++c) { // with 293 valid nodes 
		checkNodesVector->at(((int)PC_ROWS - 1)*(int)ALL_COLUMNS + c).setLine(line((int)PC_ROWS - 1, c));
	}

	// fill the LLR of the blocks for (1,0) -> 0+293, 293+291, 293*2+290, 293*3+289, 293*4+288, 293*5 + 287, 293*6+286, each at row 1
	checkNodesVector->at(293).setLLRat(3, 1); // this will not be summed, since this check node is not valid
	checkNodesVector->at(293+291).setLLRat(3, 1);
	checkNodesVector->at(293*2+290).setLLRat(2, 1);
	checkNodesVector->at(293*3+289).setLLRat(-4, 1);
	checkNodesVector->at(293*4+288).setLLRat(-1, 1);
	checkNodesVector->at(293*5+287).setLLRat(3, 1);
	checkNodesVector->at(293*6+286).setLLRat(0, 1);

	node.updateLLR(checkNodesVector);
	std::cout << "LLR = " << node.getLLRat(0) << " expecting 9\n";
	std::cout << "LLR = " << node.getLLRat(1) << " expecting 6\n";
	std::cout << "LLR = " << node.getLLRat(2) << " expecting 7\n";
	std::cout << "LLR = " << node.getLLRat(3) << " expecting 13\n";
	std::cout << "LLR = " << node.getLLRat(4) << " expecting 10\n";
	std::cout << "LLR = " << node.getLLRat(5) << " expecting 6\n";
	std::cout << "LLR = " << node.getLLRat(6) << " expecting 9\n";
	std::cout << "LLR = " << node.getLLRat(7) << " expecting 3\n";

	delete checkNodesVector;

	// ----------------------------------------- test the update LLR function on checkNode ----------------------------------------
	// Create VariableNode vector
	std::vector<VariableNode> *variableNodeVector = new std::vector<VariableNode>;
	variableNodeVector->resize(ALL_COLUMNS*ALL_ROWS);
	// Init its coordinates
	for(int node_index = 0; node_index < variableNodeVector->size(); ++node_index) {
															// row 						// column
		variableNodeVector->at(node_index).setCoordinates(node_index/(int)ALL_COLUMNS, node_index%(int)ALL_COLUMNS);
	}

	int line_index = 2;
	int node_c = 3;
	CheckNode check_node(line(line_index,node_c));
	double all_llr = -11;
	// init LLR on the corresponding nodes
	for(int a = 0; a < (int)ALL_ROWS; ++a) {
		variableNodeVector->at(a*ALL_COLUMNS + (slopes[line_index]*a + node_c)%ALL_COLUMNS).setLLRat(all_llr, line_index);
	}
	// set an LLR on a different branch to 0 and check that it does not change the results
	variableNodeVector->at(106*ALL_COLUMNS + (slopes[line_index]*106 + node_c)%ALL_COLUMNS).setLLRat(0, line_index+1);

	double phiTildeNode = phiTilde(std::abs(all_llr));
	double exp_llr = (all_llr > 0) ? phiTilde(111*phiTildeNode) : -phiTilde(111*phiTildeNode);
	begin = std::chrono::system_clock::now();
	check_node.updateLLR(variableNodeVector);
	std::cout << "updateLLR time " << (double)(std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now() - begin)).count()/1000 << " ms\n";
	std::cout << "Expecting " << exp_llr << " computed " << check_node.getLLRat(1) << " " <<  check_node.getLLRat(2) <<"\n";

	variableNodeVector->at(110*ALL_COLUMNS + (slopes[line_index]*110 + node_c)%ALL_COLUMNS).setLLRat(-all_llr, line_index);
	phiTildeNode = phiTilde(std::abs(all_llr));
	exp_llr = (all_llr > 0) ? -phiTilde(111*phiTildeNode) : phiTilde(111*phiTildeNode);
	begin = std::chrono::system_clock::now();
	check_node.updateLLR(variableNodeVector);
	std::cout << "updateLLR time " << (double)(std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now() - begin)).count()/1000 << " ms\n";
	std::cout << "Expecting " << exp_llr << " computed " << check_node.getLLRat(1) << " " <<  check_node.getLLRat(2) <<"\n";
	std::cout << "For node 110, expecting " << -exp_llr << " computed " << check_node.getLLRat(110) <<"\n";

	variableNodeVector->at(107*ALL_COLUMNS + (slopes[line_index]*107 + node_c)%ALL_COLUMNS).setLLRat(-all_llr, line_index);
	phiTildeNode = phiTilde(std::abs(all_llr));
	exp_llr = (all_llr > 0) ? phiTilde(111*phiTildeNode) : -phiTilde(111*phiTildeNode);
	check_node.updateLLR(variableNodeVector);
	std::cout << "Expecting " << exp_llr << " computed " << check_node.getLLRat(1) << " " <<  check_node.getLLRat(2) <<"\n";
	std::cout << "For node 110, expecting " << -exp_llr << " computed " << check_node.getLLRat(110) <<"\n";
	std::cout << "For node 107, expecting " << -exp_llr << " computed " << check_node.getLLRat(107) <<"\n";



	// set one LLR to 0 -> also the resulting llr should be 0
	variableNodeVector->at(106*ALL_COLUMNS + (slopes[line_index]*106 + node_c)%ALL_COLUMNS).setLLRat(0, line_index);
	phiTildeNode = phiTilde(std::abs(all_llr));
	exp_llr = (all_llr > 0) ? phiTilde(111*phiTildeNode) : -phiTilde(111*phiTildeNode);
	check_node.updateLLR(variableNodeVector);
	std::cout << "Expecting " << 0 << " computed " << check_node.getLLRat(1) << " " <<  check_node.getLLRat(2) <<"\n";
	std::cout << "For node 110, expecting " << 0 << " computed " << check_node.getLLRat(110) <<"\n";
	std::cout << "For node 107, expecting " << 0 << " computed " << check_node.getLLRat(107) <<"\n";
	std::cout << "For node 106, expecting " << exp_llr << " computed " << check_node.getLLRat(106) <<"\n";


	// set one LLR to infinity -> the result is given only by the other ones
	variableNodeVector->at(106*ALL_COLUMNS + (slopes[line_index]*106 + node_c)%ALL_COLUMNS).setLLRat(std::numeric_limits<double>::infinity(), line_index);
	phiTildeNode = phiTilde(std::abs(all_llr));
	exp_llr = phiTilde(110*phiTildeNode);
	check_node.updateLLR(variableNodeVector);
	std::cout << "Expecting " << exp_llr << " computed " << check_node.getLLRat(1) << " " <<  check_node.getLLRat(2) <<"\n";
	std::cout << "For node 110, expecting " << -exp_llr << " computed " << check_node.getLLRat(110) <<"\n";
	std::cout << "For node 107, expecting " << -exp_llr << " computed " << check_node.getLLRat(107) <<"\n";
	std::cout << "For node 106, expecting " << ((all_llr > 0) ? phiTilde(111*phiTildeNode) : -phiTilde(111*phiTildeNode)) << " computed " << check_node.getLLRat(106) <<"\n";


	for(int a = 0; a < (int)ALL_ROWS; ++a) {
		variableNodeVector->at(a*ALL_COLUMNS + (slopes[line_index]*a + node_c)%ALL_COLUMNS).setLLRat(std::numeric_limits<double>::infinity(), line_index);
	}
	phiTildeNode = phiTilde(std::abs(std::numeric_limits<double>::infinity()));
	exp_llr = (std::numeric_limits<double>::infinity() > 0) ? phiTilde(111*phiTildeNode) : -phiTilde(111*phiTildeNode);
	check_node.updateLLR(variableNodeVector);
	std::cout << "Expecting " << exp_llr << " computed " << check_node.getLLRat(1) << " " <<  check_node.getLLRat(2) <<"\n";

	// ----------------------------------------- test the min sum update LLR function on checkNode ----------------------------------------

	std::cout << "Min Sum test\n";
	line_index = 2;
	node_c = 3;
	CheckNode check_node_ms = CheckNode(line(line_index,node_c));
	all_llr = -11;
	// init LLR on the corresponding nodes
	for(int a = 0; a < (int)ALL_ROWS; ++a) {
		variableNodeVector->at(a*ALL_COLUMNS + (slopes[line_index]*a + node_c)%ALL_COLUMNS).setLLRat(all_llr, line_index);
	}
	// set an LLR on a different branch to 0 and check that it does not change the results
	variableNodeVector->at(106*ALL_COLUMNS + (slopes[line_index]*106 + node_c)%ALL_COLUMNS).setLLRat(0, line_index+1);

	begin = std::chrono::system_clock::now();
	check_node_ms.updateLLRminSum(variableNodeVector);
	std::cout << "updateLLR time " << (double)(std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now() - begin)).count()/1000 << " ms\n";
	std::cout << "Expecting " << all_llr << " computed " << check_node_ms.getLLRat(1) << " " <<  check_node_ms.getLLRat(2) <<"\n";

	variableNodeVector->at(110*ALL_COLUMNS + (slopes[line_index]*110 + node_c)%ALL_COLUMNS).setLLRat(-all_llr, line_index);
	exp_llr = -all_llr;
	begin = std::chrono::system_clock::now();
	check_node_ms.updateLLRminSum(variableNodeVector);
	std::cout << "updateLLR time " << (double)(std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now() - begin)).count()/1000 << " ms\n";
	std::cout << "Expecting " << exp_llr << " computed " << check_node_ms.getLLRat(1) << " " <<  check_node_ms.getLLRat(2) <<"\n";
	std::cout << "For node 110, expecting " << -exp_llr << " computed " << check_node_ms.getLLRat(110) <<"\n";


	variableNodeVector->at(107*ALL_COLUMNS + (slopes[line_index]*107 + node_c)%ALL_COLUMNS).setLLRat((all_llr > 0 ? -(all_llr - 1) : -(all_llr + 1)), line_index);
	exp_llr = (all_llr > 0) ? all_llr-1 : -(all_llr-1);
	check_node_ms.updateLLRminSum(variableNodeVector);
	std::cout << "Expecting " << (all_llr > 0 ? (all_llr - 1) : (all_llr + 1)) << " computed " << check_node_ms.getLLRat(1) << " " <<  check_node_ms.getLLRat(2) <<"\n";
	std::cout << "For node 110, expecting " << (all_llr < 0 ? -(all_llr + 1) : -(all_llr - 1))   << " computed " << check_node_ms.getLLRat(110) <<"\n";
	std::cout << "For node 107, expecting " << -all_llr << " computed " << check_node_ms.getLLRat(107) <<"\n";



	// set one LLR to 0 -> also the resulting llr should be 0
	variableNodeVector->at(106*ALL_COLUMNS + (slopes[line_index]*106 + node_c)%ALL_COLUMNS).setLLRat(0, line_index);
	check_node_ms.updateLLRminSum(variableNodeVector);
	std::cout << "Expecting " << 0 << " computed " << check_node_ms.getLLRat(1) << " " <<  check_node_ms.getLLRat(2) <<"\n";
	std::cout << "For node 110, expecting " << 0 << " computed " << check_node_ms.getLLRat(110) <<"\n";
	std::cout << "For node 107, expecting " << 0 << " computed " << check_node_ms.getLLRat(107) <<"\n";
	std::cout << "For node 106, expecting " << (all_llr > 0 ? (all_llr - 1) : (all_llr + 1)) << " computed " << check_node_ms.getLLRat(106) <<"\n";


	// set one LLR to infinity -> the result is given only by the other ones
	variableNodeVector->at(106*ALL_COLUMNS + (slopes[line_index]*106 + node_c)%ALL_COLUMNS).setLLRat(std::numeric_limits<double>::infinity(), line_index);
	check_node_ms.updateLLRminSum(variableNodeVector);
	std::cout << "Expecting " << (all_llr > 0 ? (all_llr - 1) : -(all_llr + 1)) << " computed " << check_node_ms.getLLRat(1) << " " <<  check_node_ms.getLLRat(2) <<"\n";
	std::cout << "For node 110, expecting " << -(all_llr > 0 ? (all_llr - 1) : -(all_llr + 1)) << " computed " << check_node_ms.getLLRat(110) <<"\n";
	std::cout << "For node 107, expecting " << (all_llr > 0 ? -all_llr : all_llr) << " computed " << check_node_ms.getLLRat(107) <<"\n";
	std::cout << "For node 106, expecting " << (all_llr > 0 ? (all_llr - 1) : (all_llr + 1)) << " computed " << check_node_ms.getLLRat(106) <<"\n";


	for(int a = 0; a < (int)ALL_ROWS; ++a) {
		variableNodeVector->at(a*ALL_COLUMNS + (slopes[line_index]*a + node_c)%ALL_COLUMNS).setLLRat(std::numeric_limits<double>::infinity(), line_index);
	}
	check_node_ms.updateLLRminSum(variableNodeVector);
	std::cout << "Expecting " << std::numeric_limits<double>::infinity() << " computed " << check_node_ms.getLLRat(1) << " " <<  check_node_ms.getLLRat(2) <<"\n";
	
	return 0;
}
Example #20
0
void Collision::CheckNode( int nodeIndex, float startFraction, float endFraction, vec3f start, vec3f end)
{
  if (nodeIndex < 0)
  {	
    // this is a leaf
    Q3BspLeaf *leaf = &mQ3Map->m_pLeafs[-(nodeIndex + 1)];

    for (int i = 0; i < leaf->n_leafbrushes; i++)
    {
      Q3BspBrush *brush = &mQ3Map->m_pBrushes[mQ3Map->m_pLeafBrushes[leaf->leafbrush + i]];
      if (brush->n_brushsides > 0 && (mQ3Map->m_pTextures[brush->texture].contents & 1) )			    
      {
        CheckBrush( brush );
      }
    }

    // don't have to do anything else for leaves
    return;
  }

  // this is a node

  Q3BspNode *node = &mQ3Map->m_pNodes[nodeIndex];
  Q3BspPlane *plane = &mQ3Map->m_pPlanes[node->plane];

  vec3f normal = vec3f(plane->normal); 
  vec3f startDX = vec3f(start);
  vec3f endDX = vec3f(end); 

  float startDistance = vec3dot( &startDX, &normal ) - plane->dist;
  float endDistance = vec3dot( &endDX, &normal ) - plane->dist;
  float offset;

  if (mTraceType == TT_RAY)
  {
    offset = 0.0f;
  }
  else if (mTraceType == TT_SPHERE)
  {
    offset = mTraceRadius;
  }
  else
  {
    offset = 0.0f;
  }

  if (startDistance >= offset && endDistance >= offset)
  {	// both points are in front of the plane
    // so check the front child
    CheckNode( node->children[0], startFraction, endFraction, start, end );
  }
  else if (startDistance < -offset && endDistance < -offset)
  {	// both points are behind the plane
    // so check the back child
    CheckNode( node->children[1], startFraction, endFraction, start, end );
  }
  else
  {	// the line spans the splitting plane
    int side;
    float fraction1, fraction2, middleFraction;
    vec3f middle;

    // split the segment into two
    if (startDistance < endDistance)
    {
      side = 1; // back
      float inverseDistance = 1.0f / (startDistance - endDistance);
      fraction1 = (startDistance - offset + EPSILON) * inverseDistance;
      fraction2 = (startDistance + offset + EPSILON) * inverseDistance;
    }
    else if (endDistance < startDistance)
    {
      side = 0; // front
      float inverseDistance = 1.0f / (startDistance - endDistance);
      fraction1 = (startDistance + offset + EPSILON) * inverseDistance;
      fraction2 = (startDistance - offset - EPSILON) * inverseDistance;
    }
    else
    {
      side = 0; // front
      fraction1 = 1.0f;
      fraction2 = 0.0f;
    }

    // make sure the numbers are valid
    if (fraction1 < 0.0f) fraction1 = 0.0f;
    else if (fraction1 > 1.0f) fraction1 = 1.0f;
    if (fraction2 < 0.0f) fraction2 = 0.0f;
    else if (fraction2 > 1.0f) fraction2 = 1.0f;

    // calculate the middle point for the first side
    middleFraction = startFraction + (endFraction - startFraction) * fraction1;
    /*for (int i = 0; i < 3; i++)
    middle[i] = start[i] + fraction1 * (end[i] - start[i]);*/
    middle = start + fraction1 * (end - start);

    // check the first side
    CheckNode( node->children[side], startFraction, middleFraction, start, middle );

    // calculate the middle point for the second side
    middleFraction = startFraction + (endFraction - startFraction) * fraction2;
    /*for (int i = 0; i < 3; i++)
    middle[i] = start[i] + fraction2 * (end[i] - start[i]);*/
    middle = start + fraction2 * (end - start);

    // check the second side
    CheckNode( node->children[!side], middleFraction, endFraction, middle, end );
  }
}
Example #21
0
void CQuake3BSP::CheckNode(int nodeIndex, float startRatio, float endRatio, CVector3 vStart, CVector3 vEnd)
{
    // Check if the next node is a leaf
    if(nodeIndex < 0)
    {
        // If this node in the BSP is a leaf, we need to negate and add 1 to offset
        // the real node index into the m_pLeafs[] array.  You could also do [~nodeIndex].
        tBSPLeaf *pLeaf = &m_pLeafs[-(nodeIndex + 1)];

        // We have a leaf, so let's go through all of the brushes for that leaf
        for(int i = 0; i < pLeaf->numOfLeafBrushes; i++)
        {
            // Get the current brush that we going to check
            tBSPBrush *pBrush = &m_pBrushes[m_pLeafBrushes[pLeaf->leafBrush + i]];

            // Check if we have brush sides and the current brush is solid and collidable
            if((pBrush->numOfBrushSides > 0) && (m_pTextures[pBrush->textureID].textureType & 1))
            {
                // Now we delve into the dark depths of the real calculations for collision.
                // We can now check the movement vector against our brush planes.
                CheckBrush(pBrush, vStart, vEnd);
            }
        }

        // Since we found the brushes, we can go back up and stop recursing at this level
        return;
    }

    // Grad the next node to work with and grab this node's plane data
    tBSPNode *pNode = &m_pNodes[nodeIndex];
    tBSPPlane *pPlane = &m_pPlanes[pNode->plane];

    // Here we use the plane equation to find out where our initial start position is
    // according the the node that we are checking.  We then grab the same info for the end pos.
    float startDistance = Dot(vStart, pPlane->vNormal) - pPlane->d;
    float endDistance = Dot(vEnd, pPlane->vNormal) - pPlane->d;
    float offset = 0.0f;

    // If we are doing sphere collision, include an offset for our collision tests below
    if(m_traceType == TYPE_SPHERE)
        offset = m_traceRadius;

    // Here we check to see if we are working with a BOX or not
    else if(m_traceType == TYPE_BOX)
    {
        // Get the distance our AABB is from the current splitter plane
        offset = (float)(fabs( m_vExtents.x * pPlane->vNormal.x ) +
                         fabs( m_vExtents.y * pPlane->vNormal.y ) +
                         fabs( m_vExtents.z * pPlane->vNormal.z ) );
    }

    // Here we check to see if the start and end point are both in front of the current node.
    // If so, we want to check all of the nodes in front of this current splitter plane.
    if(startDistance >= offset && endDistance >= offset)
    {
        // Traverse the BSP tree on all the nodes in front of this current splitter plane
        CheckNode(pNode->front, startDistance, endDistance, vStart, vEnd);
    }
    // If both points are behind the current splitter plane, traverse down the back nodes
    else if(startDistance < -offset && endDistance < -offset)
    {
        // Traverse the BSP tree on all the nodes in back of this current splitter plane
        CheckNode(pNode->back, startDistance, endDistance, vStart, vEnd);
    }
    else
    {
        // If we get here, then our ray needs to be split in half to check the nodes
        // on both sides of the current splitter plane.  Thus we create 2 ratios.
        float Ratio1 = 1.0f, Ratio2 = 0.0f, middleRatio = 0.0f;
        CVector3 vMiddle;	// This stores the middle point for our split ray

        // Start of the side as the front side to check
        int side = pNode->front;

        // Here we check to see if the start point is in back of the plane (negative)
        if(startDistance < endDistance)
        {
            // Since the start position is in back, let's check the back nodes
            side = pNode->back;

            // Here we create 2 ratios that hold a distance from the start to the
            // extent closest to the start (take into account a sphere and epsilon).
            float inverseDistance = 1.0f / (startDistance - endDistance);
            Ratio1 = (startDistance - offset - kEpsilon) * inverseDistance;
            Ratio2 = (startDistance + offset + kEpsilon) * inverseDistance;
        }
        // Check if the starting point is greater than the end point (positive)
        else if(startDistance > endDistance)
        {
            // This means that we are going to recurse down the front nodes first.
            // We do the same thing as above and get 2 ratios for split ray.
            float inverseDistance = 1.0f / (startDistance - endDistance);
            Ratio1 = (startDistance + offset + kEpsilon) * inverseDistance;
            Ratio2 = (startDistance - offset - kEpsilon) * inverseDistance;
        }

        // Make sure that we have valid numbers and not some weird float problems.
        // This ensures that we have a value from 0 to 1 as a good ratio should be :)
        if (Ratio1 < 0.0f) Ratio1 = 0.0f;
        else if (Ratio1 > 1.0f) Ratio1 = 1.0f;

        if (Ratio2 < 0.0f) Ratio2 = 0.0f;
        else if (Ratio2 > 1.0f) Ratio2 = 1.0f;

        // Just like we do in the Trace() function, we find the desired middle
        // point on the ray, but instead of a point we get a middleRatio percentage.
        middleRatio = startRatio + ((endRatio - startRatio) * Ratio1);
        vMiddle = vStart + ((vEnd - vStart) * Ratio1);

        // Now we recurse on the current side with only the first half of the ray
        CheckNode(side, startRatio, middleRatio, vStart, vMiddle);

        // Now we need to make a middle point and ratio for the other side of the node
        middleRatio = startRatio + ((endRatio - startRatio) * Ratio2);
        vMiddle = vStart + ((vEnd - vStart) * Ratio2);

        // Depending on which side should go last, traverse the bsp with the
        // other side of the split ray (movement vector).
        if(side == pNode->back)
            CheckNode(pNode->front, middleRatio, endRatio, vMiddle, vEnd);
        else
            CheckNode(pNode->back, middleRatio, endRatio, vMiddle, vEnd);
    }
}
Example #22
0
static int FindNextLeafNode(	BTScanState *scanState, Boolean avoidIO )
{
	int		err;
	
	err = noErr;		// Assume everything will be OK
	
	while ( 1 ) 
	{
		if ( scanState->nodesLeftInBuffer == 0 ) 
		{
			//	Time to read some more nodes into the buffer
			if ( avoidIO ) 
			{
				return fsBTTimeOutErr;
			}
			else 
			{
				//	read some more nodes into buffer
				err = ReadMultipleNodes( scanState );
				if ( err != noErr ) 
					break;
			}
		}
		else 
		{
			//	Adjust the node counters and point to the next node in the buffer
			++scanState->nodeNum;
			--scanState->nodesLeftInBuffer;
			
			//	If we've looked at all nodes in the tree, then we're done
			if ( scanState->nodeNum >= scanState->btcb->totalNodes )
				return fsEndOfIterationErr;

			if ( scanState->nodesLeftInBuffer == 0 )
			{
				scanState->recordNum = 0; 
				continue; 
			}

			(u_int8_t *) scanState->currentNodePtr += scanState->btcb->nodeSize;
		}
		
#if BYTE_ORDER == LITTLE_ENDIAN
		{
		BlockDescriptor block;
		FileReference fref;

		/* Fake a BlockDescriptor */
		block.buffer = scanState->currentNodePtr;
		block.blockSize = scanState->btcb->nodeSize;
		block.blockReadFromDisk = 1;
		block.isModified = 0;
		
		fref = scanState->btcb->fileRefNum;
		
		SWAP_BT_NODE(&block, ISHFSPLUS(VTOVCB(fref)), VTOC(fref)->c_fileid, 0);
		}
#endif

		// Make sure this is a valid node
		if ( CheckNode( scanState->btcb, scanState->currentNodePtr ) != noErr )
		{
			continue;
		}
		
		if ( scanState->currentNodePtr->kind == kBTLeafNode )
			break;
	}
	
	return err;
	
} /* FindNextLeafNode */
Example #23
0
  void Run(berry::IWorkbenchPartSite::Pointer workbenchPartSite, mitk::DataStorage::Pointer dataStorage, const QList<mitk::DataNode::Pointer>& selectedNodes /*= QList<mitk::DataNode::Pointer>()*/, mitk::BaseRenderer* baseRenderer /*= nullptr*/)
  {
    if (selectedNodes.empty())
    {
      return;
    }

    auto renderWindow = mitk::WorkbenchUtil::GetRenderWindowPart(workbenchPartSite->GetPage(), mitk::WorkbenchUtil::NONE);
    if (nullptr == renderWindow)
    {
      renderWindow = mitk::WorkbenchUtil::OpenRenderWindowPart(workbenchPartSite->GetPage(), false);
      if (nullptr == renderWindow)
      {
        // no render window available
        return;
      }
    }


    auto boundingBoxPredicate = mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("includeInBoundingBox", mitk::BoolProperty::New(false), baseRenderer));

    mitk::DataStorage::SetOfObjects::Pointer nodes = mitk::DataStorage::SetOfObjects::New();
    for (const auto& dataNode : selectedNodes)
    {
      if (boundingBoxPredicate->CheckNode(dataNode))
      {
        nodes->InsertElement(nodes->Size(), dataNode);
      }
    }

    if (nodes->empty())
    {
      return;
    }

    if (1 == nodes->Size()) // Special case: If exactly one ...
    {
      auto image = dynamic_cast<mitk::Image*>(nodes->ElementAt(0)->GetData());

      if (nullptr != image) // ... image is selected, reinit is expected to rectify askew images.
      {
        if (nullptr == baseRenderer)
        {
          mitk::RenderingManager::GetInstance()->InitializeViews(image->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true);
        }
        else
        {
          mitk::RenderingManager::GetInstance()->InitializeView(baseRenderer->GetRenderWindow(), image->GetTimeGeometry(), true);
        }
        return;
      }
    }

    auto boundingGeometry = dataStorage->ComputeBoundingGeometry3D(nodes, "visible", baseRenderer);
    if (nullptr == baseRenderer)
    {
      mitk::RenderingManager::GetInstance()->InitializeViews(boundingGeometry);
    }
    else
    {
      mitk::RenderingManager::GetInstance()->InitializeView(baseRenderer->GetRenderWindow(), boundingGeometry);
    }
  }
void Pathfinder::GeneratePath()
{
    sLog.Write("Generating new path");

    // Destroy old path
    Path = std::stack<Vector2i>();

    // Zero out status grid
    std::memset(PathfindingStatusGrid.get(), 0, MAX_MAP_HEIGHT * MAX_MAP_WIDTH * sizeof(uint8));

    // Get Node with same position as creature in pathfinding grid
    PathfinderNode* pOriginNode = &(PathfindingGrid[MAX_MAP_HEIGHT * pOrigin->GetY() + pOrigin->GetX()]);

    // Origin node does not have parent node
    pOriginNode->pParent = nullptr;

    // Origin node does not have G cost
    pOriginNode->G = 0;
    pOriginNode->H = 10 * math::GetManhattanDistance(Vector2i(pOriginNode->Position.x, pOriginNode->Position.y), Target);

    // Add origin node to queue
    OpenList.push(pOriginNode);

    do
    {
        // Grab node with highest priority
        PathfinderNode* pCurrent = OpenList.top();
        OpenList.pop();

        // Move it to "closed" list
        PathfindingStatusGrid[MAX_MAP_HEIGHT * pCurrent->Position.y + pCurrent->Position.x] = CLOSED;

        // If current node has same coordinates as target, we found our path
        if(pCurrent->Position == Target)
        {
            // Create path using parents to track down origin
            while(pCurrent->pParent != nullptr)
            {
                Path.push(pCurrent->Position);
                pCurrent = pCurrent->pParent;
            }
            
            // Destroy open list
            OpenList.clear();
            
            return;
        }

        // For each of adjacent nodes
        // if it is not out of bounds
        // and if tile is 'walkable',
        // check its status

        // Upper
        if(pCurrent->Position.y != 0)
        {
            CheckNode(pCurrent, 0, -1, 10);
        }

        // Lower
        if(pCurrent->Position.y != pTileGrid->size()-1)
        {
            CheckNode(pCurrent, 0, 1, 10);
        }

        // Right
        if(pCurrent->Position.x != (*pTileGrid)[0].size()-1)
        {
            CheckNode(pCurrent, 1, 0, 10);
        }

        // Left
        if(pCurrent->Position.x != 0)
        {
            CheckNode(pCurrent, -1, 0, 10);
        }

        // Upper-right
        if(pCurrent->Position.x != (*pTileGrid)[0].size()-1 && pCurrent->Position.y != 0)
        {
            CheckNode(pCurrent, 1, -1, 14);
        }

        // Upper-left
        if(pCurrent->Position.x != 0 && pCurrent->Position.y != 0)
        {
            CheckNode(pCurrent, -1, -1, 14);
        }

        // Lower-right
        if(pCurrent->Position.x != (*pTileGrid)[0].size()-1 && pCurrent->Position.y != pTileGrid->size()-1)
        {
            CheckNode(pCurrent, 1, 1, 14);
        }

        // Lower-left
        if(pCurrent->Position.x != 0 && pCurrent->Position.y != pTileGrid->size()-1)
        {
            CheckNode(pCurrent, -1, 1, 14);
        }

    } while(!OpenList.empty());

    sLog.Write("Could not generate path");
}
Example #25
0
TraceResult CheckNode(
    int nodeIndex,
    float startFraction,
    float endFraction,

    const Vec3& start,
    const Vec3& end,
    const Vec3& extents,
    const TraceBounds& boundsAabb,

    TraceResult result,
    const Bsp::CollisionBsp& bsp)
{
    if (result.pathFraction <= startFraction)
    {
        // already hit something nearer
        return result;
    }

    if (nodeIndex < 0)
    {
        // this is a leaf
        const auto& leaf = bsp.leaves[-(nodeIndex + 1)];

        for (int i = 0; i < leaf.leafBrushCount; i++)
        {
            const auto& brush =
                    bsp.brushes[bsp.leafBrushes[leaf.firstLeafBrushIndex + i].brushIndex];

            // Don't even bother if there are no brush sides.
            if (brush.brush.sideCount <= 0)
            {
                continue;
            }

            // Only test solid brushes
            // 1 == CONTENTS_SOLID
            if (!(bsp.textures[brush.brush.textureIndex].contentFlags & 1))
            {
                continue;
            }

            // Early exit if the AABB doesn't collide.
            if (AabbDontIntersect(
                        boundsAabb.aabbMin,
                        boundsAabb.aabbMax,
                        brush.aabbMin,
                        brush.aabbMax))
            {
                continue;
            }

            result = CheckBrush(bsp, brush.brush, boundsAabb.bounds, result);
        }

        // don't have to do anything else for leaves
        return result;
    }

    // this is a node
    const auto& node = bsp.nodes[nodeIndex];
    const auto& plane = bsp.planes[node.planeIndex];

    float startDistance = DotF(start, plane.normal) - plane.distance;
    float endDistance   = DotF(end, plane.normal) - plane.distance;

    // Offset used for non-ray tests.
    const auto& bounds = boundsAabb.bounds;
    float offset = bounds.sphereRadius;

    // extents are zero for ray or sphere tests.
    offset +=
        std::abs(extents.data[0] * plane.normal.data[0]) +
        std::abs(extents.data[1] * plane.normal.data[1]) +
        std::abs(extents.data[2] * plane.normal.data[2]);

    if (startDistance >= offset && endDistance >= offset)
    {
        // both points are in front of the plane
        // so check the front child
        return CheckNode(
            node.childIndex[0],
            startFraction,
            endFraction,
            start,
            end,
            extents,
            boundsAabb,
            result,
            bsp);
    }

    if (startDistance < -offset && endDistance < -offset)
    {
        // both points are behind the plane
        // so check the back child
        return CheckNode(
            node.childIndex[1],
            startFraction,
            endFraction,
            start,
            end,
            extents,
            boundsAabb,
            result,
            bsp);
    }

    // the line spans the splitting plane
    // Default values assume startDistance == endDistance.
    int side = 0;
    float fraction1 = 1.0f;
    float fraction2 = 0.0f;

    // split the segment into two
    if (startDistance < endDistance)
    {
        // back
        side = 1;
        float inverseDistance = 1.0f / (startDistance - endDistance);
        fraction1 = (startDistance - offset + EPSILON) * inverseDistance;
        fraction2 = (startDistance + offset + EPSILON) * inverseDistance;
    }

    if (endDistance < startDistance)
    {
        // front
        float inverseDistance = 1.0f / (startDistance - endDistance);
        fraction1 = (startDistance + offset + EPSILON) * inverseDistance;
        fraction2 = (startDistance - offset - EPSILON) * inverseDistance;
    }

    // make sure the numbers are valid
    fraction1 = Clamp0To1(fraction1);
    fraction2 = Clamp0To1(fraction2);

    // calculate the middle point for the first side
    {
        auto middleFraction =
                startFraction + (endFraction - startFraction) * fraction1;

        auto middle = Lerp(start, end, fraction1);

        // check the first side
        result = CheckNode(
            node.childIndex[side],
            startFraction,
            middleFraction,
            start,
            middle,
            extents,
            boundsAabb,
            result,
            bsp);
    }

    // calculate the middle point for the second side
    {
        auto middleFraction =
                startFraction + (endFraction - startFraction) * fraction2;

        auto middle = Lerp(start, end, fraction2);

        // check the second side
        result = CheckNode(
            node.childIndex[!side],
            middleFraction,
            endFraction,
            middle,
            end,
            extents,
            boundsAabb,
            result,
            bsp);
    }

    return result;
}