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