/** * Update some obsolete blocks using the FIFO-principle */ void CPathEstimator::Update() { pathCache->Update(); unsigned int counter = 0; while (!needUpdate.empty() && counter < BLOCKS_TO_UPDATE) { // next block in line SingleBlock sb = needUpdate.front(); needUpdate.pop_front(); const int blocknr = sb.block.y * nbrOfBlocksX + sb.block.x; // check if it's already updated if (!(blockStates[blocknr].nodeMask & PATHOPT_OBSOLETE)) continue; // no, update the block FindOffset(*sb.moveData, sb.block.x, sb.block.y); CalculateVertices(*sb.moveData, sb.block.x, sb.block.y); // mark it as updated if (sb.moveData == moveinfo->moveData.back()) { blockStates[blocknr].nodeMask &= ~PATHOPT_OBSOLETE; } // one block updated counter++; } }
/* Updating some obsolete blocks. Using FIFO-principle. */ void CPathEstimator::Update() { pathCache->Update(); int counter = 0; while(!needUpdate.empty() && counter < BLOCKS_TO_UPDATE) { //Next block in line. SingleBlock sb = needUpdate.front(); needUpdate.pop_front(); int blocknr = sb.block.y * nbrOfBlocksX + sb.block.x; //Check if already updated. if(!(blockState[blocknr].options & PATHOPT_OBSOLETE)) continue; //Update the block. FindOffset(*sb.moveData, sb.block.x, sb.block.y); CalculateVertices(*sb.moveData, sb.block.x, sb.block.y); //Mark as updated. if(sb.moveData==moveinfo->moveData.back()){ blockState[blocknr].options &= ~PATHOPT_OBSOLETE; } //One block updated. counter++; } }
void CPathEstimator::EstimatePathCosts(int minBlock, int maxBlock, int threadID) { assert(maxBlock <= nbrOfBlocks); for (int move = 0; move < moveinfo->moveData.size(); move++) { MoveData* mdi = moveinfo->moveData[move]; if (threadID == -1) { char calcMsg[512]; sprintf(calcMsg, "Blocks %d to %d (block-size %d, path-type %d of %d)", minBlock, maxBlock, BLOCK_SIZE, mdi->pathType, moveinfo->moveData.size()); PrintLoadMsg(calcMsg); } else { boost::mutex::scoped_lock lock(loadMsgMutex); // NOTE: locking PrintLoadMsg() is not enough, can't call it here logOutput.Print("Estimating path costs for blocks %d to %d (block-size %d, path-type %d of %d, thread-ID %d)", minBlock, maxBlock, BLOCK_SIZE, mdi->pathType, moveinfo->moveData.size(), threadID); } for (int idx = minBlock; idx < maxBlock; idx++) { int x = idx % nbrOfBlocksX; int z = idx / nbrOfBlocksX; CalculateVertices(*mdi, x, z, threadID); } } }
void CPathEstimator::EstimatePathCosts(int idx, int thread) { int x = idx % nbrOfBlocksX; int z = idx / nbrOfBlocksX; if (thread == 0 && (idx/1000)!=lastCostMessage) { lastCostMessage=idx/1000; char calcMsg[128]; sprintf(calcMsg, "Path cost: %d of %d (size %d)", lastCostMessage*1000, nbrOfBlocks, BLOCK_SIZE); net->Send(CBaseNetProtocol::Get().SendCPUUsage(0x1 | BLOCK_SIZE | (lastCostMessage<<8))); PrintLoadMsg(calcMsg); } for (vector<MoveData*>::iterator mi = moveinfo->moveData.begin(); mi != moveinfo->moveData.end(); mi++) CalculateVertices(**mi, x, z, thread); }
void CPathEstimator::EstimatePathCosts(int idx, int thread) { const int x = idx % nbrOfBlocksX; const int z = idx / nbrOfBlocksX; if (thread == 0 && idx >= nextCostMessage) { nextCostMessage = idx + blockStates.GetSize() / 16; char calcMsg[128]; sprintf(calcMsg, "PathCosts: precached %d of %d", idx, blockStates.GetSize()); net->Send(CBaseNetProtocol::Get().SendCPUUsage(0x1 | BLOCK_SIZE | (idx<<8))); loadscreen->SetLoadMessage(calcMsg, (idx != 0)); } for (vector<MoveData*>::iterator mi = moveinfo->moveData.begin(); mi != moveinfo->moveData.end(); mi++) { if ((*mi)->unitDefRefCount > 0) { CalculateVertices(**mi, x, z, thread); } } }
/* Constructor. Loading precalculated data. */ CPathEstimator::CPathEstimator(CPathFinder* pf, unsigned int BSIZE, unsigned int mmOpt, string name) : pathFinder(pf), BLOCK_SIZE(BSIZE), BLOCK_PIXEL_SIZE(BSIZE * SQUARE_SIZE), BLOCKS_TO_UPDATE(SQUARES_TO_UPDATE / (BLOCK_SIZE * BLOCK_SIZE) + 1), moveMathOptions(mmOpt) { //Gives the changes in (x,z) when moved one step in given direction. //(Need to be placed befor pre-calculations) directionVector[PATHDIR_LEFT].x = 1; directionVector[PATHDIR_LEFT].y = 0; directionVector[PATHDIR_LEFT_UP].x = 1; directionVector[PATHDIR_LEFT_UP].y = 1; directionVector[PATHDIR_UP].x = 0; directionVector[PATHDIR_UP].y = 1; directionVector[PATHDIR_RIGHT_UP].x = -1; directionVector[PATHDIR_RIGHT_UP].y = 1; directionVector[PATHDIR_RIGHT].x = -1; directionVector[PATHDIR_RIGHT].y = 0; directionVector[PATHDIR_RIGHT_DOWN].x = -1; directionVector[PATHDIR_RIGHT_DOWN].y = -1; directionVector[PATHDIR_DOWN].x = 0; directionVector[PATHDIR_DOWN].y = -1; directionVector[PATHDIR_LEFT_DOWN].x = 1; directionVector[PATHDIR_LEFT_DOWN].y = -1; goalSqrOffset.x=BLOCK_SIZE/2; goalSqrOffset.y=BLOCK_SIZE/2; //Creates the block-map and the vertices-map. nbrOfBlocksX = gs->mapx / BLOCK_SIZE; nbrOfBlocksZ = gs->mapy / BLOCK_SIZE; nbrOfBlocks = nbrOfBlocksX * nbrOfBlocksZ; blockState = SAFE_NEW BlockInfo[nbrOfBlocks]; nbrOfVertices = moveinfo->moveData.size() * nbrOfBlocks * PATH_DIRECTION_VERTICES; vertex = SAFE_NEW float[nbrOfVertices]; openBlockBufferPointer=openBlockBuffer; int i; for(i = 0; i < nbrOfVertices; i++) vertex[i] = PATHCOST_INFINITY; //Initialize blocks. int x, z; for(z = 0; z < nbrOfBlocksZ; z++){ for(x = 0; x < nbrOfBlocksX; x++) { int blocknr = z * nbrOfBlocksX + x; blockState[blocknr].cost = PATHCOST_INFINITY; blockState[blocknr].options = 0; blockState[blocknr].parentBlock.x = -1; blockState[blocknr].parentBlock.y = -1; blockState[blocknr].sqrCenter = SAFE_NEW int2[moveinfo->moveData.size()]; } } //Pre-read/calculate data. PrintLoadMsg("Reading estimate path costs"); if(!ReadFile(name)) { //Generate text-message. char calcMsg[1000], buffer[10]; strcpy(calcMsg, "Analyzing map accessability \""); SNPRINTF(buffer,10,"%d",BLOCK_SIZE); strcat(calcMsg, buffer); strcat(calcMsg, "\""); PrintLoadMsg(calcMsg); //Calculating block-center-offsets. for(z = 0; z < nbrOfBlocksZ; z++) { for(x = 0; x < nbrOfBlocksX; x++) { vector<MoveData*>::iterator mi; for(mi = moveinfo->moveData.begin(); mi < moveinfo->moveData.end(); mi++) { FindOffset(**mi, x, z); } } } //Calculating vectors. vector<MoveData*>::iterator mi; for(mi = moveinfo->moveData.begin(); mi < moveinfo->moveData.end(); mi++) { //Generate text-message. char calcMsg[10000]; sprintf(calcMsg,"Calculating estimate path costs \"%i\" %i/%i",BLOCK_SIZE,(*mi)->pathType,moveinfo->moveData.size()); PrintLoadMsg(calcMsg); //Calculate for(z = 0; z < nbrOfBlocksZ; z++) { for(x = 0; x < nbrOfBlocksX; x++) { CalculateVertices(**mi, x, z); } } } WriteFile(name); } //As all vertexes are bidirectional and having equal values //in both directions, only one value are needed to be stored. //This vector helps getting the right vertex. //(Need to be placed after pre-calculations) directionVertex[PATHDIR_LEFT] = PATHDIR_LEFT; directionVertex[PATHDIR_LEFT_UP] = PATHDIR_LEFT_UP; directionVertex[PATHDIR_UP] = PATHDIR_UP; directionVertex[PATHDIR_RIGHT_UP] = PATHDIR_RIGHT_UP; directionVertex[PATHDIR_RIGHT] = int(PATHDIR_LEFT) - PATH_DIRECTION_VERTICES; directionVertex[PATHDIR_RIGHT_DOWN] = int(PATHDIR_LEFT_UP) - (nbrOfBlocksX * PATH_DIRECTION_VERTICES) - PATH_DIRECTION_VERTICES; directionVertex[PATHDIR_DOWN] = int(PATHDIR_UP) - (nbrOfBlocksX * PATH_DIRECTION_VERTICES); directionVertex[PATHDIR_LEFT_DOWN] = int(PATHDIR_RIGHT_UP) - (nbrOfBlocksX * PATH_DIRECTION_VERTICES) + PATH_DIRECTION_VERTICES; pathCache=SAFE_NEW CPathCache(nbrOfBlocksX,nbrOfBlocksZ); }