Пример #1
0
// import a buffer of greyscale values as a heightfield
//
Bool HeightField::ImportBitmap( char * buffer, U32 bwid, U32 bhgt, F32 scale, Area<S32> & rect)
{
  U32 wid = rect.Width();
  U32 hgt = rect.Height();

  F32 dbx  = (F32) bwid / (F32) wid;  
  F32 dbz  = (F32) bhgt / (F32) hgt;  
  F32 bz = 0.0f;

  S32 cx, cz, offset = rect.p0.y * cellPitch + rect.p0.x;
  for (cz = rect.p0.y; cz < rect.p1.y; cz++, bz += dbz)
  {
    F32 boff = bz * (F32) bwid;
    for (cx = rect.p0.x; cx < rect.p1.x; cx++, offset++, boff += dbx)
    {
      F32 h = ((U8) buffer[ (U32) boff]) * scale;
      cellList[offset].height = h;
    }
  }

  return TRUE;
}
Пример #2
0
// perform a heightfield to heightfield paste operation
//
void HeightField::Paste( Area<S32> & dstRect, HeightField & buf, Area<S32> & bufRect, F32 scale, U32 flags, F32 atHeight)
{
  ASSERT( cellList && buf.cellList);

  // in cells
  U32 wid = dstRect.Width();
  U32 hgt = dstRect.Height();

  // in meters
  F32 sdx = (F32) bufRect.Width()  * buf.meterPerCell / (F32) wid;
  F32 sdz = (F32) bufRect.Height() * buf.meterPerCell / (F32) hgt;
  F32 sz  = (F32) bufRect.p0.y * buf.meterPerCell;

  S32 z, x;  // cells
  for (z = dstRect.p0.y; z < dstRect.p1.y; z++, sz += sdz)
  {
    F32 sx  = (F32) bufRect.p0.x * buf.meterPerCell;
    x = dstRect.p0.x;
    U32 offset = z * cellPitch + x;
    for ( ; x < dstRect.p1.x; x++, sx += sdx, offset++)
    {
      if (x < 0 || x > (S32) cellWidth || z < 0 || z > (S32) cellHeight)
      {
        continue;
      }

      Cell &cell = cellList[ offset];
      if (flags & HeightField::EDITSMOOTH)
      {
        if (x < 1 || x >= (S32) cellWidth -1  || z < 1 || z >= (S32) cellHeight -1)
        {
          continue;
        }
        Cell &c0 = cellList[offset - 1];
        Cell &c1 = cellList[offset + 1];
        Cell &c2 = cellList[offset - cellPitch];
        Cell &c3 = cellList[offset + cellPitch];

        // move towards the average of surrounding cells' heights
        F32 h = (c0.height + c1.height + c2.height + c3.height) * 0.25f - cell.height;
        // by a miniture factor of the brushscale (unfactored smoothing is too aggressive)
        h *= scale * 0.3f;
        cell.height += h;
      }
#if 1
      else if (flags & HeightField::EDITHEIGHTS)
      {
        if (flags & HeightField::EDITADD)
        {
          cell.height += buf.FindFloor( sx, sz) * scale;
        }
        else
        {
          cell.height = atHeight + (buf.FindFloor( sx, sz) - 1.0f) * scale;
        }
      }
#else
      else if (flags & HeightField::EDITHEIGHTS)
      {
        if (flags & HeightField::EDITADD)
        {
          // add heights to the current height
          atHeight = cell.height;
        }
        F32 y = atHeight + buf.FindFloor( sx, sz) * scale;
        //if (y < 0.0f)
        //{
          // clamp terrain to 0 meters or above
        //  y = 0.0f;
        //}
        cell.height = y;
      }
#endif
    }
  }
}