fov.cpp
来自「奇趣公司比较新的qt/emd版本」· C++ 代码 · 共 1,124 行 · 第 1/3 页
CPP
1,124 行
// +---++---++---+ // | || || | // | || || @ | // | || || | // +---++---++---+ // else { if(prevBlocked) { startSlope=this->invSlope((double)xCenter+0.5,(double)yCenter+0.5,(double)xCheck,(double)yCheck); } prevBlocked=false; } } // if the last cell of the scan didn't block LOS a new scan should be // started if(!prevBlocked) { this->scanNW2W(map,xCenter,yCenter,distance+1,maxRadius,startSlope,endSlope); }}/* scanSW2W scans the octant covering the area from southe west to west from bottom to top the method ignores the octants starting and ending cells since they have been applied in FOV::start*/void FOV::scanSW2W(OublietteLevel *map, int xCenter, int yCenter, int distance, int maxRadius, double startSlope, double endSlope){ if(distance > maxRadius) { return; } // calculate start and end cell of the scan int yStart=(int)((double)yCenter + 0.5 - (startSlope * distance)); int yEnd=(int)((double)yCenter + 0.5 - (endSlope * distance)); int xCheck=xCenter - distance; // is starting cell the bottommost cell in the octant? // NO: call applyCell() to starting cell // YES: it has already been applied in FOV::start() if(yStart != yCenter-(-1*distance)) { this->applyCell(map,xCheck,yStart); } // find out if starting cell blocks LOS bool prevBlocked=this->scanCell(map,xCheck,yStart); // scan from the cell after the starting cell (yStart-1) to end cell of // scan (yCheck>=yEnd) for(int yCheck=yStart-1; yCheck>=yEnd; yCheck--) { // is the current cell the topmost cell in the octant? // NO: call applyCell() to current cell // YES: it has already been applied in FOV::start() if(yCheck != yCenter) { // apply cell this->applyCell(map,xCheck,yCheck); } // cell blocks LOS // if previous cell didn't block LOS (prevBlocked==false) we have // hit a 'new' section of walls. a new scan will be started with an // endSlope that 'brushes' by the bottom of the blocking cell // // +---++---++---+ @ = [xCenter+0.5,yCenter+0.5] // | || || | a = old [xCheck,yCheck] // | || || @ | b = new [xCheck+0.99999,yCheck+1] // | || || | // +---++---++---+ // a####+---++---+ // #####| || | // #####| || | // #####| || | // #####+---++---+ // +---b+---++---+ // | || || | // | || || | // | || || | // +---++---++---+ // if(this->scanCell(map,xCheck,yCheck)) { if(!prevBlocked) { this->scanSW2W(map,xCenter,yCenter,distance+1,maxRadius,startSlope,this->invSlope((double)xCenter+0.5,(double)yCenter+0.5,(double)xCheck+0.99999,(double)yCheck+1)); } prevBlocked=true; } // cell doesn't block LOS // if the cell is the first non-blocking cell after a section of walls // we need to calculate a new startSlope that 'brushes' by the top of // the blocking cells // // +---++---++---+ @ = [xCenter+0.5,yCenter+0.5] // | || || | a = old [xCheck,yCheck] // | || || @ | b = new [xCheck,yCheck+0.99999] // | || || | // +---++---++---+ // a---++---++---+ // | || || | // | || || | // | || || | // b---++---++---+ // #####+---++---+ // #####| || | // #####| || | // #####| || | // #####+---++---+ // else { if(prevBlocked) { startSlope=this->invSlope((double)xCenter+0.5,(double)yCenter+0.5,(double)xCheck,(double)yCheck+0.99999); } prevBlocked=false; } } // if the last cell of the scan didn't block LOS a new scan should be // started if(!prevBlocked) { this->scanSW2W(map,xCenter,yCenter,distance+1,maxRadius,startSlope,endSlope); }}/* scanSW2S scans the octant covering the area from south west to south from left to right the method ignores the octants starting and ending cells since they have been applied in FOV::start*/void FOV::scanSW2S(OublietteLevel *map, int xCenter, int yCenter, int distance, int maxRadius, double startSlope, double endSlope){ if(distance > maxRadius) { return; } // calculate start and end cell of the scan int xStart=(int)((double)xCenter + 0.5 + (startSlope * distance)); int xEnd=(int)((double)xCenter + 0.5 + (endSlope * distance)); int yCheck=yCenter + distance; // is the starting cell the leftmost cell in the octant? // NO: call applyCell() to starting cell // YES: it has already been applied in FOV::start() if(xStart != xCenter+(-1*distance)) { this->applyCell(map,xStart,yCheck); } // find out if starting cell blocks LOS bool prevBlocked=this->scanCell(map,xStart,yCheck); // scan from the cell after the starting cell (xStart+1) to end cell of // scan (xCheck<=xEnd) for(int xCheck=xStart+1; xCheck<=xEnd; xCheck++) { // is the current cell the rightmost cell in the octant? // NO: call applyCell() to current cell // YES: it has already been applied in FOV::start() if(xCheck != xCenter) { // apply cell this->applyCell(map,xCheck,yCheck); } // cell blocks LOS // if previous cell didn't block LOS (prevBlocked==false) we have // hit a 'new' section of walls. a new scan will be started with an // endSlope that 'brushes' by to the left of the blocking cell // // +---++---++---+ // | || || | // | || || @ | // | || || | // +---++---++---+ // +---ba####+---+ @ = [xCenter+0.5,yCenter+0.5] // | |#####| | a = old [xCheck,yCheck] // | |#####| | b = new [xCheck-0.00001,yCheck] // | |#####| | // +---+#####+---+ // if(this->scanCell(map,xCheck,yCheck)) { if(!prevBlocked) { this->scanSW2S(map,xCenter,yCenter,distance+1,maxRadius,startSlope,this->slope((double)xCenter+0.5,(double)yCenter+0.5,(double)xCheck-0.00001,(double)yCheck)); } prevBlocked=true; } // cell doesn't block LOS // if the cell is the first non-blocking cell after a section of walls // we need to calculate a new startSlope that 'brushes' by to the right // of the blocking cells // // +---++---++---+ // | || || | // | || || @ | // | || || | // +---++---++---+ // #####a---++---+ @ = [xCenter+0.5,yCenter+0.5] // #####| || | a = old [xCheck,yCheck] // #####| || | b = new [xCheck,yCheck+0.99999] // #####| || | // #####b---++---+ // else { if(prevBlocked) { startSlope=this->slope((double)xCenter+0.5,(double)yCenter+0.5,(double)xCheck,(double)yCheck+0.99999); } prevBlocked=false; } } // if the last cell of the scan didn't block LOS a new scan should be // started if(!prevBlocked) { this->scanSW2S(map,xCenter,yCenter,distance+1,maxRadius,startSlope,endSlope); }}/* scanSE2S scans the octant covering the area from south east to south from right to left the method ignores the octants starting and ending cells since they have been applied in FOV::start*/void FOV::scanSE2S(OublietteLevel *map, int xCenter, int yCenter, int distance, int maxRadius, double startSlope, double endSlope){ if(distance > maxRadius) { return; } // calculate start and end cell of the scan int xStart=(int)((double)xCenter + 0.5 + (startSlope * distance)); int xEnd=(int)((double)xCenter + 0.5 + (endSlope * distance)); int yCheck=yCenter + distance; // is starting cell the rightmost cell in the octant? // NO: call applyCell() to starting cell // YES: it has already been applied in FOV::start() if(xStart != xCenter+(1*distance)) { this->applyCell(map,xStart,yCheck); } // find out if starting cell blocks LOS bool prevBlocked=this->scanCell(map,xStart,yCheck); // scan from the cell after the starting cell (xStart-1) to end cell of // scan (xCheck>=xEnd) for(int xCheck=xStart-1; xCheck>=xEnd; xCheck--) { // is the current cell the leftmost cell in the octant? // NO: call applyCell() to current cell // YES: it has already been applied in FOV::start() if(xCheck != xCenter) { // apply cell this->applyCell(map,xCheck,yCheck); } // cell blocks LOS // if previous cell didn't block LOS (prevBlocked==false) we have // hit a 'new' section of walls. a new scan will be started with an // endSlope that 'brushes' by to the right of the blocking cell // // +---++---++---+ // | || || | // | @ || || | // | || || | // +---++---++---+ // +---+a####b---+ @ = [xCenter+0.5,yCenter+0.5] // | |#####| | a = old [xCheck,yCheck] // | |#####| | b = new [xCheck+1,yCheck] // | |#####| | // +---+#####+---+ // if(this->scanCell(map,xCheck,yCheck)) { if(!prevBlocked) { this->scanSE2S(map,xCenter,yCenter,distance+1,maxRadius,startSlope,this->slope((double)xCenter+0.5,(double)yCenter+0.5,(double)xCheck+1,(double)yCheck)); } prevBlocked=true; } // cell doesn't block LOS // if the cell is the first non-blocking cell after a section of walls // we need to calculate a new startSlope that 'brushes' by to the left // of the blocking cells // // +---++---++---+ // | || || | // | @ || || | // | || || | // +---++---++---+ // +---+a---+##### @ = [xCenter+0.5,yCenter+0.5] // | || |##### a = old [xCheck,yCheck] // | || |##### b = new [xCheck+0.99999,yCheck+0.99999] // | || |##### // +---++---b##### // else { if(prevBlocked) { startSlope=this->slope((double)xCenter+0.5,(double)yCenter+0.5,(double)xCheck+0.99999,(double)yCheck+0.99999); } prevBlocked=false; } } // if the last cell of the scan didn't block LOS a new scan should be // started if(!prevBlocked) { this->scanSE2S(map,xCenter,yCenter,distance+1,maxRadius,startSlope,endSlope); }}/* scanNE2E scans the octant covering the area from north east to east from top to bottom the method ignores the octants starting and ending cells since they have been applied in FOV::start*/void FOV::scanNE2E(OublietteLevel *map, int xCenter, int yCenter, int distance, int maxRadius, double startSlope, double endSlope){ if(distance > maxRadius) { return; } // calculate start and end cell of the scan int yStart=(int)((double)yCenter + 0.5 + (startSlope * distance)); int yEnd=(int)((double)yCenter + 0.5 + (endSlope * distance)); int xCheck=xCenter + distance; // is starting cell the topmost cell in the octant? // NO: call applyCell() to starting cell // YES: it has already been applied in FOV::start() if(yStart != yCenter+(-1*distance)) { this->applyCell(map,xCheck,yStart); } // find out if starting cell blocks LOS bool prevBlocked=this->scanCell(map,xCheck,yStart); // scan from the cell after the starting cell (yStart+1) to end cell of // scan (yCheck<=yEnd) for(int yCheck=yStart+1; yCheck<=yEnd; yCheck++) { // is the current cell the bottommost cell in the octant? // NO: call applyCell() to current cell
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?