Пример #1
0
ZObject3dScan ZDvidInfo::getBlockIndex(const ZObject3dScan &obj) const
{
  ZIntPoint gridSize = m_endBlockIndex - m_startBlockIndex + 1;
  size_t area = ((size_t) gridSize.getX()) * gridSize.getY();
  size_t blockNumber = area * gridSize.getZ();
  std::vector<bool> isAdded(blockNumber, false);

  //std::set<ZIntPoint> blockSet;
  //ZIntPointArray blockArray;
  ZObject3dScan blockObj;

  for (size_t i = 0; i < obj.getStripeNumber(); ++i) {
#ifdef _DEBUG_2
    if (i % 10000 == 0) {
      std::cout << i << "/" << obj.getStripeNumber() << std::endl;
    }
#endif
    const ZObject3dStripe &stripe = obj.getStripe(i);
    int y = stripe.getY();
    int z = stripe.getZ();
    if (y > 0 && z > 0 && y < m_startCoordinates[1] + m_stackSize[1] &&
        z < m_startCoordinates[2] + m_stackSize[2]) {
      for (int j = 0; j < stripe.getSegmentNumber(); ++j) {
        int x0 = stripe.getSegmentStart(j);
        int x1 = stripe.getSegmentEnd(j);
        if (x0 < 0) {
          x0 = 0;
        } else if (x0 >= m_startCoordinates[0] + m_stackSize[0]) {
          x0 = m_startCoordinates[0] + m_stackSize[0] - 1;
        }

        if (x1 < 0) {
          x1 = 0;
        } else if (x1 >= m_startCoordinates[0] + m_stackSize[0]) {
          x1 = m_startCoordinates[0] + m_stackSize[0] - 1;
        }

        ZIntPoint block1 = getBlockIndex(x0, y, z);
        size_t blockIndex1 = area * block1.getZ() +
            gridSize.getY() * block1.getY() + block1.getX();
        ZIntPoint block2 = getBlockIndex(x1, y, z);
        size_t blockIndex2 = area * block2.getZ() +
            gridSize.getY() * block2.getY() + block2.getX();

        if (!isAdded[blockIndex1] || !isAdded[blockIndex2]) {
          blockObj.addSegment(
                block1.getZ(), block1.getY(), block1.getX(), block2.getX(), false);
          isAdded[blockIndex1] = true;
          isAdded[blockIndex2] = true;
        }
      }
    }
  }

  //blockArray.append(blockSet.begin(), blockSet.end());
  blockObj.canonize();

  return blockObj;
}
Пример #2
0
ZObject3dScan ZDvidInfo::getBlockIndex(const ZIntCuboid &box) const
{
  ZIntPoint startIndex = getBlockIndex(box.getFirstCorner());
  ZIntPoint endIndex = getBlockIndex(box.getLastCorner());


  return ZObject3dFactory::MakeObject3dScan(ZIntCuboid(startIndex, endIndex));
}
Пример #3
0
MapAoiBlock* MapAoi::getBlock(int x, int y)
{
	MapAoiBlock* ret = NULL;
	int row = getBlockIndex(x);
	int column = getBlockIndex(y);

	if(row >= 0 && row < m_side_block_num && column >= 0 && column < m_side_block_num)
	{
		ret = m_blocks+row*m_side_block_num+column;
	}

	return ret;
}
Пример #4
0
/* 在文件系统中加载文件,文件大小写入size所指变量,返回bool值表示是否成功 */
bool loadFile(const char *path, uint32_t partitionFirstSector, uint32_t *size) {
    printString("    ");

    firstSector = partitionFirstSector;
    loadSector(firstSector + 2, superBlockBuffer);
    blockSize = (uint32_t) (1024 << superBlock->logBlockSize);
    sectorsPerBlock = blockSize / SECTOR_SIZE_512;

    if (superBlock->magic != EXT2_MAGIC_NUM) {
        printLine("incorrect ext2 magic number");
        return false;
    }
    if (superBlock->revLevel < EXT2_DYNAMIC_REV) {
        printLine("reversion of this ext2 filesystem is too old");
        return false;
    }
    if (blockSize > 0x10000) {
        printLine("block size is too large");
        return false;
    }

    uint32_t targetInode = EXT2_INODE_ROOT;

    for (const char *nameEnd = path; *nameEnd != '\0';) {
        for (path = nameEnd; *path == '/'; ++path);
        for (nameEnd = path; *nameEnd != '/' && *nameEnd != '\0'; ++nameEnd);
        if (nameEnd == path) {
            break;
        }
        targetInode = findChild(targetInode, path, nameEnd - path);
        if (targetInode == EXT2_INODE_NULL) {
            printLine("can't find such file");
            return false;
        }
    };

    Ext2Inode inode = loadInode(targetInode);
    if ((inode.mode & EXT2_MODE_FT_MASK) != EXT2_MODE_FT_REG_FILE) {
        printLine("not a regular file");
        return false;
    } else {
        printString("file found, size: ");
        printInt(inode.size);
        printString(" bytes (");
        printStorageSize(inode.size);
        printLine(")");
    }

    uint32_t blkCnt = inode.size / blockSize + (inode.size % blockSize != 0);
    for (uint32_t blockOffset = 0; blockOffset < blkCnt; ++blockOffset) {
        uint32_t block = getBlockIndex(&inode, blockOffset);
        if (!readFileSectorsToBuffer(lbaOfBlock(block), sectorsPerBlock)) {
            return false;
        }
    }

    *size = inode.size;
    return true;
}
Пример #5
0
// TODO YukigassenChunkRoom should probably pass a pointer to an object that can store the triangles and filaments instead of passing pointer to itself.
void YukigassenVoxelMap::setupInternalRenderingDataLocal(const YukigassenChunkRoom *ybr, YukigassenChunk *yukigassenChunk)
{
	assert(ybr==getParentObj());
/*void YukigassenVoxelMap::setupInternalRenderingDataLocal(YukigassenChunk *yukigassenChunk)
{
	const YukigassenChunkRoom *ybr=dynamic_cast<const YukigassenChunkRoom *>(getParentObj());*/
	if (ybr!=NULL)
	{
		const float bsx2 = 0.5f * ybr->blockSizeX();
		const float bsy2 = 0.5f * ybr->blockSizeY();
		const float bsz2 = 0.5f * ybr->blockSizeZ();

		const int subXo=ybr->translateToVoxelMapIndexX(geographicIndex)*mapSizeInBlocks.x;
		const int subYo=ybr->translateToVoxelMapIndexY(geographicIndex)*mapSizeInBlocks.y;
		const int subZo=ybr->translateToVoxelMapIndexZ(geographicIndex)*mapSizeInBlocks.z;


		//addLineBox(0.0f, 0.0f, 0.0f, rsx2, rsy2, rsz2);

		//printf("setupInternalRenderingDataLocal: %d %d %d\n", subXo, subYo, subZo);

	    for(size_t lx=0;lx<mapSizeInBlocks.x;lx++)
	    {
	        for(size_t ly=0;ly<mapSizeInBlocks.y;ly++)
	        {
	            for(size_t lz=0;lz<mapSizeInBlocks.z;lz++)
	            {
	            	const long long blockIndex = getBlockIndex(lx,ly,lz);

					const int b = getVoxel(blockIndex);
					if (!YukigassenChunk::getBlockInvisible(b))
					{
						int rx=subXo+lx;
						int ry=subYo+ly;
						int rz=subZo+lz;

						// TODO Would be much faster to not do this via parent unless needed.
						int neighborMask = ybr->getNeighborMaskXp(rx,ry,rz) | ybr->getNeighborMaskYp(rx,ry,rz) | ybr->getNeighborMaskZp(rx,ry,rz) | ybr->getNeighborMaskXn(rx,ry,rz) | ybr->getNeighborMaskYn(rx,ry,rz) | ybr->getNeighborMaskZn(rx,ry,rz);
						//int neighborMask=0x1f;

						float xc = ybr->translateBlockToCoordinatesX(rx);
						float yc = ybr->translateBlockToCoordinatesY(ry);
						float zc = ybr->translateBlockToCoordinatesZ(rz);

						//printf("setupInternalRenderingDataLocal: %f %f %f  %03x %d\n", xc, yc, zc, neighborMask, b);
						//if ((bsx2==bsy2) && (bsy2==bsz2)) {};
						if (neighborMask!=0x3F)
						{
							yukigassenChunk->addTriangleBox(xc, yc, zc, bsx2, bsy2, bsz2, neighborMask, b);
						}
	            	}
	            }
	        }
	    }

	}
}
Пример #6
0
const TilePtr& Map::getTile(const Position& pos)
{
    if(!pos.isMapPosition())
        return m_nulltile;
    auto it = m_tileBlocks[pos.z].find(getBlockIndex(pos));
    if(it != m_tileBlocks[pos.z].end())
        return it->second.get(pos);
    return m_nulltile;
}
Пример #7
0
ZObject3dScan ZDvidInfo::getBlockIndex(const ZIntCuboidArray &boxArray) const
{
  ZObject3dScan obj;
  for (ZIntCuboidArray::const_iterator iter = boxArray.begin();
       iter != boxArray.end(); ++iter) {
    const ZIntCuboid &box = *iter;
    obj.unify(getBlockIndex(box));
  }

  return obj;
}
Пример #8
0
void ThreadedDyscoColumn<DataType>::putValues(casacore::uInt rowNr, const casacore::Array<DataType>* dataPtr)
{
	if(!areOffsetsInitialized())
	{
		// If the manager did not initialize its offsets yet, then it is determined
		// from the first "time block" (a block with the same time, field and spw) that
		// is written into the measurement set.
		//
		// This only happens when a new measurement
		// set was created; if an existing measurement set is opened with at least one block,
		// then the offsets will be read from the headers.
		//
		// A consequence of this is that the first blocks in a new measurement set are required to
		// be written consecutively.
		double time = (*_timeCol)(rowNr);
		int fieldId = (*_fieldCol)(rowNr);
		int dataDescId = (*_dataDescIdCol)(rowNr);
		if(_timeBlockBuffer->Empty())
		{
			// This is the first row written
			_currentBlock = 0;
			_lastWrittenTime = time;
			_lastWrittenField = fieldId;
			_lastWrittenDataDescId = dataDescId;
		}
		else if(time != _lastWrittenTime || fieldId != _lastWrittenField || dataDescId != _lastWrittenDataDescId)
		{
			initializeRowsPerBlock(rowNr, _timeBlockBuffer->MaxAntennaIndex() + 1);
		}
	}
	
	const int ant1 = (*_ant1Col)(rowNr), ant2 = (*_ant2Col)(rowNr);
	if(areOffsetsInitialized())
	{
		const size_t
			blockIndex = getBlockIndex(rowNr),
			blockRow = getRowWithinBlock(rowNr);
		
		// Is this the first row of a new block?
		if(blockIndex != _currentBlock)
		{
			if(_isCurrentBlockChanged)
				storeBlock();
			
			// Load new block
			loadBlock(blockIndex);
		}
		_timeBlockBuffer->SetData(blockRow, ant1, ant2, dataPtr->data());
	}
	else {
		_timeBlockBuffer->SetData(rowNr, ant1, ant2, dataPtr->data());
	}
	_isCurrentBlockChanged = true;
}
Пример #9
0
const TilePtr& Map::getOrCreateTile(const Position& pos)
{
    if(!pos.isMapPosition())
        return m_nulltile;
    if(pos.x < m_tilesRect.left())
        m_tilesRect.setLeft(pos.x);
    if(pos.y < m_tilesRect.top())
        m_tilesRect.setTop(pos.y);
    if(pos.x > m_tilesRect.right())
        m_tilesRect.setRight(pos.x);
    if(pos.y > m_tilesRect.bottom())
        m_tilesRect.setBottom(pos.y);
    TileBlock& block = m_tileBlocks[pos.z][getBlockIndex(pos)];
    return block.getOrCreate(pos);
}
Пример #10
0
double getBlockHardness(int height) {
    const CBlockIndex* blockindex = getBlockIndex(height);

    int nShift = (blockindex->nBits >> 24) & 0xff;

    double dDiff =
        (double)0x0000ffff / (double)(blockindex->nBits & 0x00ffffff);

    while (nShift < 29) {
        dDiff *= 256.0;
        nShift++;
    }

    while (nShift > 29) {
        dDiff /= 256.0;
        nShift--;
    }

    return dDiff;
}
Пример #11
0
void ThreadedDyscoColumn<DataType>::getValues(casacore::uInt rowNr, casacore::Array<DataType>* dataPtr)
{
	if(!areOffsetsInitialized())
	{
		// Trying to read before first block was written -- return zero
		// TODO if a few rows were written of the first block, those are
		// incorrectly returned. This is a rare case but can be fixed.
		for(typename casacore::Array<DataType>::contiter i=dataPtr->cbegin(); i!=dataPtr->cend(); ++i)
			*i = DataType();
	}
	else {
		size_t blockIndex = getBlockIndex(rowNr);
		if(blockIndex >= nBlocksInFile())
		{
			// Trying to read a row that was not stored yet -- return zero
			for(typename casacore::Array<DataType>::contiter i=dataPtr->cbegin(); i!=dataPtr->cend(); ++i)
				*i = DataType();
		}
		else {
			mutex::scoped_lock lock(_mutex);
			// Wait until the block to be read is not in the write cache
			typename cache_t::const_iterator cacheItemPtr = _cache.find(blockIndex);
			while(cacheItemPtr != _cache.end())
			{
				_cacheChangedCondition.wait(lock);
				cacheItemPtr = _cache.find(blockIndex);
			}
			lock.unlock();
			
			if(_currentBlock != blockIndex)
			{
				if(_isCurrentBlockChanged)
					storeBlock();
				loadBlock(blockIndex);
			}
			
			// The time block encoder is now initialized and contains the unpacked block.
			_timeBlockBuffer->GetData(getRowWithinBlock(rowNr), dataPtr->data());
		}
	}
}
Пример #12
0
void Map::cleanTile(const Position& pos)
{
    if(!pos.isMapPosition())
        return;
    auto it = m_tileBlocks[pos.z].find(getBlockIndex(pos));
    if(it != m_tileBlocks[pos.z].end()) {
        TileBlock& block = it->second;
        if(const TilePtr& tile = block.get(pos)) {
            tile->clean();
            if(tile->canErase())
                block.remove(pos);

            notificateTileUpdate(pos);
        }
    }
    for(auto it = m_staticTexts.begin();it != m_staticTexts.end();) {
        const StaticTextPtr& staticText = *it;
        if(staticText->getPosition() == pos && staticText->getMessageMode() == Otc::MessageNone)
            it = m_staticTexts.erase(it);
        else
            ++it;
    }
}
BOOL WINAPI SFileOpenFileEx(HANDLE hArchive, char * fileName, int something, HANDLE * hFile)
{
    TMPQArchive * ha = (TMPQArchive *)hArchive;
    TMPQFile    * hf;
    TMPQBlock   * block;                // File block
    DWORD         blockIndex;           // Found table index

    if(hFile != NULL)
        *hFile = NULL;

    if(hArchive == NULL || fileName == NULL || *fileName == 0 || hFile == NULL)
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    // If opened file is simple PLAIN file
    if(ha->header->id != ID_MPQ)
    {
        // Allocate file handle
        if((hf = new TMPQFile) == NULL)
        {
            SetLastError(ERROR_NOT_ENOUGH_MEMORY);
            return FALSE;
        }

        // Initialize file handle
        memset(hf, 0, sizeof(TMPQFile));
        hf->hFile    = ha->hFile;
        hf->hArchive = ha;

        *hFile = hf;
    }

    // Get block index from file name
    blockIndex = getBlockIndex(ha, fileName);

    // If index was not found, or is greater than number of files, exit.
    if(blockIndex == -1 || blockIndex > ha->header->nFiles)
    {
        SetLastError(ERROR_FILE_NOT_FOUND);
        return FALSE;
    }

    // Get block and test it
    block = ha->block + blockIndex;
    if(block->fsize == 0 || (block->flags & 0x80000000) == 0)
    {
        SetLastError(ERROR_BAD_FORMAT);
        return FALSE;
    }

    // Skip ':' in the file name
    while(strchr(fileName, '\\') != NULL)
        fileName = strchr(fileName, '\\') + 1;

    // Allocate file handle (ESI = hFile);
    // EBP - block
    if((hf = new TMPQFile) == NULL)
    {
        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
        return FALSE;
    }

    // Initialize file handle
    memset(hf, 0, sizeof(TMPQFile));
    hf->hFile    = INVALID_HANDLE_VALUE;
    hf->hArchive = ha;
    hf->block    = block;
    hf->nBlocks  = (hf->block->fsize + ha->blockSize - 1) / ha->blockSize;
    hf->seed1    = decryptFileSeed(fileName, stormBuffer);

    if(hf->block->flags & MPQ_FILE_FIXSEED)
        hf->seed1 = (hf->seed1 + hf->block->filePos - ha->mpqPos) ^ hf->block->fsize;

    // Allocate buffers for decompression.
    if(hf->block->flags & MPQ_FILE_COMPRESSED)
    {
        // Buffer for decompressed data. Always must be 0x1000 bytes length,
        // because this is length of decompressed block required by PKWARE data compression library.
//      hf->buffer = new BYTE[0x1000];
        
        // Allocate buffer for block positions. At the begin of file are stored
        // DWORDs holding positions of each block relative from begin of file in the archive
        if((hf->blockPos = new DWORD[hf->nBlocks + 1]) == NULL)
        {
            SetLastError(ERROR_NOT_ENOUGH_MEMORY);
            return FALSE;
        }
    }
    *hFile = hf;
    return TRUE;
}
Пример #14
0
static uint32_t findChild(
        uint32_t dirInode, const char *childName, uint32_t nameLen) {
    Ext2Inode inode = loadInode(dirInode);
    if ((inode.mode & EXT2_MODE_FT_MASK) != EXT2_MODE_FT_DIR) {
        return EXT2_INODE_NULL;
    }

    /* 目录项一定占用整数个块,blkCnt */
    uint32_t blkCnt = inode.size / blockSize + (inode.size % blockSize != 0);
    /* 一个目录项不可能跨块,但可能跨扇区,用第二个缓冲区作为副缓冲区 */
    uint8_t buffers[2][SECTOR_SIZE_512];
    uint32_t bufferedSector2 = 0;
    /* 当前的目录项和下一个目录项的指针 */
    Ext2DirEntry *curEntry;
    Ext2DirEntry *nextEntry;

    /* 遍历目录文件的每一个块 */
    for (uint32_t blockOffset = 0; blockOffset < blkCnt; ++blockOffset) {

        uint32_t block = getBlockIndex(&inode, blockOffset);
        if (block == INVALID_DATA_BLOCK) {
            return EXT2_INODE_NULL;
        }

        nextEntry = (Ext2DirEntry *) &buffers[0];

        /* 遍历目录文件的每一个扇区 */
        for (uint32_t sectorOffset = 0; sectorOffset < sectorsPerBlock;) {

            /* 副缓冲区本用作存储长文件名,但若其中有对应扇区,复制之,避免IO */
            uint32_t sector = lbaOfBlock(block) + sectorOffset;
            if (sector == bufferedSector2) {
                for (uint32_t i = 0; i < SECTOR_SIZE_512; ++i) {
                    buffers[0][i] = buffers[1][i];
                }
            } else {
                loadSector(sector, buffers[0]);
            }

            /* 遍历目录项,不确定退出时机 */
            for (;;) {
                /* 空目录项或者文件名不相等就直接跳过 */
                if ((curEntry = nextEntry)->inode != EXT2_INODE_NULL &&
                        curEntry->nameLen == nameLen) {

                    /* 如果文件名跨扇区,就要用副缓冲区延伸保存了 */
                    if (((uintptr_t) curEntry + offsetof(Ext2DirEntry, name) +
                            curEntry->nameLen) >=
                            (uintptr_t) &buffers[0] + SECTOR_SIZE_512) {
                        bufferedSector2 = sector + 1;
                        loadSector(bufferedSector2, buffers[1]);
                    }

                    /* 文件名一致就返回正确inode */
                    for (uint32_t i = 0; i < nameLen; ++i) {
                        if (curEntry->name[i] != childName[i]) {
                            break;
                        }
                        if (i == nameLen - 1) {
                            return curEntry->inode;
                        }
                    }
                }

                /* next是nextEntry的uintptr_t形式表达 */
                uintptr_t next = (uintptr_t) curEntry + curEntry->recLen;
                /* 下一个目录项是否超过扇区大小 */
                if (next >= (uintptr_t) &buffers[0] + SECTOR_SIZE_512) {
                    /* 是则要增加扇区偏移并且回滚nextEntry值,并结束当前扇区 */
                    uintptr_t offset = next - (uintptr_t) &buffers[0];
                    sectorOffset += offset / SECTOR_SIZE_512;
                    next = (uintptr_t) &buffers[0] + offset % SECTOR_SIZE_512;
                    nextEntry = (Ext2DirEntry *) next;
                    break;
                } else {
                    /* 否则继续在本扇区寻找 */
                    nextEntry = (Ext2DirEntry *) next;
                }
            }
        }
    }

    return EXT2_INODE_NULL;
}
Пример #15
0
YukigassenVoxelMap::YukigassenVoxelMap() :
	MirrorContainer(),
	geographicIndex(-1),
	mapSizeInBlocks(0,0,0),
	voxelMap(NULL)
#ifdef NEIGBOUR_MAP
	neighbourMap(NULL),
#endif
{
}


YukigassenVoxelMap::~YukigassenVoxelMap() {
	free(voxelMap);
#ifdef NEIGBOUR_MAP
	free(neighbourMap);
#endif
}


void YukigassenVoxelMap::readSelf(WordReader *wr)
{
	MirrorContainer::readSelf(wr);

	free(voxelMap); // Free old data area if any
#ifdef NEIGBOUR_MAP
	free(neighbourMap); // Free old data area if any
#endif

	geographicIndex = wr->readLong();

	mapSizeInBlocks.readSelf(wr);

	size_t voxelMapSize = mapSizeInBlocks.x * mapSizeInBlocks.y * mapSizeInBlocks.z;

	voxelMap = (char *)malloc(voxelMapSize); // free is done in destructor free(voxelMap);
	assert(voxelMap!=NULL);
#ifdef NEIGBOUR_MAP
	neighbourMap = (char *)malloc(voxelMapSize);
	assert(neighbourMap!=NULL);
#endif

    for(size_t x=0;x<mapSizeInBlocks.x;x++)
    {
        for(size_t y=0;y<mapSizeInBlocks.y;y++)
        {
            for(size_t z=0;z<mapSizeInBlocks.z;z++)
            {
            	const int b=wr->readInt();
            	const int index = getBlockIndex(x,y,z);
            	voxelMap[index]=b;
            }
        }
    }

#ifdef NEIGBOUR_MAP
    // Calculate neighbourMask
    for(size_t x=0;x<mapSizeInBlocks.x;x++)
    {
        for(size_t y=0;y<mapSizeInBlocks.y;y++)
        {
            for(size_t z=0;z<mapSizeInBlocks.z;z++)
            {
            	const int index = getBlockIndex(x,y,z);

            	neighbourMap[index] = getNeighborMaskXp(x,y,z) | getNeighborMaskYp(x,y,z) | getNeighborMaskZp(x,y,z) | getNeighborMaskXn(x,y,z) | getNeighborMaskYn(x,y,z) | getNeighborMaskZn(x,y,z);
            }
        }
    }
#endif
}
Пример #16
0
void Chunk::initBlock(vec3ui8 intraChunkCoords, uint8 type) {
	blocks[getBlockIndex(intraChunkCoords)] = type;
}
Пример #17
0
ZIntPoint ZDvidInfo::getBlockIndex(const ZIntPoint &blockIndex) const
{
  return getBlockIndex(blockIndex.getX(), blockIndex.getY(), blockIndex.getZ());
}
Пример #18
0
void Chunk::makePassThroughs() {
	if (numAirBlocks > SIZE - WIDTH * WIDTH) {
		passThroughs = 0x7FFF;
		return;
	} else if (numAirBlocks == 0) {
		passThroughs = 0x0000;
		return;
	}
	passThroughs = 0;
	bool visited[SIZE];

	for (uint i = 0; i < SIZE; i++) {
		visited[i] = false;
	}

	size_t index = 0;
	uint foundAirBlocks = 0;
	for (uint8 z = 0; z < WIDTH; z++) {
		for (uint8 y = 0; y < WIDTH; y++) {
			for (uint8 x = 0; x < WIDTH; x++) {
				visited[index] = true;
				if (blocks[index] != 0) {
					index++;
					continue;
				}

				vec3ui8 fringe[SIZE];
				fringe[0] = vec3ui8(x, y, z);
				int fringeSize = 1;
				int borderSet = 0;
				while (fringeSize > 0) {
					foundAirBlocks++;
					vec3ui8 icc = fringe[--fringeSize];
					for (int d = 0; d < 6; d++) {
						if (icc[DIR_DIMS[d]] == (1 - d / 3) * (WIDTH - 1))
							borderSet |= (1 << d);
						else {
							vec3ui8 nIcc = icc + DIRS[d].cast<uint8>();
							size_t nIndex = getBlockIndex(nIcc);
							if (blocks[nIndex] == 0 && !visited[nIndex]) {
								visited[nIndex] = true;
								fringe[fringeSize++] = nIcc;
							}
						}
					}
				}

				int shift = 0;
				for (int d1 = 0; d1 < 5; d1++) {
					if (borderSet & (1 << d1)) {
						for (int d2 = d1 + 1; d2 < 6; d2++) {
							if (borderSet & (1 << d2))
								passThroughs |= (1 << shift);
							shift++;
						}
					} else
						shift += 5 - d1;
				}

				if (foundAirBlocks >= numAirBlocks)
					return;

				index++;
			}
		}
	}
}
Пример #19
0
uint8 Chunk::getBlock(vec3ui8 icc) const {
	return blocks[getBlockIndex(icc)];
}