/* * calculate requested vertex */ void CPathEstimator::CalculateVertex(const MoveData& moveData, int parentBlockX, int parentBlockZ, unsigned int direction, int threadID) { // initial calculations int parentBlocknr = parentBlockZ * nbrOfBlocksX + parentBlockX; int childBlockX = parentBlockX + directionVector[direction].x; int childBlockZ = parentBlockZ + directionVector[direction].y; int vertexNbr = moveData.pathType * nbrOfBlocks * PATH_DIRECTION_VERTICES + parentBlocknr * PATH_DIRECTION_VERTICES + direction; // outside map? if (childBlockX < 0 || childBlockZ < 0 || childBlockX >= nbrOfBlocksX || childBlockZ >= nbrOfBlocksZ) { vertex[vertexNbr] = PATHCOST_INFINITY; return; } // start position int parentXSquare = blockState[parentBlocknr].sqrCenter[moveData.pathType].x; int parentZSquare = blockState[parentBlocknr].sqrCenter[moveData.pathType].y; float3 startPos = SquareToFloat3(parentXSquare, parentZSquare); // goal position int childBlocknr = childBlockZ * nbrOfBlocksX + childBlockX; int childXSquare = blockState[childBlocknr].sqrCenter[moveData.pathType].x; int childZSquare = blockState[childBlocknr].sqrCenter[moveData.pathType].y; float3 goalPos = SquareToFloat3(childXSquare, childZSquare); // PathFinder definition CRangedGoalWithCircularConstraint pfDef(startPos, goalPos, 0, 1.1f, 2); // the path to find Path path; SearchResult result; if (threadID >= 0) { // since CPathFinder::GetPath() is not thread-safe, // use this thread's "private" CPathFinder instance // (rather than locking pathFinder->GetPath()) if we // are in one result = pathFinders[threadID]->GetPath(moveData, startPos, pfDef, path, false, true, 10000, false); } else { // otherwise use the pathFinder instance passed to // the constructor of this CPathEstimator object result = pathFinder->GetPath(moveData, startPos, pfDef, path, false, true, 10000, false); } // store the result if (result == Ok) { vertex[vertexNbr] = path.pathCost; } else { vertex[vertexNbr] = PATHCOST_INFINITY; } }
/** * Recreate the path taken to the goal */ void CPathEstimator::FinishSearch(const MoveData& moveData, IPath::Path& foundPath) { int2 block = goalBlock; while (block.x != startBlock.x || block.y != startBlock.y) { const int blockIdx = block.y * nbrOfBlocksX + block.x; { // use offset defined by the block const int xBSquare = blockStates[blockIdx].nodeOffsets[moveData.pathType].x; const int zBSquare = blockStates[blockIdx].nodeOffsets[moveData.pathType].y; const float3& pos = SquareToFloat3(xBSquare, zBSquare); foundPath.path.push_back(pos); } // next step backwards block = blockStates[blockIdx].parentNodePos; } if (!foundPath.path.empty()) { foundPath.pathGoal = foundPath.path.front(); } // set some additional information foundPath.pathCost = blockStates[goalBlock.y * nbrOfBlocksX + goalBlock.x].fCost - goalHeuristic; }
/* Recreate the path taken to the goal. */ void CPathEstimator::FinishSearch(const MoveData& moveData, Path& path) { int2 block = goalBlock; while(block.x != startBlock.x || block.y != startBlock.y) { int blocknr = block.y * nbrOfBlocksX + block.x; /* int xGSquare = block.x * BLOCK_SIZE + goalSqrOffset.x; int zGSquare = block.y * BLOCK_SIZE + goalSqrOffset.y; //In first case trying to use a by goal defined offset... if(!moveData.moveMath->IsBlocked(moveData, moveMathOptions, xGSquare, zGSquare)) { float3 pos = SquareToFloat3(xGSquare, zGSquare); pos.y = moveData.moveMath->yLevel(xGSquare, zGSquare); path.path.push_back(pos); } //...if not possible, then use offset defined by the block. else */{ int xBSquare = blockState[blocknr].sqrCenter[moveData.pathType].x; int zBSquare = blockState[blocknr].sqrCenter[moveData.pathType].y; float3 pos = SquareToFloat3(xBSquare, zBSquare); path.path.push_back(pos); } //Next step backwards. block = blockState[blocknr].parentBlock; } //Additional information. path.pathCost = blockState[goalBlock.y * nbrOfBlocksX + goalBlock.x].cost - goalHeuristic; path.pathGoal = path.path.front(); }
/** * Calculate requested vertex */ void CPathEstimator::CalculateVertex(const MoveData& moveData, int parentBlockX, int parentBlockZ, unsigned int direction, int thread) { // initial calculations const int parentBlocknr = parentBlockZ * nbrOfBlocksX + parentBlockX; const int childBlockX = parentBlockX + directionVector[direction].x; const int childBlockZ = parentBlockZ + directionVector[direction].y; const int vertexNbr = moveData.pathType * blockStates.GetSize() * PATH_DIRECTION_VERTICES + parentBlocknr * PATH_DIRECTION_VERTICES + direction; // outside map? if (childBlockX < 0 || childBlockZ < 0 || childBlockX >= nbrOfBlocksX || childBlockZ >= nbrOfBlocksZ) { vertices[vertexNbr] = PATHCOST_INFINITY; return; } // start position const int parentXSquare = blockStates[parentBlocknr].nodeOffsets[moveData.pathType].x; const int parentZSquare = blockStates[parentBlocknr].nodeOffsets[moveData.pathType].y; const float3 startPos = SquareToFloat3(parentXSquare, parentZSquare); // goal position const int childBlocknr = childBlockZ * nbrOfBlocksX + childBlockX; const int childXSquare = blockStates[childBlocknr].nodeOffsets[moveData.pathType].x; const int childZSquare = blockStates[childBlocknr].nodeOffsets[moveData.pathType].y; const float3 goalPos = SquareToFloat3(childXSquare, childZSquare); // PathFinder definition CRangedGoalWithCircularConstraint pfDef(startPos, goalPos, 0, 1.1f, 2); // the path to find IPath::Path path; IPath::SearchResult result; // since CPathFinder::GetPath() is not thread-safe, // use this thread's "private" CPathFinder instance // (rather than locking pathFinder->GetPath()) if we // are in one result = pathFinders[thread]->GetPath(moveData, startPos, pfDef, path, false, true, MAX_SEARCHED_NODES_PE, false, 0, true); // store the result if (result == IPath::Ok) vertices[vertexNbr] = path.pathCost; else vertices[vertexNbr] = PATHCOST_INFINITY; }
/* Calculate requested vertex. */ void CPathEstimator::CalculateVertex(const MoveData& moveData, int parentBlockX, int parentBlockZ, unsigned int direction) { //Initial calculations. int parentBlocknr = parentBlockZ * nbrOfBlocksX + parentBlockX; int childBlockX = parentBlockX + directionVector[direction].x; int childBlockZ = parentBlockZ + directionVector[direction].y; int vertexNbr = moveData.pathType * nbrOfBlocks * PATH_DIRECTION_VERTICES + parentBlocknr * PATH_DIRECTION_VERTICES + direction; //Outside map? if(childBlockX < 0 || childBlockZ < 0 || childBlockX >= nbrOfBlocksX || childBlockZ >= nbrOfBlocksZ) { vertex[vertexNbr] = PATHCOST_INFINITY; return; } //Starting position. int parentXSquare = blockState[parentBlocknr].sqrCenter[moveData.pathType].x; int parentZSquare = blockState[parentBlocknr].sqrCenter[moveData.pathType].y; float3 startPos = SquareToFloat3(parentXSquare, parentZSquare); //Goal position. int childBlocknr = childBlockZ * nbrOfBlocksX + childBlockX; int childXSquare = blockState[childBlocknr].sqrCenter[moveData.pathType].x; int childZSquare = blockState[childBlocknr].sqrCenter[moveData.pathType].y; float3 goalPos = SquareToFloat3(childXSquare, childZSquare); //PathFinder definiton. CRangedGoalWithCircularConstraint pfDef(startPos, goalPos, 0, 1.1f,2); //Path Path path; //Performs the search. SearchResult result = pathFinder->GetPath(moveData, startPos, pfDef, path, false, true,10000,false); //Store the result. if(result == Ok) { vertex[vertexNbr] = path.pathCost; } else { vertex[vertexNbr] = PATHCOST_INFINITY; } }
void QTPFSPathDrawer::UpdateExtraTexture(int extraTex, int starty, int endy, int offset, unsigned char* texMem) const { switch (extraTex) { case CLegacyInfoTextureHandler::drawPathTrav: { const MoveDef* md = GetSelectedMoveDef(); if (md != NULL) { const QTPFS::NodeLayer& nl = pm->nodeLayers[md->pathType]; const float smr = 1.0f / nl.GetMaxRelSpeedMod(); const bool los = (gs->cheatEnabled || gu->spectating); for (int ty = starty; ty < endy; ++ty) { for (int tx = 0; tx < mapDims.hmapx; ++tx) { const int sqx = (tx << 1); const int sqz = (ty << 1); const int texIdx = ((ty * (mapDims.pwr2mapx >> 1)) + tx) * 4 - offset; const bool losSqr = losHandler->InLos(SquareToFloat3(sqx, sqz), gu->myAllyTeam); #if 1 // use node-modifiers as baseline so visualisation is in sync with alt+B const QTPFS::QTNode* node = static_cast<const QTPFS::QTNode*>(nl.GetNode(sqx, sqz)); const float sm = CMoveMath::GetPosSpeedMod(*md, sqx, sqz); const SColor& smc = GetSpeedModColor((los || losSqr)? node->speedModAvg * smr: sm); #else float scale = 1.0f; if (los || losSqr) { if (CMoveMath::IsBlocked(*md, sqx, sqz ) & CMoveMath::BLOCK_STRUCTURE) { scale -= 0.25f; } if (CMoveMath::IsBlocked(*md, sqx + 1, sqz ) & CMoveMath::BLOCK_STRUCTURE) { scale -= 0.25f; } if (CMoveMath::IsBlocked(*md, sqx, sqz + 1) & CMoveMath::BLOCK_STRUCTURE) { scale -= 0.25f; } if (CMoveMath::IsBlocked(*md, sqx + 1, sqz + 1) & CMoveMath::BLOCK_STRUCTURE) { scale -= 0.25f; } } const float sm = CMoveMath::GetPosSpeedMod(md, sqx, sqz); const SColor& smc = GetSpeedModColor(sm * scale); #endif texMem[texIdx + CLegacyInfoTextureHandler::COLOR_R] = smc.r; texMem[texIdx + CLegacyInfoTextureHandler::COLOR_G] = smc.g; texMem[texIdx + CLegacyInfoTextureHandler::COLOR_B] = smc.b; texMem[texIdx + CLegacyInfoTextureHandler::COLOR_A] = smc.a; } } } else { // we have nothing to show -> draw a dark red overlay for (int ty = starty; ty < endy; ++ty) { for (int tx = 0; tx < mapDims.hmapx; ++tx) { const int texIdx = ((ty * (mapDims.pwr2mapx >> 1)) + tx) * 4 - offset; texMem[texIdx + CLegacyInfoTextureHandler::COLOR_R] = 100; texMem[texIdx + CLegacyInfoTextureHandler::COLOR_G] = 0; texMem[texIdx + CLegacyInfoTextureHandler::COLOR_B] = 0; texMem[texIdx + CLegacyInfoTextureHandler::COLOR_A] = 255; } } } } break; case CLegacyInfoTextureHandler::drawPathCost: { } break; }
/* Tells whenever the goal is in range. */ bool CPathFinderDef::IsGoal(int xSquare, int zSquare) const { return ((SquareToFloat3(xSquare, zSquare)-goal).SqLength2D() <= sqGoalRadius); }