void FontInstanceAdapter::getWideGlyphAdvance(le_uint32 glyph, LEPoint &advance) const
{
    hsGGlyph glyphRef;
    hsFixedPoint2 adv;

    // FIXME: return value?
    fStrike->getMetrics(glyph, glyphRef, adv);

    advance.fX = fixedToFloat(adv.fX);
    advance.fY = fixedToFloat(adv.fY);
}
void FontInstanceAdapter::transformFunits(float xFunits, float yFunits, LEPoint &pixels) const
{
    hsFixedPoint2 pt;

    long xFunitsL = (long)xFunits;
    long yFunitsL = (long)yFunits;
    fStrike->TransformFunits(0, (short)xFunitsL, (short)yFunitsL, pt);

    pixels.fX = fixedToFloat(pt.fX);
    pixels.fY = fixedToFloat(pt.fY);
}
Exemple #3
0
void transform_t::dump(const char* what)
{
    GLfixed const * const m = matrix.m;
    LOGD("%s:", what);
    for (int i=0 ; i<4 ; i++)
        LOGD("[%08x %08x %08x %08x] [%f %f %f %f]\n",
            m[I(0,i)], m[I(1,i)], m[I(2,i)], m[I(3,i)],
            fixedToFloat(m[I(0,i)]),
            fixedToFloat(m[I(1,i)]), 
            fixedToFloat(m[I(2,i)]),
            fixedToFloat(m[I(3,i)]));
}
le_bool FontInstanceAdapter::getGlyphPoint(LEGlyphID glyph, le_int32 pointNumber, LEPoint &point) const
{
    hsFixedPoint2 pt;
    le_bool result;

    result = fStrike->GetGlyphPoint(glyph, pointNumber, pt);

    if (result) {
        point.fX = fixedToFloat(pt.fX);
        point.fY = fixedToFloat(pt.fY);
    }

    return result;
}
Exemple #5
0
void matrixf_t::load(const GLfixed* rhs) {
    GLfloat* fp = m;
    unsigned int i = 16;
    do {
        *fp++ = fixedToFloat(*rhs++);
    } while (--i);
}
bool TerrainBlock::exportHeightMap( const UTF8 *filePath, const String &format ) const
{

   GBitmap output(   mFile->mSize,
                     mFile->mSize,
                     false,
                     GFXFormatR5G6B5 );

   // First capture the max height... we'll normalize 
   // everything to this value.
   U16 maxHeight = 0;

   Vector<const U16>::iterator iBits = mFile->mHeightMap.begin();
   for ( S32 y = 0; y < mFile->mSize; y++ )
   {
      for ( S32 x = 0; x < mFile->mSize; x++ )
      {
         if ( *iBits > maxHeight )
            maxHeight = *iBits;
         ++iBits;
      }
   }

   // Now write out the map.
   iBits = mFile->mHeightMap.begin();
   U16 *oBits = (U16*)output.getWritableBits();
   for ( S32 y = 0; y < mFile->mSize; y++ )
   {
      for ( S32 x = 0; x < mFile->mSize; x++ )
      {
         // PNG expects big endian.
         U16 height = (U16)( ( (F32)(*iBits) / (F32)maxHeight ) * (F32)U16_MAX );
         *oBits = convertHostToBEndian( height );
         ++oBits;
         ++iBits;
      }
   }

   FileStream stream;
   if ( !stream.open( filePath, Torque::FS::File::Write ) )
   {
      Con::errorf( "TerrainBlock::exportHeightMap() - Error opening file for writing: %s !", filePath );
      return false;
   }

   if ( !output.writeBitmap( format, stream ) )
   {
      Con::errorf( "TerrainBlock::exportHeightMap() - Error writing %s: %s !", format.c_str(), filePath );
      return false;
   }

   // Print out the map size in meters, so that the user 
   // knows what values to use when importing it into 
   // another terrain tool.
   S32 dim = mSquareSize * mFile->mSize;
   S32 height = fixedToFloat( maxHeight );
   Con::printf( "Saved heightmap with dimensions %d x %d x %d.", dim, dim, height );

   return true;
}
int Tracker::arCameraObserv2Ideal_LUT(Camera* pCam, ARFloat ox, ARFloat oy, ARFloat *ix, ARFloat *iy) {
    if (!undistO2ITable)
        buildUndistO2ITable(pCam);

    int x = (int) ox, y = (int) oy;

    fixedToFloat(undistO2ITable[x + y * arImXsize], *ix, *iy);
    return 0;
}
AR_TEMPL_FUNC int
AR_TEMPL_TRACKER::arParamObserv2Ideal_LUT(Camera* pCam, ARFloat ox, ARFloat oy, ARFloat *ix, ARFloat *iy)
{
	if(!undistO2ITable)
		buildUndistO2ITable(pCam);

	int x=(int)ox, y=(int)oy;

	fixedToFloat(undistO2ITable[x+y*arImXsize], *ix,*iy);
	return 0;
}
void Tracker::buildUndistO2ITable(Camera* pCam) {
    int x, y;
    ARFloat cx, cy, ox, oy;
    unsigned int fixed;
    char* cachename = NULL;
    bool loaded = false;

    if (loadCachedUndist) {
        assert(pCam->getFileName() != "");
        cachename = new char[strlen(pCam->getFileName().c_str()) + 5];
        strcpy(cachename, pCam->getFileName().c_str());
        strcat(cachename, ".LUT");
    }

    // we have to take care here when using a memory manager that can not free memory
    // (usually this lookup table should only be built once - unless we change camera resolution)
    //
    if (undistO2ITable)
        delete[] undistO2ITable;

    undistO2ITable = new unsigned int[arImXsize * arImYsize];

    if (loadCachedUndist) {
        if (FILE* fp = fopen(cachename, "rb")) {
            size_t numBytes = fread(undistO2ITable, 1, arImXsize * arImYsize * sizeof(unsigned int), fp);
            fclose(fp);

            if (numBytes == arImXsize * arImYsize * sizeof(unsigned int))
                loaded = true;
        }
    }

    if (!loaded) {
        for (x = 0; x < arImXsize; x++) {
            for (y = 0; y < arImYsize; y++) {
                arCameraObserv2Ideal_std(pCam, (ARFloat) x, (ARFloat) y, &cx, &cy);
                floatToFixed(cx, cy, fixed);
                fixedToFloat(fixed, ox, oy);
                undistO2ITable[x + y * arImXsize] = fixed;
            }
        }

        if (loadCachedUndist)
            if (FILE* fp = fopen(cachename, "wb")) {
                fwrite(undistO2ITable, 1, arImXsize * arImYsize * sizeof(unsigned int), fp);
                fclose(fp);
            }
    }

    delete[] cachename;
}
Exemple #10
0
void TerrCell::_updateBounds()
{
   PROFILE_SCOPE( TerrCell_UpdateBounds );

   const F32 squareSize = mTerrain->getSquareSize();

   // This should really only be called for cells of smMinCellSize,
   // in which case stepSize is always one.
   const U32 stepSize = mSize / smMinCellSize;

   // Prepare to expand the bounds.
   mBounds.minExtents.set( F32_MAX, F32_MAX, F32_MAX );
   mBounds.maxExtents.set( -F32_MAX, -F32_MAX, -F32_MAX );   

   Point3F vert;
   Point2F texCoord;

   const TerrainFile *file = mTerrain->getFile();

   for ( U32 y = 0; y < smVBStride; y++ )
   {
      for ( U32 x = 0; x < smVBStride; x++ )
      {
         // Setup this point.
         vert.x = (F32)( mPoint.x + x * stepSize ) * squareSize;
         vert.y = (F32)( mPoint.y + y * stepSize ) * squareSize;
         vert.z = fixedToFloat( file->getHeight(   mPoint.x + x,
                                                   mPoint.y + y ) );

         // HACK: Call it twice to deal with the inverted
         // inital bounds state... shouldn't be a perf issue.
         mBounds.extend( vert );
         mBounds.extend( vert );
      }
   }

   mRadius = mBounds.len() * 0.5;

   _updateOBB();
}
Exemple #11
0
void TerrCell::_updateVertexBuffer()
{
   PROFILE_SCOPE( TerrCell_UpdateVertexBuffer );

   // Start off with no empty squares
   mHasEmpty = false;
   mEmptyVertexList.clear();

   mVertexBuffer.set( GFX, smVBSize, GFXBufferTypeStatic );

   const F32 squareSize = mTerrain->getSquareSize();
   const U32 blockSize = mTerrain->getBlockSize();
   const U32 stepSize = mSize / smMinCellSize;

   U32 vbcounter = 0;

   TerrVertex *vert = mVertexBuffer.lock();

   Point2I gridPt;
   Point2F point;
   F32 height;
   Point3F normal;   
   
   const TerrainFile *file = mTerrain->getFile();

   for ( U32 y = 0; y < smVBStride; y++ )
   {
      for ( U32 x = 0; x < smVBStride; x++ )
      {
         // We clamp here to keep the geometry from reading across
         // one side of the height map to the other causing walls
         // around the edges of the terrain.
         gridPt.x = mClamp( mPoint.x + x * stepSize, 0, blockSize - 1 );
         gridPt.y = mClamp( mPoint.y + y * stepSize, 0, blockSize - 1 );

         // Setup this point.
         point.x = (F32)gridPt.x * squareSize;
         point.y = (F32)gridPt.y * squareSize;
         height = fixedToFloat( file->getHeight( gridPt.x, gridPt.y ) );
         vert->point.x = point.x;
         vert->point.y = point.y;
         vert->point.z = height;

         // Get the normal.
         mTerrain->getSmoothNormal( point, &normal, true, false );
         vert->normal = normal;

         // Get the tangent z.
         vert->tangentZ = fixedToFloat( file->getHeight( gridPt.x + 1, gridPt.y ) ) - height;

         // Test the empty state for this vert.
         if ( file->isEmptyAt( gridPt.x, gridPt.y ) )
         {
            mHasEmpty = true;
            mEmptyVertexList.push_back( vbcounter );
         }

         vbcounter++;
         ++vert;
      }
   }

   // Add verts for 'skirts' around/beneath the edge verts of this cell.
   // This could probably be reduced to a loop...
   
   const F32 skirtDepth = mSize / smMinCellSize * mTerrain->getSquareSize();

   // Top edge skirt
   for ( U32 i = 0; i < smVBStride; i++ )
   {      
      gridPt.x = mClamp( mPoint.x + i * stepSize, 0, blockSize - 1 );
      gridPt.y = mClamp( mPoint.y, 0, blockSize - 1 );
      
      point.x = (F32)gridPt.x * squareSize;
      point.y = (F32)gridPt.y * squareSize;
      height = fixedToFloat( file->getHeight( gridPt.x, gridPt.y ) );
      vert->point.x = point.x;
      vert->point.y = point.y;
      vert->point.z = height - skirtDepth;

      // Get the normal.
      mTerrain->getNormal( point, &normal, true, false );
      vert->normal = normal;

      // Get the tangent.
      vert->tangentZ = height - fixedToFloat( file->getHeight( gridPt.x + 1, gridPt.y ) );

      vbcounter++;
      ++vert;      
   }

   // Bottom edge skirt
   for ( U32 i = 0; i < smVBStride; i++ )
   {      
      gridPt.x = mClamp( mPoint.x + i * stepSize, 0, blockSize - 1 );
      gridPt.y = mClamp( mPoint.y + smMinCellSize * stepSize, 0, blockSize - 1 );

      point.x = (F32)gridPt.x * squareSize;
      point.y = (F32)gridPt.y * squareSize;
      height = fixedToFloat( file->getHeight( gridPt.x, gridPt.y ) );
      vert->point.x = point.x;
      vert->point.y = point.y;
      vert->point.z = height - skirtDepth;

      // Get the normal.
      mTerrain->getNormal( point, &normal, true, false );
      vert->normal = normal;

      // Get the tangent.
      vert->tangentZ = height - fixedToFloat( file->getHeight( gridPt.x + 1, gridPt.y ) );

      vbcounter++;
      ++vert;      
   }

   // Left edge skirt
   for ( U32 i = 0; i < smVBStride; i++ )
   {      
      gridPt.x = mClamp( mPoint.x, 0, blockSize - 1 );
      gridPt.y = mClamp( mPoint.y + i * stepSize, 0, blockSize - 1 );

      point.x = (F32)gridPt.x * squareSize;
      point.y = (F32)gridPt.y * squareSize;
      height = fixedToFloat( file->getHeight( gridPt.x, gridPt.y ) );
      vert->point.x = point.x;
      vert->point.y = point.y;
      vert->point.z = height - skirtDepth;

      // Get the normal.
      mTerrain->getNormal( point, &normal, true, false );
      vert->normal = normal;

      // Get the tangent.
      vert->tangentZ = height - fixedToFloat( file->getHeight( gridPt.x + 1, gridPt.y ) );

      vbcounter++;
      ++vert;      
   }

   // Right edge skirt
   for ( U32 i = 0; i < smVBStride; i++ )
   {      
      gridPt.x = mClamp( mPoint.x + smMinCellSize * stepSize, 0, blockSize - 1 );
      gridPt.y = mClamp( mPoint.y + i * stepSize, 0, blockSize - 1 );

      point.x = (F32)gridPt.x * squareSize;
      point.y = (F32)gridPt.y * squareSize;
      height = fixedToFloat( file->getHeight( gridPt.x, gridPt.y ) );
      vert->point.x = point.x;
      vert->point.y = point.y;
      vert->point.z = height - skirtDepth;

      // Get the normal.
      mTerrain->getNormal( point, &normal, true, false );
      vert->normal = normal;

      // Get the tangent.
      vert->tangentZ = height - fixedToFloat( file->getHeight( gridPt.x + 1, gridPt.y ) );

      vbcounter++;
      ++vert;      
   }

   AssertFatal( vbcounter == smVBSize, "bad" );
   mVertexBuffer.unlock();
}
Exemple #12
0
bool TerrainBlock::buildPolyList(AbstractPolyList* polyList, const Box3F &box, const SphereF&)
{
   if (box.maxExtents.z < -TerrainThickness || box.minExtents.z > fixedToFloat(gridMap[BlockShift]->maxHeight))
      return false;

   // Transform the bounding sphere into the object's coord space.  Note that this
   //  not really optimal.
   Box3F osBox = box;
   mWorldToObj.mul(osBox);
   AssertWarn(mObjScale == Point3F::One, "Error, handle the scale transform on the terrain");

   // Setup collision state data
   polyList->setTransform(&getTransform(), getScale());
   polyList->setObject(this);

   S32 xStart = (S32)mFloor( osBox.minExtents.x / mSquareSize );
   S32 xEnd   = (S32)mCeil ( osBox.maxExtents.x / mSquareSize );
   S32 yStart = (S32)mFloor( osBox.minExtents.y / mSquareSize );
   S32 yEnd   = (S32)mCeil ( osBox.maxExtents.y / mSquareSize );
   if (!mTile && xStart<0)
      xStart = 0;
   S32 xExt = xEnd - xStart;
   if (xExt > MaxExtent)
      xExt = MaxExtent;
   xEnd = xStart + xExt;

   mHeightMax = floatToFixed(osBox.maxExtents.z);
   mHeightMin = (osBox.minExtents.z < 0.0f)? 0.0f: floatToFixed(osBox.minExtents.z);

   // Index of shared points
   U32 bp[(MaxExtent + 1) * 2],*vb[2];
   vb[0] = &bp[0];
   vb[1] = &bp[xExt + 1];
   clrbuf(vb[1],xExt + 1);

   bool emitted = false;
   for (S32 y = yStart; y < yEnd; y++) 
   {
      S32 yi = y & BlockMask;

      swap(vb[0],vb[1]);
      clrbuf(vb[1],xExt + 1);
      //
      for (S32 x = xStart; x < xEnd; x++) 
      {
         S32 xi = x & BlockMask;
         GridSquare *gs = findSquare(0, Point2I(xi, yi));

         // If we disable repeat, then skip non-primary
         if(!mTile && (x!=xi || y!=yi))
            continue;

         // holes only in the primary terrain block
         if (((gs->flags & GridSquare::Empty) && x == xi && y == yi) || gs->minHeight > mHeightMax || gs->maxHeight < mHeightMin)
            continue;
         emitted = true;

         // Add the missing points
         U32 vi[5];
         for (int i = 0; i < 4 ; i++) 
         {
            S32 dx = i >> 1;
            S32 dy = dx ^ (i & 1);
            U32* vp = &vb[dy][x - xStart + dx];
            if (*vp == U32_MAX) 
            {
               Point3F pos;
               pos.x = (F32)((x + dx) * mSquareSize);
               pos.y = (F32)((y + dy) * mSquareSize);
               pos.z = fixedToFloat(getHeight(xi + dx, yi + dy));
               *vp = polyList->addPoint(pos);
            }
            vi[i] = *vp;
         }

         U32* vp = &vi[0];
         if (!(gs->flags & GridSquare::Split45))
            vi[4] = vi[0], vp++;

         BaseMatInstance* material = getMaterialInst( xi, yi );
         U32 surfaceKey = ((xi << 16) + yi) << 1;
         polyList->begin(material,surfaceKey);
         polyList->vertex(vp[0]);
         polyList->vertex(vp[1]);
         polyList->vertex(vp[2]);
         polyList->plane(vp[0],vp[1],vp[2]);
         polyList->end();
         polyList->begin(material,surfaceKey + 1);
         polyList->vertex(vp[0]);
         polyList->vertex(vp[2]);
         polyList->vertex(vp[3]);
         polyList->plane(vp[0],vp[2],vp[3]);
         polyList->end();
      }
   }
   return emitted;
}
Exemple #13
0
void TerrainBlock::buildConvex(const Box3F& box,Convex* convex)
{
   sTerrainConvexList.collectGarbage();

   //
   if (box.maxExtents.z < -TerrainThickness || box.minExtents.z > fixedToFloat(gridMap[BlockShift]->maxHeight))
      return;

   // Transform the bounding sphere into the object's coord space.  Note that this
   // not really optimal.
   Box3F osBox = box;
   mWorldToObj.mul(osBox);
   AssertWarn(mObjScale == Point3F(1, 1, 1), "Error, handle the scale transform on the terrain");

   S32 xStart = (S32)mFloor( osBox.minExtents.x / mSquareSize );
   S32 xEnd   = (S32)mCeil ( osBox.maxExtents.x / mSquareSize );
   S32 yStart = (S32)mFloor( osBox.minExtents.y / mSquareSize );
   S32 yEnd   = (S32)mCeil ( osBox.maxExtents.y / mSquareSize );
   S32 xExt = xEnd - xStart;
   if (xExt > MaxExtent)
      xExt = MaxExtent;

   mHeightMax = floatToFixed(osBox.maxExtents.z);
   mHeightMin = (osBox.minExtents.z < 0)? 0: floatToFixed(osBox.minExtents.z);

   for (S32 y = yStart; y < yEnd; y++) {
      S32 yi = y & BlockMask;

      //
      for (S32 x = xStart; x < xEnd; x++) {
         S32 xi = x & BlockMask;
         GridSquare *gs = findSquare(0, Point2I(xi, yi));

         // If we disable repeat, then skip non-primary
         if(!mTile && (x!=xi || y!=yi))
            continue;

         // holes only in the primary terrain block
         if (((gs->flags & GridSquare::Empty) && x == xi && y == yi) ||
             gs->minHeight > mHeightMax || gs->maxHeight < mHeightMin)
            continue;

         U32 sid = (x << 16) + (y & ((1 << 16) - 1));
         Convex* cc = 0;

         // See if the square already exists as part of the working set.
         CollisionWorkingList& wl = convex->getWorkingList();
         for (CollisionWorkingList* itr = wl.wLink.mNext; itr != &wl; itr = itr->wLink.mNext)
            if (itr->mConvex->getType() == TerrainConvexType &&
                static_cast<TerrainConvex*>(itr->mConvex)->squareId == sid) {
               cc = itr->mConvex;
               break;
            }
         if (cc)
            continue;

         // Create a new convex.
         TerrainConvex* cp = new TerrainConvex;
         sTerrainConvexList.registerObject(cp);
         convex->addToWorkingList(cp);
         cp->halfA = true;
         cp->square = 0;
         cp->mObject = this;
         cp->squareId = sid;
         cp->material = getMaterial(xi,yi)->index;//RDTODO
         cp->box.minExtents.set((F32)(x * mSquareSize), (F32)(y * mSquareSize), fixedToFloat(gs->minHeight));
         cp->box.maxExtents.x = cp->box.minExtents.x + mSquareSize;
         cp->box.maxExtents.y = cp->box.minExtents.y + mSquareSize;
         cp->box.maxExtents.z = fixedToFloat(gs->maxHeight);
         mObjToWorld.mul(cp->box);

         // Build points
         Point3F* pos = cp->point;
         for (int i = 0; i < 4 ; i++,pos++) {
            S32 dx = i >> 1;
            S32 dy = dx ^ (i & 1);
            pos->x = (F32)((x + dx) * mSquareSize);
            pos->y = (F32)((y + dy) * mSquareSize);
            pos->z = fixedToFloat(getHeight(xi + dx, yi + dy));
         }

         // Build normals, then split into two Convex objects if the
         // square is concave
         if ((cp->split45 = gs->flags & GridSquare::Split45) == true) {
            VectorF *vp = cp->point;
            mCross(vp[0] - vp[1],vp[2] - vp[1],&cp->normal[0]);
            cp->normal[0].normalize();
            mCross(vp[2] - vp[3],vp[0] - vp[3],&cp->normal[1]);
            cp->normal[1].normalize();
            if (mDot(vp[3] - vp[1],cp->normal[0]) > 0) {
               TerrainConvex* nc = new TerrainConvex(*cp);
               sTerrainConvexList.registerObject(nc);
               convex->addToWorkingList(nc);
               nc->halfA = false;
               nc->square = cp;
               cp->square = nc;
            }
         }
         else {
            VectorF *vp = cp->point;
            mCross(vp[3] - vp[0],vp[1] - vp[0],&cp->normal[0]);
            cp->normal[0].normalize();
            mCross(vp[1] - vp[2],vp[3] - vp[2],&cp->normal[1]);
            cp->normal[1].normalize();
            if (mDot(vp[2] - vp[0],cp->normal[0]) > 0) {
               TerrainConvex* nc = new TerrainConvex(*cp);
               sTerrainConvexList.registerObject(nc);
               convex->addToWorkingList(nc);
               nc->halfA = false;
               nc->square = cp;
               cp->square = nc;
            }
         }
      }
   }
}
Exemple #14
0
bool TerrainBlock::buildPolyList(PolyListContext, AbstractPolyList* polyList, const Box3F &box, const SphereF&)
{
	PROFILE_SCOPE( TerrainBlock_buildPolyList );

   // First check to see if the query misses the 
   // terrain elevation range.
   const Point3F &terrainPos = getPosition();
   if (  box.maxExtents.z - terrainPos.z < -TerrainThickness || 
         box.minExtents.z - terrainPos.z > fixedToFloat( mFile->getMaxHeight() ) )
      return false;

   // Transform the bounding sphere into the object's coord 
   // space.  Note that this is really optimal.
   Box3F osBox = box;
   mWorldToObj.mul(osBox);
   AssertWarn(mObjScale == Point3F::One, "Error, handle the scale transform on the terrain");

   // Setup collision state data
   polyList->setTransform(&getTransform(), getScale());
   polyList->setObject(this);

   S32 xStart = (S32)mFloor( osBox.minExtents.x / mSquareSize );
   S32 xEnd   = (S32)mCeil ( osBox.maxExtents.x / mSquareSize );
   S32 yStart = (S32)mFloor( osBox.minExtents.y / mSquareSize );
   S32 yEnd   = (S32)mCeil ( osBox.maxExtents.y / mSquareSize );
   if ( xStart < 0 )
      xStart = 0;
   S32 xExt = xEnd - xStart;
   if ( xExt > MaxExtent )
      xExt = MaxExtent;
   xEnd = xStart + xExt;

   U32 heightMax = floatToFixed(osBox.maxExtents.z);
   U32 heightMin = (osBox.minExtents.z < 0.0f)? 0.0f: floatToFixed(osBox.minExtents.z);

   // Index of shared points
   U32 bp[(MaxExtent + 1) * 2],*vb[2];
   vb[0] = &bp[0];
   vb[1] = &bp[xExt + 1];
   clrbuf(vb[1],xExt + 1);

   const U32 BlockMask = mFile->mSize - 1;

   bool emitted = false;
   for (S32 y = yStart; y < yEnd; y++) 
   {
      S32 yi = y & BlockMask;

      swap(vb[0],vb[1]);
      clrbuf(vb[1],xExt + 1);
      //
      for (S32 x = xStart; x < xEnd; x++) 
      {
         S32 xi = x & BlockMask;
         const TerrainSquare *sq = mFile->findSquare( 0, xi, yi );

         if ( x != xi || y != yi )
            continue;

         // holes only in the primary terrain block
         if (  ( ( sq->flags & TerrainSquare::Empty ) && x == xi && y == yi ) || 
               sq->minHeight > heightMax || 
               sq->maxHeight < heightMin )
            continue;

         emitted = true;

         // Add the missing points
         U32 vi[5];
         for (int i = 0; i < 4 ; i++) 
         {
            S32 dx = i >> 1;
            S32 dy = dx ^ (i & 1);
            U32* vp = &vb[dy][x - xStart + dx];
            if (*vp == U32_MAX) 
            {
               Point3F pos;
               pos.x = (F32)((x + dx) * mSquareSize);
               pos.y = (F32)((y + dy) * mSquareSize);
               pos.z = fixedToFloat( mFile->getHeight(xi + dx, yi + dy) );
               *vp = polyList->addPoint(pos);
            }
            vi[i] = *vp;
         }

         U32* vp = &vi[0];
         if ( !( sq->flags & TerrainSquare::Split45 ) )
            vi[4] = vi[0], vp++;

         BaseMatInstance *material = NULL; //getMaterialInst( xi, yi );
         U32 surfaceKey = ((xi << 16) + yi) << 1;
         polyList->begin(material,surfaceKey);
         polyList->vertex(vp[0]);
         polyList->vertex(vp[1]);
         polyList->vertex(vp[2]);
         polyList->plane(vp[0],vp[1],vp[2]);
         polyList->end();
         polyList->begin(material,surfaceKey + 1);
         polyList->vertex(vp[0]);
         polyList->vertex(vp[2]);
         polyList->vertex(vp[3]);
         polyList->plane(vp[0],vp[2],vp[3]);
         polyList->end();
      }
   }

   return emitted;
}
Exemple #15
0
static GLfixed fog_exp2(ogles_context_t* c, GLfixed z) {
    const float e = fixedToFloat(gglMulx(c->fog.density, z));
    return clampF(gglFloatToFixed(fastexpf(-e*e)));
}
Exemple #16
0
 virtual float getAltitude(int x, int y)
 {
    return fixedToFloat(mBlock->getHeight(x,y));
 }
Exemple #17
0
 virtual float getMaxHeight()
 {
    return fixedToFloat(mBlock->findSquare(TerrainBlock::BlockShift, Point2I(0,0))->maxHeight);
 }
Exemple #18
0
bool TerrainBlock::castRayBlock(const Point3F &pStart, const Point3F &pEnd, const Point2I &aBlockPos, U32 aLevel, F32 invDeltaX, F32 invDeltaY, F32 aStartT, F32 aEndT, RayInfo *info, bool collideEmpty)
{
   F32 invBlockSize = 1 / F32(BlockSquareWidth);

   static TerrLOSStackNode stack[BlockShift * 3 + 1];
   U32 stackSize = 1;

   stack[0].startT = aStartT;
   stack[0].endT = aEndT;
   stack[0].blockPos = aBlockPos;
   stack[0].level = aLevel;
   
   if(!mTile && !aBlockPos.isZero())
      return false;

   while(stackSize--)
   {
      TerrLOSStackNode *sn = stack + stackSize;
      U32 level  = sn->level;
      F32 startT = sn->startT;
      F32 endT   = sn->endT;
      Point2I blockPos = sn->blockPos;

      GridSquare *sq = findSquare(level, Point2I(blockPos.x & BlockMask, blockPos.y & BlockMask));

      F32 startZ = startT * (pEnd.z - pStart.z) + pStart.z;
      F32 endZ = endT * (pEnd.z - pStart.z) + pStart.z;

      F32 minHeight = fixedToFloat(sq->minHeight);
      if(startZ <= minHeight && endZ <= minHeight)
      {
         //drawLineTest(startT, sn->endT, false);
         continue;
      }
      F32 maxHeight = fixedToFloat(sq->maxHeight);
      if(startZ >= maxHeight && endZ >= maxHeight)
      {
         //drawLineTest(startT, endT, false);
         continue;
      }
      if (!collideEmpty && (sq->flags & GridSquare::Empty) &&
      	  blockPos.x == (blockPos.x & BlockMask) && blockPos.y == (blockPos.y & BlockMask))
      {
         //drawLineTest(startT, endT, false);
         continue;
      }
      if(level == 0)
      {
         F32 xs = blockPos.x * invBlockSize;
         F32 ys = blockPos.y * invBlockSize;

         F32 zBottomLeft = fixedToFloat(getHeight(blockPos.x, blockPos.y));
         F32 zBottomRight= fixedToFloat(getHeight(blockPos.x + 1, blockPos.y));
         F32 zTopLeft =    fixedToFloat(getHeight(blockPos.x, blockPos.y + 1));
         F32 zTopRight =   fixedToFloat(getHeight(blockPos.x + 1, blockPos.y + 1));

         PlaneF p1, p2;
         PlaneF divider;
         Point3F planePoint;

         if(sq->flags & GridSquare::Split45)
         {
            p1.set(zBottomLeft - zBottomRight, zBottomRight - zTopRight, invBlockSize);
            p2.set(zTopLeft - zTopRight, zBottomLeft - zTopLeft, invBlockSize);
            planePoint.set(xs, ys, zBottomLeft);
            divider.x = 1;
            divider.y = -1;
            divider.z = 0;
         }
         else
         {
            p1.set(zTopLeft - zTopRight, zBottomRight - zTopRight, invBlockSize);
            p2.set(zBottomLeft - zBottomRight, zBottomLeft - zTopLeft, invBlockSize);
            planePoint.set(xs + invBlockSize, ys, zBottomRight);
            divider.x = 1;
            divider.y = 1;
            divider.z = 0;
         }
         p1.setPoint(planePoint);
         p2.setPoint(planePoint);
         divider.setPoint(planePoint);

         F32 t1 = p1.intersect(pStart, pEnd);
         F32 t2 = p2.intersect(pStart, pEnd);
         F32 td = divider.intersect(pStart, pEnd);

         F32 dStart = divider.distToPlane(pStart);
         F32 dEnd = divider.distToPlane(pEnd);

         // see if the line crosses the divider
         if((dStart >= 0 && dEnd < 0) || (dStart < 0 && dEnd >= 0))
         {
            if(dStart < 0)
            {
               F32 temp = t1;
               t1 = t2;
               t2 = temp;
            }
            if(t1 >= startT && t1 && t1 <= td && t1 <= endT)
            {
               info->t = t1;
               info->normal = p1;
               return true;
            }
            if(t2 >= td && t2 >= startT && t2 <= endT)
            {
               info->t = t2;
               info->normal = p2;
               return true;
            }
         }
         else
         {
            F32 t;
            if(dStart >= 0) {
               t = t1;
               info->normal = p1;
            }
            else {
               t = t2;
               info->normal = p2;
            }
            if(t >= startT && t <= endT)
            {
               info->t = t;
               return true;
            }
         }
         continue;
      }
      int subSqWidth = 1 << (level - 1);
      F32 xIntercept = (blockPos.x + subSqWidth) * invBlockSize;
      F32 xInt = calcInterceptX(pStart.x, invDeltaX, xIntercept);
      F32 yIntercept = (blockPos.y + subSqWidth) * invBlockSize;
      F32 yInt = calcInterceptY(pStart.y, invDeltaY, yIntercept);

      F32 startX = startT * (pEnd.x - pStart.x) + pStart.x;
      F32 startY = startT * (pEnd.y - pStart.y) + pStart.y;

      if(xInt < startT)
         xInt = MAX_FLOAT;
      if(yInt < startT)
         yInt = MAX_FLOAT;

      U32 x0 = (startX > xIntercept) * subSqWidth;
      U32 y0 = (startY > yIntercept) * subSqWidth;
      U32 x1 = subSqWidth - x0;
      U32 y1 = subSqWidth - y0;
      U32 nextLevel = level - 1;

      // push the items on the stack in reverse order of processing
      if(xInt > endT && yInt > endT)
      {
         // only test the square the point started in:
         stack[stackSize].blockPos.set(blockPos.x + x0, blockPos.y + y0);
         stack[stackSize].level = nextLevel;
         stackSize++;
      }
      else if(xInt < yInt)
      {
         F32 nextIntersect = endT;
         if(yInt <= endT)
         {
            stack[stackSize].blockPos.set(blockPos.x + x1, blockPos.y + y1);
            stack[stackSize].startT = yInt;
            stack[stackSize].endT = endT;
            stack[stackSize].level = nextLevel;
            nextIntersect = yInt;
            stackSize++;
         }
         stack[stackSize].blockPos.set(blockPos.x + x1, blockPos.y + y0);
         stack[stackSize].startT = xInt;
         stack[stackSize].endT = nextIntersect;
         stack[stackSize].level = nextLevel;

         stack[stackSize+1].blockPos.set(blockPos.x + x0, blockPos.y + y0);
         stack[stackSize+1].startT = startT;
         stack[stackSize+1].endT = xInt;
         stack[stackSize+1].level = nextLevel;
         stackSize += 2;
      }
      else if(yInt < xInt)
      {
         F32 nextIntersect = endT;
         if(xInt <= endT)
         {
            stack[stackSize].blockPos.set(blockPos.x + x1, blockPos.y + y1);
            stack[stackSize].startT = xInt;
            stack[stackSize].endT = endT;
            stack[stackSize].level = nextLevel;
            nextIntersect = xInt;
            stackSize++;
         }
         stack[stackSize].blockPos.set(blockPos.x + x0, blockPos.y + y1);
         stack[stackSize].startT = yInt;
         stack[stackSize].endT = nextIntersect;
         stack[stackSize].level = nextLevel;

         stack[stackSize+1].blockPos.set(blockPos.x + x0, blockPos.y + y0);
         stack[stackSize+1].startT = startT;
         stack[stackSize+1].endT = yInt;
         stack[stackSize+1].level = nextLevel;
         stackSize += 2;
      }
      else
      {
         stack[stackSize].blockPos.set(blockPos.x + x1, blockPos.y + y1);
         stack[stackSize].startT = xInt;
         stack[stackSize].endT = endT;
         stack[stackSize].level = nextLevel;

         stack[stackSize+1].blockPos.set(blockPos.x + x0, blockPos.y + y0);
         stack[stackSize+1].startT = startT;
         stack[stackSize+1].endT = xInt;
         stack[stackSize+1].level = nextLevel;
         stackSize += 2;
      }
   }
   return false;
}