Example #1
0
void SFXSource::_updateVolume( const MatrixF& listener )
{
   const F32 volume = mVolume * mModulativeVolume;

   if ( !mIs3D ) 
   {
      mDistToListener = 0.0f;
      mAttenuatedVolume = volume; 
      return;
	}

   Point3F pos, lpos;
   mTransform.getColumn( 3, &pos );
   listener.getColumn( 3, &lpos );

   mDistToListener = ( pos - lpos ).len();
   mAttenuatedVolume = SFXDistanceAttenuation(
      SFX->getDistanceModel(),
      mMinDistance,
      mMaxDistance,
      mDistToListener,
      volume,
      SFX->getRolloffFactor() );
}
Example #2
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 );
         }
      }
   }
}