/// Add everything from an object database, swaying positions.
    ///
    /// \param db Database.
    /// \param amplitude Swaying amplitudes.
    /// \param phase Current phase.
    /// \param block_size Block size, objects in same block are considered to be in same phase.
    /// \param pass Render pass id.
    void addObjectDatabaseSwaying(const ObjectDatabase &db, const vec3 &amplitude, float phase,
        unsigned block_size, unsigned pass = 0)
    {
      for(unsigned ii = 0; (ii < db.getObjectCount()); ++ii)
      {
        const Object& obj = db.getObject(ii);

        bsd_srand(ii / block_size);

        float px = frand(-amplitude[0], amplitude[0]);
        float py = frand(-amplitude[1], amplitude[1]);
        float pz = frand(-amplitude[2], amplitude[2]);
        float ax = frand(static_cast<float>(M_PI));
        float ay = frand(static_cast<float>(M_PI));
        float az = frand(static_cast<float>(M_PI));
       
        px *= dnload_sinf(ax + phase * (brand() ? -1.0f : 1.0f));
        py *= dnload_sinf(ay + phase * (brand() ? -1.0f : 1.0f));
        pz *= dnload_sinf(az + phase * (brand() ? -1.0f : 1.0f));

        mat4 tr = obj.unpackTransform(m_frame);

        tr[12] += px;
        tr[13] += py;
        tr[14] += pz;

        addObject(obj, tr, pass);
      }
    }
    /// Add everything from an object database.
    ///
    /// \param db Database.
    /// \param pass Render pass id.
    void addObjectDatabase(const ObjectDatabase &db, unsigned pass = 0)
    {
      for(unsigned ii = 0; (ii < db.getObjectCount()); ++ii)
      {
        const Object& obj = db.getObject(ii);

        addObject(obj, pass);
      }
    }
    /// Add objects from an object database, constructing at limits.
    ///
    /// \param db Database.
    /// \param pos Position to render from.
    /// \param fw Collect objects that have bounding box lying in area this much forward.
    /// \param bk Collect objects that have bounding box lying in area this much backward.
    /// \param interp Fade-in interpolation range (<=0 to disable).
    /// \param pass Render pass id.
    void addObjectDatabaseConstructing(const ObjectDatabase &db, const vec3 &pos, float fw, float bk,
        float fade = 0.0f, unsigned pass = 0)
    {
      unsigned mid = db.find(pos[2]);

#if defined(USE_LD)
      if((fade >= fw) || (fade >= bk))
      {
        std::ostringstream sstr;
        sstr << "fade-in range " << fade << " must be smaller than advance ranges " << vec2(bk, fw);
        BOOST_THROW_EXCEPTION(std::runtime_error(sstr.str()));
      }
#endif

      // Forward.
      {
        float limit = pos[2] + fw;

        for(unsigned ii = mid; (ii < db.getObjectCount()); ++ii)
        {
          const Object &obj = db.getObject(ii);
          float cmp = obj.getBoundingVolume().getMinZ();

          if(cmp <= limit)
          {
            float diff = limit - cmp;
            if(diff <= fade)
            {
              mat4 aa = obj.unpackTransform(m_frame);
              mat4 bb = randomOffsetTransform(aa, obj.getCenter(), ii, diff / fade);

              addObject(obj, bb, pass, false);
            }
            else
            {
              addObject(obj, pass);
            }
          }
          else if(cmp - fade > limit)
          {
            break;
          }
        }
      }

      if(mid > 0)
      {
        float limit = pos[2] - bk;
        unsigned ii = mid - 1;

        for(;;)
        {
          const Object &obj = db.getObject(ii);
          float cmp = obj.getBoundingVolume().getMaxZ();

          if(cmp >= limit)
          {
            float diff = cmp - limit;
            if(diff <= fade)
            {
              //std::cout << "cmp " << cmp << " versus limit " << limit << ", diff: " << diff << std::endl <<
              //  obj.getBoundingVolume() << std::endl;
              mat4 aa = obj.unpackTransform(m_frame);
              mat4 bb = randomOffsetTransform(aa, obj.getCenter(), ii, diff / fade);

              addObject(obj, bb, pass, false);
            }
            else
            {
              addObject(obj, pass);
            }
          }
          else if(cmp + fade < limit)
          {
            break;
          }

          if(0 >= ii)
          {
            break;
          }
          --ii;
        }
      }
    }