Пример #1
0
void DrawFrame() {
    //_LAT(LED1) = 1;

    global_drawop = SRCCOPY;
    SetFontSize(1);
    SetFont(fonts.Stellaris);

    // Draw the wallpaper
    //DrawImage(0,0,wallpaper);
    ClearImage();

    // Draw foreground app
    if (foreground_app != NULL)
        foreground_app->draw();

    // Draw the battery bar
    uint8 w = mLerp(0,100, 0,DISPLAY_WIDTH, battery_level);
    color_t c = WHITE;
    switch (power_status) {
        case pwBattery: {
            switch (battery_status) {
                case batFull: c = SKYBLUE; break;
                case batNormal: c = SKYBLUE; break;
                case batLow: c = RED; break;
                // No need to put batFlat or batNotConnected
                default: break;
            }
            break;
        }
        case pwCharged: c = GREEN; break;
        case pwCharging: c = ORANGE; break;
    }
    // Extra padding at the top of the display to compensate for the bezel
    //DrawBox(0,0, DISPLAY_WIDTH,4, BLACK,BLACK);
    DrawBox(0,0, w,3, c,c);

    // Draw the battery icon
    if (power_status == pwBattery) {
        char s[8];
        sprintf(s, "%3d%%", battery_level);
        //utoa(s, battery_level, 10);
        //int x = DISPLAY_WIDTH - StringWidth(s) - 2;
        int x = DISPLAY_WIDTH - 30;
        DrawImString(s, x,5, WHITE);

    } else {
        if (usb_connected) {
            DrawImage(DISPLAY_WIDTH-USB_WIDTH-2,5, &img_usb);
        } else {
            DrawImage(DISPLAY_WIDTH-POWER_WIDTH-2,6, &img_power);
        }
    }

    // Framerate debug info
//    char s[8];
//    sprintf(s, "%d", draw_ticks);
//    DrawString(s, 4,5, DARKGREEN);
}
Пример #2
0
void PSSMLightShadowMap::_calcSplitPos(const Frustum& currFrustum)
{
   const F32 nearDist = 0.01f; // TODO: Should this be adjustable or different?
   const F32 farDist = currFrustum.getFarDist();

   for ( U32 i = 1; i < mNumSplits; i++ )
   {
      F32 step = (F32) i / (F32) mNumSplits;
      F32 logSplit = nearDist * mPow(farDist / nearDist, step);
      F32 linearSplit = nearDist + (farDist - nearDist) * step;
      mSplitDist[i] = mLerp( linearSplit, logSplit, mClampF( mLogWeight, 0.0f, 1.0f ) );
   }

   mSplitDist[0] = nearDist;
   mSplitDist[mNumSplits] = farDist;
}
Пример #3
0
void PxSingleActor::_updateContainerForces()
{   
   if ( !mWorld->getEnabled() )
      return;

   PROFILE_SCOPE( PxSingleActor_updateContainerForces );

   // Update container drag and buoyancy properties      

   ContainerQueryInfo info;
   info.box = getWorldBox();
   info.mass = getMass();

   // Find and retreive physics info from intersecting WaterObject(s)
   mContainer->findObjects( getWorldBox(), WaterObjectType|PhysicalZoneObjectType, findRouter, &info );
   
   // Calculate buoyancy and drag
   F32 angDrag = mBuildAngDrag;
   F32 linDrag = mBuildLinDrag;
   F32 buoyancy = 0.0f;

   if ( true ) //info.waterCoverage >= 0.1f) 
   {
      F32 waterDragScale = info.waterViscosity * mDataBlock->waterDragScale;
      F32 powCoverage = mPow( info.waterCoverage, 0.25f );

      if ( info.waterCoverage > 0.0f )
      {
         //angDrag = mBuildAngDrag * waterDragScale;
         //linDrag = mBuildLinDrag * waterDragScale;
         angDrag = mLerp( mBuildAngDrag, mBuildAngDrag * waterDragScale, powCoverage );
         linDrag = mLerp( mBuildLinDrag, mBuildLinDrag * waterDragScale, powCoverage );
      }

      buoyancy = ( info.waterDensity / mDataBlock->buoyancyDensity ) * mPow( info.waterCoverage, 2.0f );
   }

   // Apply drag (dampening)
   mActor->setLinearDamping( linDrag );
   mActor->setAngularDamping( angDrag );   

   // Apply buoyancy force
   if ( buoyancy != 0 )
   {     
      // A little hackery to prevent oscillation
      // Based on this blog post (http://reinot.blogspot.com/2005/11/oh-yes-they-float-georgie-they-all.html)
      // JCF: DISABLED
      NxVec3 gravity;
      mWorld->getScene()->getGravity(gravity);
      //NxVec3 velocity = mActor->getLinearVelocity();

      NxVec3 buoyancyForce = buoyancy * -gravity * TickSec;
      //F32 currHeight = getPosition().z;
      //const F32 C = 2.0f;
      //const F32 M = 0.1f;

      //if ( currHeight + velocity.z * TickSec * C > info.waterHeight )
      //   buoyancyForce *= M;

      mActor->addForceAtPos( buoyancyForce, mActor->getCMassGlobalPosition(), NX_IMPULSE );
   }

   // Apply physical zone forces
   if ( info.appliedForce.len() > 0.001f )
      mActor->addForceAtPos( pxCast<NxVec3>(info.appliedForce), mActor->getCMassGlobalPosition(), NX_IMPULSE );
}
void ClippedPolyList::end()
{
   PROFILE_SCOPE( ClippedPolyList_Clip );

   Poly& poly = mPolyList.last();
   
   // Reject polygons facing away from our normal.   
   if ( mDot( poly.plane, mNormal ) < mNormalTolCosineRadians )
   {
      mIndexList.setSize(poly.vertexStart);
      mPolyList.decrement();
      return;
   }

   // Build initial inside/outside plane masks
   U32 indexStart = poly.vertexStart;
   U32 vertexCount = mIndexList.size() - indexStart;

   U32 frontMask = 0,backMask = 0;
   U32 i;
   for (i = indexStart; i < mIndexList.size(); i++) 
   {
      U32 mask = mVertexList[mIndexList[i]].mask;
      frontMask |= mask;
      backMask |= ~mask;
   }

   // Trivial accept if all the vertices are on the backsides of
   // all the planes.
   if (!frontMask) 
   {
      poly.vertexCount = vertexCount;
      return;
   }

   // Trivial reject if any plane not crossed has all it's points
   // on the front.
   U32 crossMask = frontMask & backMask;
   if (~crossMask & frontMask) 
   {
      mIndexList.setSize(poly.vertexStart);
      mPolyList.decrement();
      return;
   }

   // Potentially, this will add up to mPlaneList.size() * (indexStart - indexEnd) 
   // elements to mIndexList, so ensure that it has enough space to store that
   // so we can use push_back_noresize. If you find this code block getting hit
   // frequently, changing the value of 'IndexListReserveSize' or doing some selective
   // allocation is suggested
   //
   // TODO: Re-visit this, since it obviously does not work correctly, and than
   // re-enable the push_back_noresize
   //while(mIndexList.size() + mPlaneList.size() * (mIndexList.size() - indexStart) > mIndexList.capacity() )
   //   mIndexList.reserve(mIndexList.capacity() * 2);

   // Need to do some clipping
   for (U32 p = 0; p < mPlaneList.size(); p++) 
   {
      U32 pmask = 1 << p;

      // Only test against this plane if we have something
      // on both sides
      if (!(crossMask & pmask))
         continue;

      U32 indexEnd = mIndexList.size();
      U32 i1 = indexEnd - 1;
      U32 mask1 = mVertexList[mIndexList[i1]].mask;

      for (U32 i2 = indexStart; i2 < indexEnd; i2++) 
      {
         U32 mask2 = mVertexList[mIndexList[i2]].mask;
         if ((mask1 ^ mask2) & pmask) 
         {
            //
            mVertexList.increment();
            VectorF& v1 = mVertexList[mIndexList[i1]].point;
            VectorF& v2 = mVertexList[mIndexList[i2]].point;
            VectorF vv = v2 - v1;
            F32 t = -mPlaneList[p].distToPlane(v1) / mDot(mPlaneList[p],vv);

            mNormalList.increment();
            VectorF& n1 = mNormalList[mIndexList[i1]];
            VectorF& n2 = mNormalList[mIndexList[i1]];
            VectorF nn = mLerp( n1, n2, t );
            nn.normalizeSafe();
            mNormalList.last() = nn;

            mIndexList.push_back/*_noresize*/(mVertexList.size() - 1);
            Vertex& iv = mVertexList.last();
            iv.point.x = v1.x + vv.x * t;
            iv.point.y = v1.y + vv.y * t;
            iv.point.z = v1.z + vv.z * t;
            iv.mask = 0;

            // Test against the remaining planes
            for (U32 i = p + 1; i < mPlaneList.size(); i++)
               if (mPlaneList[i].distToPlane(iv.point) > 0) 
               {
                  iv.mask = 1 << i;
                  break;
               }
         }

         if (!(mask2 & pmask)) 
         {
            U32 index = mIndexList[i2];
            mIndexList.push_back/*_noresize*/(index);
         }

         mask1 = mask2;
         i1 = i2;
      }

      // Check for degenerate
      indexStart = indexEnd;
      if (mIndexList.size() - indexStart < 3) 
      {
         mIndexList.setSize(poly.vertexStart);
         mPolyList.decrement();
         return;
      }
   }

   // Emit what's left and compress the index list.
   poly.vertexCount = mIndexList.size() - indexStart;
   memcpy(&mIndexList[poly.vertexStart],
      &mIndexList[indexStart],poly.vertexCount);
   mIndexList.setSize(poly.vertexStart + poly.vertexCount);
}
Пример #5
0
void SFXEmitter::_renderCone( F32 radialIncrements, F32 sweepIncrements,
                              F32 pointDistance,
                              F32 startAngle, F32 stopAngle,
                              F32 startVolume, F32 stopVolume,
                              const ColorI& color )
{
   if( startAngle == stopAngle )
      return;
      
   const F32 startAngleRadians = mDegToRad( startAngle );
   const F32 stopAngleRadians = mDegToRad( stopAngle );
   const F32 radialIncrementsRadians = mDegToRad( radialIncrements );
      
   // Unit quaternions representing the start and end angle so we
   // can interpolate between the two without flipping.
   
   QuatF rotateZStart( EulerF( 0.f, 0.f, startAngleRadians / 2.f ) );
   QuatF rotateZEnd( EulerF( 0.f, 0.f, stopAngleRadians / 2.f ) );
   
   // Do an angular sweep on one side of our XY disc.  Since we do a full 360 radial sweep
   // around Y for each angle, we only need to sweep over one side.
   
   const F32 increment = 1.f / ( ( ( startAngle / 2.f ) - ( stopAngle / 2.f ) ) / sweepIncrements );
   for( F32 t = 0.f; t < 1.0f; t += increment )
   {
      // Quaternion to rotate point into place on XY disc.
      QuatF rotateZ;
      rotateZ.interpolate( rotateZStart, rotateZEnd, t );
      
      // Quaternion to rotate one position around Y axis.  Used for radial sweep.
      QuatF rotateYOne( EulerF( 0.f, radialIncrementsRadians, 0.f ) );

      // Do a radial sweep each step along the distance axis.  For each step, volume is
      // the same for any point on the sweep circle.

      for( F32 y = pointDistance; y <= mDescription.mMaxDistance; y += pointDistance )
      {
         ColorI c = color;
         
         // Compute volume at current point.  First off, find the interpolated volume
         // in the cone.  Only for the outer cone will this actually result in
         // interpolation.  For the remaining angles, the cone volume is constant.

         F32 volume = mLerp( startVolume, stopVolume, t );
         if( volume == 0.f )
            c.alpha = 0;
         else
         {         
            // Apply distance attenuation.
            
            F32 attenuatedVolume = SFXDistanceAttenuation(
               SFX->getDistanceModel(),
               mDescription.mMinDistance,
               mDescription.mMaxDistance,
               y,
               volume,
               SFX->getRolloffFactor() ); //RDTODO

            // Fade alpha according to how much volume we
            // have left at the current point.
            
            c.alpha = F32( c.alpha ) * ( attenuatedVolume / 1.f );
         }
         
         PrimBuild::color( c );
         
         // Create points by doing a full 360 degree radial sweep around Y.

         Point3F p( 0.f, y, 0.f );
         rotateZ.mulP( p, &p );
         
         for( F32 radialAngle = 0.f; radialAngle < 360.f; radialAngle += radialIncrements )
         {
            PrimBuild::vertex3f( p.x, p.y, p.z );
            rotateYOne.mulP( p, &p );
         }
      }
   }
}