//len = len(RecordHeader + RecordContent) //TODO: not enough length checking RecordHeader RecordPage::allocRecordHeader(int len, int& slotID){ slotID = -1; if (getFreelen() < len){ cout<<"not enough space for RecordHeader"; return RecordHeader(); } for (int i = 0; i < get_rcdnum(); i++) if (isEmptyAt(i)) { slotID = i + 1; break; } if (slotID == -1){ set_rcdnum(get_rcdnum() + 1); slotID = get_rcdnum(); } set_offset(slotID - 1, get_freeptr()); set_rcdlen(slotID - 1, len); set_freeptr(get_freeptr() + len); return RecordHeader(data + get_offset(slotID - 1)); }
void TerrainFile::updateGrid( const Point2I &minPt, const Point2I &maxPt ) { // here's how it works: // for the current terrain renderer we only care about // the minHeight and maxHeight on the GridSquare // so we do one pass through, updating minHeight and maxHeight // on the level 0 squares, then we loop up the grid map from 1 to // the top, expanding the bounding boxes as necessary. // this should end up being way, way, way, way faster for the terrain // editor PROFILE_SCOPE( TerrainFile_UpdateGrid ); for ( S32 y = minPt.y - 1; y < maxPt.y + 1; y++ ) { for ( S32 x = minPt.x - 1; x < maxPt.x + 1; x++ ) { S32 px = x; S32 py = y; if ( px < 0 ) px += mSize; if ( py < 0 ) py += mSize; TerrainSquare *sq = findSquare( 0, px, py ); sq->minHeight = 0xFFFF; sq->maxHeight = 0; // Update the empty state. if ( isEmptyAt( x, y ) ) sq->flags |= TerrainSquare::Empty; else sq->flags &= ~TerrainSquare::Empty; getMinMax( sq->minHeight, sq->maxHeight, getHeight( x, y ) ); getMinMax( sq->minHeight, sq->maxHeight, getHeight( x+1, y ) ); getMinMax( sq->minHeight, sq->maxHeight, getHeight( x, y+1 ) ); getMinMax( sq->minHeight, sq->maxHeight, getHeight( x+1, y+1 ) ); } } // ok, all the level 0 grid squares are updated: // now update all the parent grid squares that need to be updated: for( S32 level = 1; level <= mGridLevels; level++ ) { S32 size = 1 << level; S32 halfSize = size >> 1; for( S32 y = (minPt.y - 1) >> level; y < (maxPt.y + size) >> level; y++ ) { for ( S32 x = (minPt.x - 1) >> level; x < (maxPt.x + size) >> level; x++ ) { S32 px = x << level; S32 py = y << level; TerrainSquare *sq = findSquare(level, px, py); sq->minHeight = 0xFFFF; sq->maxHeight = 0; sq->flags &= ~( TerrainSquare::Empty | TerrainSquare::HasEmpty ); checkSquare( sq, findSquare( level - 1, px, py ) ); checkSquare( sq, findSquare( level - 1, px + halfSize, py ) ); checkSquare( sq, findSquare( level - 1, px, py + halfSize ) ); checkSquare( sq, findSquare( level - 1, px + halfSize, py + halfSize ) ); } } } }
void TerrainFile::_buildGridMap() { // The grid level count is the same as the // most significant bit of the size. While // we loop we take the time to calculate the // grid memory pool size. mGridLevels = 0; U32 size = mSize; U32 poolSize = size * size; while ( size >>= 1 ) { poolSize += size * size; mGridLevels++; } mGridMapPool.setSize( poolSize ); mGridMapPool.compact(); mGridMap.setSize( mGridLevels + 1 ); mGridMap.compact(); // Assign memory from the pool to each grid level. TerrainSquare *sq = mGridMapPool.address(); for ( S32 i = mGridLevels; i >= 0; i-- ) { mGridMap[i] = sq; sq += 1 << ( 2 * ( mGridLevels - i ) ); } for( S32 i = mGridLevels; i >= 0; i-- ) { S32 squareCount = 1 << ( mGridLevels - i ); S32 squareSize = mSize / squareCount; for ( S32 squareX = 0; squareX < squareCount; squareX++ ) { for ( S32 squareY = 0; squareY < squareCount; squareY++ ) { U16 min = 0xFFFF; U16 max = 0; U16 mindev45 = 0; U16 mindev135 = 0; // determine max error for both possible splits. const Point3F p1(0, 0, getHeight(squareX * squareSize, squareY * squareSize)); const Point3F p2(0, (F32)squareSize, getHeight(squareX * squareSize, squareY * squareSize + squareSize)); const Point3F p3((F32)squareSize, (F32)squareSize, getHeight(squareX * squareSize + squareSize, squareY * squareSize + squareSize)); const Point3F p4((F32)squareSize, 0, getHeight(squareX * squareSize + squareSize, squareY * squareSize)); // pl1, pl2 = split45, pl3, pl4 = split135 const PlaneF pl1(p1, p2, p3); const PlaneF pl2(p1, p3, p4); const PlaneF pl3(p1, p2, p4); const PlaneF pl4(p2, p3, p4); bool parentSplit45 = false; TerrainSquare *parent = NULL; if ( i < mGridLevels ) { parent = findSquare( i+1, squareX * squareSize, squareY * squareSize ); parentSplit45 = parent->flags & TerrainSquare::Split45; } bool empty = true; bool hasEmpty = false; for ( S32 sizeX = 0; sizeX <= squareSize; sizeX++ ) { for ( S32 sizeY = 0; sizeY <= squareSize; sizeY++ ) { S32 x = squareX * squareSize + sizeX; S32 y = squareY * squareSize + sizeY; if(sizeX != squareSize && sizeY != squareSize) { if ( !isEmptyAt( x, y ) ) empty = false; else hasEmpty = true; } U16 ht = getHeight( x, y ); if ( ht < min ) min = ht; if( ht > max ) max = ht; Point3F pt( (F32)sizeX, (F32)sizeY, (F32)ht ); U16 dev; if(sizeX < sizeY) dev = calcDev(pl1, pt); else if(sizeX > sizeY) dev = calcDev(pl2, pt); else dev = Umax(calcDev(pl1, pt), calcDev(pl2, pt)); if(dev > mindev45) mindev45 = dev; if(sizeX + sizeY < squareSize) dev = calcDev(pl3, pt); else if(sizeX + sizeY > squareSize) dev = calcDev(pl4, pt); else dev = Umax(calcDev(pl3, pt), calcDev(pl4, pt)); if(dev > mindev135) mindev135 = dev; } } TerrainSquare *sq = findSquare( i, squareX * squareSize, squareY * squareSize ); sq->minHeight = min; sq->maxHeight = max; sq->flags = empty ? TerrainSquare::Empty : 0; if ( hasEmpty ) sq->flags |= TerrainSquare::HasEmpty; bool shouldSplit45 = ((squareX ^ squareY) & 1) == 0; bool split45; //split45 = shouldSplit45; if ( i == 0 ) split45 = shouldSplit45; else if( i < 4 && shouldSplit45 == parentSplit45 ) split45 = shouldSplit45; else split45 = mindev45 < mindev135; //split45 = shouldSplit45; if(split45) { sq->flags |= TerrainSquare::Split45; sq->heightDeviance = mindev45; } else sq->heightDeviance = mindev135; if( parent ) if ( parent->heightDeviance < sq->heightDeviance ) parent->heightDeviance = sq->heightDeviance; } } } /* for ( S32 y = 0; y < mSize; y += 2 ) { for ( S32 x=0; x < mSize; x += 2 ) { GridSquare *sq = findSquare(1, Point2I(x, y)); GridSquare *s1 = findSquare(0, Point2I(x, y)); GridSquare *s2 = findSquare(0, Point2I(x+1, y)); GridSquare *s3 = findSquare(0, Point2I(x, y+1)); GridSquare *s4 = findSquare(0, Point2I(x+1, y+1)); sq->flags |= (s1->flags | s2->flags | s3->flags | s4->flags) & ~(GridSquare::MaterialStart -1); } } */ }
int RecordPage::nextRecord(int start_from_slot){ for (int i = start_from_slot; i < get_rcdnum(); i++) if (!isEmptyAt(i) && !isTombStone(i)) return i + 1; //slotid = index + 1 return -1; }