Esempio n. 1
0
/**
 * 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);
		}
	}
}
Esempio n. 4
0
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);
}
Esempio n. 5
0
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);
}