示例#1
0
void readPackAndWrite(
    uint64_t& writeSize, packet::Packet& pkt,
    cybozu::util::File& fileW, bool doWriteDiff, DiscardType discardType,
    uint64_t fsyncIntervalSize,
    std::vector<char>& zero, AlignedArray& buf)
{
    const char *const FUNC = __func__;
    size_t size;
    pkt.read(size);
    verifyDiffPackSize(size, FUNC);
    buf.resize(size);
    pkt.read(buf.data(), buf.size());

    verifyDiffPack(buf.data(), buf.size(), true);
    if (doWriteDiff) {
        fileW.write(buf.data(), buf.size());
    } else {
        MemoryDiffPack pack(buf.data(), buf.size());
        issueDiffPack(fileW, discardType, pack, zero);
    }
    writeSize += buf.size();
    if (writeSize >= fsyncIntervalSize) {
        fileW.fdatasync();
        writeSize = 0;
    }
}
示例#2
0
void setRandomData(AlignedArray& buf, Rand& rand)
{
    size_t off = 0;
    while (off < buf.size()) {
        const size_t size = std::min<size_t>(buf.size() - off, 16);
        rand.fill(buf.data() + off, size);
        off += 512;
    }
}
示例#3
0
    // ------------------------------------------------------------------------
    void swap(int ID1, int ID2)
    {
        assert(ID1 > -1);
        assert((unsigned int)ID1 < m_contents_vector.size());
        assert(ID2 > -1);
        assert((unsigned int)ID2 < m_contents_vector.size());


        TYPE* temp = m_contents_vector[ID2];

        m_contents_vector[ID2] = m_contents_vector[ID1];
        m_contents_vector[ID1] = temp;
    }   // swap
示例#4
0
    // ------------------------------------------------------------------------
    void clearAndDeleteAll()
    {
        for (unsigned int n=0; n<(unsigned int)m_contents_vector.size(); n++)
        {
            TYPE * pointer = m_contents_vector[n];
            delete pointer;
            m_contents_vector[n] = (TYPE*)0xDEADBEEF;

            // When deleting, it's important that the same pointer cannot be
            // twice in the vector, resulting in a double delete
            assert( !contains(pointer) );
        }
        m_contents_vector.clear();
    }  // clearAndDeleteAll
示例#5
0
void readAndSendHash(
    uint64_t& hashLb,
    packet::Packet& pkt, packet::StreamControl2& ctrl, Reader &reader,
    uint64_t sizeLb, size_t bulkLb,
    cybozu::murmurhash3::Hasher& hasher, AlignedArray& buf)
{
    const uint64_t lb = std::min<uint64_t>(sizeLb - hashLb, bulkLb);
    buf.resize(lb * LOGICAL_BLOCK_SIZE);
    reader.read(buf.data(), buf.size());
    const cybozu::murmurhash3::Hash hash = hasher(buf.data(), buf.size());
    doRetrySockIo(2, "ctrl.send.next", [&]() { ctrl.sendNext(); });
    pkt.write(hash);
    hashLb += lb;
}
示例#6
0
void GFXGLShaderConstBuffer::internalSet(GFXShaderConstHandle* handle, const AlignedArray<ConstType>& fv)
{
   AssertFatal(handle, "GFXGLShaderConstBuffer::internalSet - Handle is NULL!" );
   AssertFatal(handle->isValid(), "GFXGLShaderConstBuffer::internalSet - Handle is not valid!" );
   AssertFatal(dynamic_cast<GFXGLShaderConstHandle*>(handle), "GFXGLShaderConstBuffer::set - Incorrect const buffer type");

   GFXGLShaderConstHandle* _glHandle = static_cast<GFXGLShaderConstHandle*>(handle);
   AssertFatal(mShader == _glHandle->mShader, "GFXGLShaderConstBuffer::set - Should only set handles which are owned by our shader");
   const U8* fvBuffer = static_cast<const U8*>(fv.getBuffer());
   for(U32 i = 0; i < fv.size(); ++i)
   {
      dMemcpy(mBuffer + _glHandle->mOffset + i * sizeof(ConstType), fvBuffer, sizeof(ConstType));
      fvBuffer += fv.getElementSize();
   }
}
示例#7
0
    // ------------------------------------------------------------------------
    const TYPE* get(const int ID) const
    {
        assert(ID > -1);
        assert((unsigned int)ID < (unsigned int)m_contents_vector.size());

        return m_contents_vector[ID];
    }   // get
示例#8
0
    // ------------------------------------------------------------------------
    void erase(const int ID)
    {
        assert(ID > -1);
        assert((unsigned int)ID < (unsigned int)m_contents_vector.size());

        delete ( TYPE *) m_contents_vector[ID];
#ifdef USE_ALIGNED
        const unsigned int amount = (unsigned int)m_contents_vector.size();
        for(unsigned int i=ID; i<amount-1; i++)
        {
            m_contents_vector[i]=m_contents_vector[i+1];
        }
        m_contents_vector.pop_back();
#else
        m_contents_vector.erase(m_contents_vector.begin()+ID);
#endif
    }   // erase
示例#9
0
 /** Returns the start coordinates for a kart with a given index.
  *  \param index Index of kart ranging from 0 to kart_num-1. */
 btTransform        getStartTransform (unsigned int index) const
 {
     if (index >= m_start_transforms.size())
     {
         fprintf(stderr, "No start position for kart %i\n", index);
         abort();
     }
     return m_start_transforms[index];
 }
uint64_t readAndValidateLogPackIo(cybozu::util::File& file, const device::SuperBlock& super, const LogPackHeader& logh)
{
    const uint32_t pbs = super.getPhysicalBlockSize();
    assert(logh.isValid());
    AlignedArray buf;
    for (size_t i = 0; i < logh.nRecords(); i++) {
        const WlogRecord &rec = logh.record(i);
        if (!rec.hasDataForChecksum()) continue;
        const uint64_t pb = super.getOffsetFromLsid(rec.lsid);
        const size_t ioSize = rec.ioSizeLb() * LBS;
        buf.resize(ioSize);
        file.pread(buf.data(), ioSize, pb * pbs);
        const uint32_t csum = cybozu::util::calcChecksum(buf.data(), buf.size(), logh.salt());
        if (csum == rec.checksum) continue;
        LOGs.info() << "INVALID_LOGPACK_IO" << rec << csum;
    }
    return logh.nextLogpackLsid();
}
示例#11
0
    // ------------------------------------------------------------------------
    bool contains( const TYPE* instance ) const
    {
        const unsigned int amount = (unsigned int)m_contents_vector.size();
        for (unsigned int n=0; n<amount; n++)
        {
            const TYPE * pointer = m_contents_vector[n];
            if (pointer == instance) return true;
        }

        return false;
    }   // contains
示例#12
0
 // ------------------------------------------------------------------------
 void insertionSort(unsigned int start=0, bool desc = false)
 {
     if (!desc)
     {
         // We should not used unsigned ints here, because if the vector is
         // empty j needs to be compared against -1
         for(int j=(int)start; j<(int)m_contents_vector.size()-1; j++)
         {
             if(*(m_contents_vector[j])<*(m_contents_vector[j+1])) continue;
             // Now search the proper place for m_contents_vector[j+1]
             // in the sorted section contentsVectot[start:j]
             TYPE* t=m_contents_vector[j+1];
             unsigned int i = j+1;
             do
             {
                 m_contents_vector[i] = m_contents_vector[i-1];
                 i--;
             } while (i>start && *t<*(m_contents_vector[i-1]));
             m_contents_vector[i]=t;
         }
     }
     else
     {
         for(int j=(int)start; j<(int)m_contents_vector.size()-1; j++)
          {
              if(*(m_contents_vector[j+1])<*(m_contents_vector[j])) continue;
              // Now search the proper place for m_contents_vector[j+1]
              // in the sorted section contentsVectot[start:j]
              TYPE* t=m_contents_vector[j+1];
              unsigned int i = j+1;
              do
              {
                  m_contents_vector[i] = m_contents_vector[i-1];
                  i--;
              } while (i>start && *(m_contents_vector[i-1]) <*t);
              m_contents_vector[i]=t;
          }
      }
 }   // insertionSort
示例#13
0
/*
 * @zero is used as zero-filled buffer. It may be resized.
 */
inline void issueDiffPack(cybozu::util::File& file, DiscardType discardType, MemoryDiffPack& pack, std::vector<char>& zero)
{
    const DiffPackHeader& head = pack.header();
    DiffRecord rec;
    AlignedArray array; // buffer for uncompressed data.
    for (size_t i = 0; i < head.n_records; i++) {
        const DiffRecord& inRec = head[i];
        const char *iodata = nullptr;
        if (inRec.isNormal()) {
            if (inRec.isCompressed()) {
                uncompressDiffIo(inRec, pack.data(i), rec, array, false);
                iodata = array.data();
            } else {
                rec = inRec;
                iodata = pack.data(i);
            }
        } else {
            rec = inRec;
        }
        issueIo(file, discardType, rec, iodata, zero);
    }
}
示例#14
0
/*
	read text data from fileName
*/
inline bool LoadFile(AlignedArray<char>& textBuf, const std::string& fileName)
{
	std::ifstream ifs(fileName.c_str(), std::ios::binary);
	if (!ifs) return false;
	ifs.seekg(0, std::ifstream::end);
	const size_t size = ifs.tellg();
	ifs.seekg(0);
	fprintf(stderr, "size=%d\n", (int)size);
	textBuf.resize(size + 1);
	ifs.read(&textBuf[0], size);
	textBuf[size] = '\0';
	return true;
}
示例#15
0
    /**
    * \brief Removes and deletes the given object.
    * \return whether this object was found in the vector and deleted
    */
    bool erase(void* obj)
    {
        for(unsigned int n=0; n<(unsigned int)m_contents_vector.size(); n++)
        {
            TYPE * pointer = m_contents_vector[n];
            if((void*)pointer == obj)
            {
#ifdef USE_ALIGNED
                const unsigned int amount =
                    (unsigned int)m_contents_vector.size();
                for(unsigned int i=n; i<amount-1; i++)
                {
                    m_contents_vector[i]=m_contents_vector[i+1];
                }
                m_contents_vector.pop_back();
#else
                m_contents_vector.erase(m_contents_vector.begin()+n);
#endif
                delete pointer;
                return true;
            }
        }   // for n < size()
        return false;
    }   // erase
示例#16
0
    /**
    * Removes without deleting
    */
    void remove(TYPE* obj)
    {
        for(unsigned int n=0; n<(unsigned int)m_contents_vector.size(); n++)
        {

            TYPE * pointer = m_contents_vector[n];
            if(pointer == obj)
            {
#ifdef USE_ALIGNED
                const unsigned int amount =
                    (unsigned int)m_contents_vector.size();
                for(unsigned int i=n; i<amount-1; i++)
                {
                    m_contents_vector[i]=m_contents_vector[i+1];
                }
                m_contents_vector.pop_back();
#else
                m_contents_vector.erase(m_contents_vector.begin()+n);
#endif
                return;
            }
        }   // for n < size()

    }   // remove
示例#17
0
 bool empty() const
 {
     return m_contents_vector.empty();
 }
示例#18
0
 // ------------------------------------------------------------------------
 void clearWithoutDeleting()
 {
     m_contents_vector.clear();
 }   // clearWithoutDeleting
示例#19
0
    // ------------------------------------------------------------------------
    const TYPE& operator[](const unsigned int ID) const
    {
        assert((unsigned int)ID < (unsigned int)m_contents_vector.size());

        return *(m_contents_vector[ID]);
    }   // operator[]
示例#20
0
 /** Returns the start coordinates for a kart with a given index.
  *  \param index Index of kart ranging from 0 to kart_num-1. */
 btTransform        getStartTransform (unsigned int index) const
 {
     if (index >= m_start_transforms.size())
         Log::fatal("Tracj", "No start position for kart %i.", index);
     return m_start_transforms[index];
 }
示例#21
0
inline bool dirtyHashSyncClient(
    packet::Packet &pkt, Reader &reader,
    uint64_t sizeLb, uint64_t bulkLb, uint32_t hashSeed,
    const std::atomic<int> &stopState, const ProcessStatus &ps,
    const std::atomic<uint64_t>& maxLbPerSec)
{
    const char *const FUNC = __func__;
    packet::StreamControl2 recvCtl(pkt.sock());
    packet::StreamControl2 sendCtl(pkt.sock());
    DiffPacker packer;
    walb::PackCompressor compr(::WALB_DIFF_CMPR_SNAPPY);
    cybozu::murmurhash3::Hasher hasher(hashSeed);
    ThroughputStabilizer thStab;

    uint64_t addr = 0;
    uint64_t remainingLb = sizeLb;
    AlignedArray buf;
    size_t cHash = 0, cSend = 0, cDummy = 0;
    try {
    for (;;) {
        if (stopState == ForceStopping || ps.isForceShutdown()) {
            return false;
        }
        dirty_hash_sync_local::doRetrySockIo(4, "ctrl.recv", [&]() { recvCtl.recv(); });
        if (recvCtl.isNext()) {
            if (remainingLb == 0) throw cybozu::Exception(FUNC) << "has next but remainingLb is zero";
        } else {
            if (remainingLb == 0) break;
            throw cybozu::Exception(FUNC) << "no next but remainingLb is not zero" << remainingLb;
        }
        cybozu::murmurhash3::Hash recvHash;
        pkt.read(recvHash);
        cHash++;

        const uint32_t lb = std::min<uint64_t>(remainingLb, bulkLb);
        buf.resize(lb * LOGICAL_BLOCK_SIZE);
        reader.read(buf.data(), buf.size());

        // to avoid socket timeout.
        dirty_hash_sync_local::doRetrySockIo(4, "ctrl.send.dummy", [&]() { sendCtl.sendDummy(); });
        cDummy++; cSend++;

        const cybozu::murmurhash3::Hash bdHash = hasher(buf.data(), buf.size());
        const uint64_t bgnAddr = packer.empty() ? addr : packer.header()[0].io_address;
        if (addr - bgnAddr >= DIRTY_HASH_SYNC_MAX_PACK_AREA_LB && !packer.empty()) {
            dirty_hash_sync_local::doRetrySockIo(4, "ctrl.send.next0", [&]() { sendCtl.sendNext(); });
            cSend++;
            dirty_hash_sync_local::compressAndSend(pkt, packer, compr);
        }
        if (recvHash != bdHash && !packer.add(addr, lb, buf.data())) {
            dirty_hash_sync_local::doRetrySockIo(4, "ctrl.send.next1", [&]() { sendCtl.sendNext(); });
            cSend++;
            dirty_hash_sync_local::compressAndSend(pkt, packer, compr);
            packer.add(addr, lb, buf.data());
        }
        pkt.flush();
        remainingLb -= lb;
        addr += lb;
        thStab.setMaxLbPerSec(maxLbPerSec.load());
        thStab.addAndSleepIfNecessary(lb, 10, 100);
    }
    } catch (...) {
        LOGs.warn() << "SEND_CTL" << cHash << cSend << cDummy;
        throw;
    }
    if (!packer.empty()) {
        dirty_hash_sync_local::doRetrySockIo(4, "ctrl.send.next2", [&]() { sendCtl.sendNext(); });
        cSend++;
        dirty_hash_sync_local::compressAndSend(pkt, packer, compr);
    }
    if (recvCtl.isError()) {
        throw cybozu::Exception(FUNC) << "recvCtl";
    }
    dirty_hash_sync_local::doRetrySockIo(4, "ctrl.send.next2", [&]() { sendCtl.sendEnd(); });
    pkt.flush();

    LOGs.debug() << "SEND_CTL" << cHash << cSend << cDummy;
    return true;
}
示例#22
0
 void push_back(TYPE* t)
 {
     m_contents_vector.push_back(t);
 }   // push_back
示例#23
0
void ModelViewWidget::setupRTTScene(PtrVector<scene::IMesh, REF>& mesh,
                                    AlignedArray<Vec3>& mesh_location,
                                    AlignedArray<Vec3>& mesh_scale,
                                    const std::vector<int>& model_frames)
{
    irr_driver->suppressSkyBox();
    
    if (m_rtt_main_node != NULL) m_rtt_main_node->remove();
    if (m_light != NULL) m_light->remove();
    if (m_camera != NULL) m_camera->remove();
    
    m_rtt_main_node = NULL;
    m_camera = NULL;
    m_light = NULL;
    
    irr_driver->clearLights();
    
    if (model_frames[0] == -1)
    {
        scene::ISceneNode* node = irr_driver->addMesh(mesh.get(0), "rtt_mesh", NULL);
        node->setPosition(mesh_location[0].toIrrVector());
        node->setScale(mesh_scale[0].toIrrVector());
        node->setMaterialFlag(video::EMF_FOG_ENABLE, false);
        m_rtt_main_node = node;
    }
    else
    {
        scene::IAnimatedMeshSceneNode* node =
        irr_driver->addAnimatedMesh((scene::IAnimatedMesh*)mesh.get(0), "rtt_mesh", NULL);
        node->setPosition(mesh_location[0].toIrrVector());
        node->setFrameLoop(model_frames[0], model_frames[0]);
        node->setAnimationSpeed(0);
        node->setScale(mesh_scale[0].toIrrVector());
        node->setMaterialFlag(video::EMF_FOG_ENABLE, false);
        
        m_rtt_main_node = node;
    }
    
    assert(m_rtt_main_node != NULL);
    assert(mesh.size() == mesh_location.size());
    assert(mesh.size() == model_frames.size());
    
    const int mesh_amount = mesh.size();
    for (int n = 1; n<mesh_amount; n++)
    {
        if (model_frames[n] == -1)
        {
            scene::ISceneNode* node =
            irr_driver->addMesh(mesh.get(n), "rtt_node", m_rtt_main_node);
            node->setPosition(mesh_location[n].toIrrVector());
            node->updateAbsolutePosition();
            node->setScale(mesh_scale[n].toIrrVector());
        }
        else
        {
            scene::IAnimatedMeshSceneNode* node =
            irr_driver->addAnimatedMesh((scene::IAnimatedMesh*)mesh.get(n),
                                        "modelviewrtt", m_rtt_main_node);
            node->setPosition(mesh_location[n].toIrrVector());
            node->setFrameLoop(model_frames[n], model_frames[n]);
            node->setAnimationSpeed(0);
            node->updateAbsolutePosition();
            node->setScale(mesh_scale[n].toIrrVector());
            //Log::info("ModelViewWidget", "Set frame %d", model_frames[n]);
        }
    }
    
    irr_driver->getSceneManager()->setAmbientLight(video::SColor(255, 35, 35, 35));
    
    const core::vector3df &spot_pos = core::vector3df(0, 30, 40);
    m_light = irr_driver->addLight(spot_pos, 0.3f /* energy */, 10 /* distance */, 1.0f /* r */, 1.0f /* g */, 1.0f /* g*/, true, NULL);
    
    m_rtt_main_node->setMaterialFlag(video::EMF_GOURAUD_SHADING, true);
    m_rtt_main_node->setMaterialFlag(video::EMF_LIGHTING, true);
    
    const int materials = m_rtt_main_node->getMaterialCount();
    for (int n = 0; n<materials; n++)
    {
        m_rtt_main_node->getMaterial(n).setFlag(video::EMF_LIGHTING, true);
        
        // set size of specular highlights
        m_rtt_main_node->getMaterial(n).Shininess = 100.0f;
        m_rtt_main_node->getMaterial(n).SpecularColor.set(255, 50, 50, 50);
        m_rtt_main_node->getMaterial(n).DiffuseColor.set(255, 150, 150, 150);
        
        m_rtt_main_node->getMaterial(n).setFlag(video::EMF_GOURAUD_SHADING,
                                                true);
    }
    
    m_camera = irr_driver->getSceneManager()->addCameraSceneNode();
    m_camera->setAspectRatio(1.0f);
    
    m_camera->setPosition(core::vector3df(0.0, 20.0f, 70.0f));
    m_camera->setUpVector(core::vector3df(0.0, 1.0, 0.0));
    m_camera->setTarget(core::vector3df(0, 10, 0.0f));
    m_camera->setFOV(DEGREE_TO_RAD*50.0f);
    m_camera->updateAbsolutePosition();
}
示例#24
0
 /** Returns the number of points in this bezier curve. */
 unsigned int getNumPoints() const {
     return (unsigned int) m_all_data.size();
 }
void LightManager::_update4LightConsts(   const SceneData &sgData,
                                          GFXShaderConstHandle *lightPositionSC,
                                          GFXShaderConstHandle *lightDiffuseSC,
                                          GFXShaderConstHandle *lightAmbientSC,
                                          GFXShaderConstHandle *lightInvRadiusSqSC,
                                          GFXShaderConstHandle *lightSpotDirSC,
                                          GFXShaderConstHandle *lightSpotAngleSC,
										  GFXShaderConstHandle *lightSpotFalloffSC,
                                          GFXShaderConstBuffer *shaderConsts )
{
   PROFILE_SCOPE( LightManager_Update4LightConsts );

   // Skip over gathering lights if we don't have to!
   if (  lightPositionSC->isValid() || 
         lightDiffuseSC->isValid() ||
         lightInvRadiusSqSC->isValid() ||
         lightSpotDirSC->isValid() ||
         lightSpotAngleSC->isValid() ||
		 lightSpotFalloffSC->isValid() )
   {
      PROFILE_SCOPE( LightManager_Update4LightConsts_setLights );

      static AlignedArray<Point4F> lightPositions( 3, sizeof( Point4F ) );
      static AlignedArray<Point4F> lightSpotDirs( 3, sizeof( Point4F ) );
      static AlignedArray<Point4F> lightColors( 4, sizeof( Point4F ) );
      static Point4F lightInvRadiusSq;
      static Point4F lightSpotAngle;
	  static Point4F lightSpotFalloff;
      F32 range;
      
      // Need to clear the buffers so that we don't leak
      // lights from previous passes or have NaNs.
      dMemset( lightPositions.getBuffer(), 0, lightPositions.getBufferSize() );
      dMemset( lightSpotDirs.getBuffer(), 0, lightSpotDirs.getBufferSize() );
      dMemset( lightColors.getBuffer(), 0, lightColors.getBufferSize() );
      lightInvRadiusSq = Point4F::Zero;
      lightSpotAngle.set( -1.0f, -1.0f, -1.0f, -1.0f );
      lightSpotFalloff.set( F32_MAX, F32_MAX, F32_MAX, F32_MAX );

      // Gather the data for the first 4 lights.
      const LightInfo *light;
      for ( U32 i=0; i < 4; i++ )
      {
         light = sgData.lights[i];
         if ( !light )            
            break;
      
            // The light positions and spot directions are 
            // in SoA order to make optimal use of the GPU.
            const Point3F &lightPos = light->getPosition();
            lightPositions[0][i] = lightPos.x;
            lightPositions[1][i] = lightPos.y;
            lightPositions[2][i] = lightPos.z;

            const VectorF &lightDir = light->getDirection();
            lightSpotDirs[0][i] = lightDir.x;
            lightSpotDirs[1][i] = lightDir.y;
            lightSpotDirs[2][i] = lightDir.z;
            
            if ( light->getType() == LightInfo::Spot )
			{
               lightSpotAngle[i] = mCos( mDegToRad( light->getOuterConeAngle() / 2.0f ) ); 
			   lightSpotFalloff[i] = 1.0f / getMax( F32_MIN, mCos( mDegToRad( light->getInnerConeAngle() / 2.0f ) ) - lightSpotAngle[i] );
			}

         // Prescale the light color by the brightness to 
         // avoid doing this in the shader.
         lightColors[i] = Point4F(light->getColor()) * light->getBrightness();

         // We need 1 over range^2 here.
         range = light->getRange().x;
         lightInvRadiusSq[i] = 1.0f / ( range * range );
      }

      shaderConsts->setSafe( lightPositionSC, lightPositions );   
      shaderConsts->setSafe( lightDiffuseSC, lightColors );
      shaderConsts->setSafe( lightInvRadiusSqSC, lightInvRadiusSq );
      
      shaderConsts->setSafe( lightSpotDirSC, lightSpotDirs ); 
      shaderConsts->setSafe( lightSpotAngleSC, lightSpotAngle );
		shaderConsts->setSafe( lightSpotFalloffSC, lightSpotFalloff );

      
   }

   // Setup the ambient lighting from the first 
   // light which is the directional light if 
   // one exists at all in the scene.
   if ( lightAmbientSC->isValid() )
      shaderConsts->set( lightAmbientSC, sgData.ambientLightColor );
}
示例#26
0
 /** Get the number of start positions defined in the scene file. */
 unsigned int getNumberOfStartPositions() const
                                       { return m_start_transforms.size(); }
示例#27
0
 // ------------------------------------------------------------------------
 unsigned int size() const
 {
     return m_contents_vector.size();
 }   // size
示例#28
0
//-----------------------------------------------------------------------------
bool ItemManager::randomItemsForArena(const AlignedArray<btTransform>& pos)
{
    if (!UserConfigParams::m_random_arena_item) return false;
    if (!BattleGraph::get()) return false;

    std::vector<int> used_location;
    std::vector<int> invalid_location;
    for (unsigned int i = 0; i < pos.size(); i++)
    {
        // Load all starting positions of arena, so no items will be near them
        int node = BattleGraph::get()->pointToNode(/*cur_node*/-1,
            Vec3(pos[i].getOrigin()), /*ignore_vertical*/true);
        assert(node != -1);
        used_location.push_back(node);
        invalid_location.push_back(node);
    }

    RandomGenerator random;
    const unsigned int MIN_DIST = int(sqrt(BattleGraph::get()->getNumNodes()));
    const unsigned int TOTAL_ITEM = MIN_DIST / 2;

    Log::info("[ItemManager]","Creating %d random items for arena", TOTAL_ITEM);
    for (unsigned int i = 0; i < TOTAL_ITEM; i++)
    {
        int chosen_node = -1;
        const unsigned int total_node = BattleGraph::get()->getNumNodes();
        while(true)
        {
            if (used_location.size() - pos.size() +
                invalid_location.size() == total_node)
            {
                Log::warn("[ItemManager]","Can't place more random items! "
                    "Use default item location.");
                return false;
            }

            const int node = random.get(total_node);

            // Check if tried
            std::vector<int>::iterator it = std::find(invalid_location.begin(),
                invalid_location.end(), node);
            if (it != invalid_location.end())
                continue;

            // Check if near edge
            if (BattleGraph::get()->isNearEdge(node))
            {
                invalid_location.push_back(node);
                continue;
            }
            // Check if too close
            bool found = true;
            for (unsigned int j = 0; j < used_location.size(); j++)
            {
                if (!found) continue;
                Vec3 d = BattleGraph::get()
                    ->getPolyOfNode(used_location[j]).getCenter() -
                    BattleGraph::get()->getPolyOfNode(node).getCenter();
                found = d.length_2d() > MIN_DIST;
            }
            if (found)
            {
                chosen_node = node;
                invalid_location.push_back(node);
                break;
            }
            else
                invalid_location.push_back(node);
        }

        assert(chosen_node != -1);
        used_location.push_back(chosen_node);
    }

    for (unsigned int i = 0; i < pos.size(); i++)
        used_location.erase(used_location.begin());

    assert (used_location.size() == TOTAL_ITEM);

    // Hard-coded ratio for now
    const int BONUS_BOX = 4;
    const int NITRO_BIG = 2;
    const int NITRO_SMALL = 1;

    for (unsigned int i = 0; i < TOTAL_ITEM; i++)
    {
        const int j = random.get(10);
        Item::ItemType type = (j > BONUS_BOX ? Item::ITEM_BONUS_BOX :
            j > NITRO_BIG ? Item::ITEM_NITRO_BIG :
            j > NITRO_SMALL ? Item::ITEM_NITRO_SMALL : Item::ITEM_BANANA);
        Vec3 loc = BattleGraph::get()
            ->getPolyOfNode(used_location[i]).getCenter();
        Item* item = newItem(type, loc, Vec3(0, 1, 0));
        BattleGraph::get()->insertItems(item, used_location[i]);
    }

    return true;
}   // randomItemsForArena