Ejemplo n.º 1
0
void AssetDownloadTask::handleAssetParsed(Mesh::MeshdataPtr md) {
    mAsset = md;

    if (!md) {
        SILOG(ogre,error,"Failed to parse mesh " << mAssetURI.toString());
        mCB();
        return;
    }

    // This is a sanity check. There's no way Ogre can reasonably handle meshes
    // that require a ton of draw calls. Estimate them here and if its too high,
    // destroy the data and invoke the callback to make it look like failure.
    {
        // Draw calls =
        //   Number of instances * number of primitives in instance
        uint32 draw_calls = 0;
        Meshdata::GeometryInstanceIterator geoinst_it = md->getGeometryInstanceIterator();
        uint32 geoinst_idx;
        Matrix4x4f pos_xform;
        while( geoinst_it.next(&geoinst_idx, &pos_xform) )
            draw_calls += md->geometry[ md->instances[geoinst_idx].geometryIndex ].primitives.size();

        // Arbitrary number, but probably more than we should even allow given
        // that there are probably hundreds or thousands of other objects
        if (draw_calls > 500) {
            SILOG(ogre,error,"Excessively complicated mesh: " << mAssetURI.toString() << " has " << draw_calls << " draw calls. Ignoring this mesh.");
            mAsset = Mesh::MeshdataPtr();
            mCB();
            return;
        }
    }

    mRemainingDownloads = md->textures.size();

    // Special case for no dependent downloads
    if (mRemainingDownloads == 0) {
        mCB();
        return;
    }

    String assetURIString = mAssetURI.toString();
    for(TextureList::const_iterator it = md->textures.begin(); it != md->textures.end(); it++) {
        String texURIString = assetURIString.substr(0, assetURIString.rfind("/")+1) + (*it);
        Transfer::URI texURI(texURIString);
        ResourceDownloadTaskPtr dl = ResourceDownloadTask::construct(
            texURI, mScene->transferPool(),
            mPriority,
            std::tr1::bind(&AssetDownloadTask::weakTextureDownloaded, getWeakPtr(), _1, _2)
        );
        mActiveDownloads[texURI] = dl;
        dl->start();
    }
}
Ejemplo n.º 2
0
void AssetDownloadTask::textureDownloaded(Transfer::URI uri, ResourceDownloadTaskPtr taskptr, Transfer::TransferRequestPtr request, Transfer::DenseDataPtr response) {
    // This could be triggered by any CDN thread, protect access
    // (mActiveDownloads, mDependencies)
    boost::mutex::scoped_lock lok(mDependentDownloadMutex);

    if (!taskptr) {
        SILOG(ogre, warn, "failed request dependent callback");
        failDownload();
        return;
    }

    if (!request) {
        SILOG(ogre, warn, "failed request dependent callback " << taskptr->getIdentifier());
        failDownload();
        return;
    }

    // Clear the download task
    mActiveDownloads.erase(taskptr->getIdentifier());
    mFinishedDownloads.push_back(taskptr->getIdentifier());

    // Lack of response data means failure of some sort
    if (!response) {
        SILOG(ogre, warn, "failed response dependent callback " << taskptr->getIdentifier());
        failDownload();
        return;
    }

    // Store data for later use
    mDependencies[uri].request = request;
    mDependencies[uri].response = response;

    if (mActiveDownloads.size() == 0)
        mCB();
}
Ejemplo n.º 3
0
void AssetDownloadTask::failDownload() {
    // Cancel will stop the current download process.
    cancel();

    // In this case, since it wasn't user requested, we also clear any parsed
    // data (e.g. if we failed on a texture download) and trigger a callback to
    // let them know about the failure.
    mAsset.reset();
    mCB();
}
Ejemplo n.º 4
0
void AssetDownloadTask::textureDownloaded(std::tr1::shared_ptr<ChunkRequest> request, std::tr1::shared_ptr<const DenseData> response) {
    // Clear the download task
    mActiveDownloads.erase(request->getURI());

    // Lack of response data means failure of some sort
    if (!response) {
        failDownload();
        return;
    }

    // Store data for later use
    mDependencies[request->getURI()].request = request;
    mDependencies[request->getURI()].response = response;

    mRemainingDownloads--;
    if (mRemainingDownloads == 0)
        mCB();
}
Ejemplo n.º 5
0
void AssetDownloadTask::handleAssetParsed(Mesh::VisualPtr vis) {
    mAsset = vis;

    if (!vis) {
        SILOG(ogre,error,"Failed to parse mesh " << mAssetURI.toString());
        mCB();
        return;
    }

    // Now we need to handle downloads for each type of Visual.
    MeshdataPtr md( std::tr1::dynamic_pointer_cast<Meshdata>(vis) );
    if (md) {
        // This is a sanity check. There's no way Ogre can reasonably handle meshes
        // that require a ton of draw calls. Estimate them here and if its too high,
        // destroy the data and invoke the callback to make it look like failure.
        {
            // Draw calls =
            //   Number of instances * number of primitives in instance
            uint32 draw_calls = 0;
            Meshdata::GeometryInstanceIterator geoinst_it = md->getGeometryInstanceIterator();
            uint32 geoinst_idx;
            Matrix4x4f pos_xform;
            while( geoinst_it.next(&geoinst_idx, &pos_xform) )
                draw_calls += md->geometry[ md->instances[geoinst_idx].geometryIndex ].primitives.size();

            // Arbitrary number, but probably more than we should even allow given
            // that there are probably hundreds or thousands of other objects
            if (draw_calls > 500) {
                SILOG(ogre,error,"Excessively complicated mesh: " << mAssetURI.toString() << " has " << draw_calls << " draw calls. Ignoring this mesh.");
                mAsset = Mesh::VisualPtr();
                mCB();
                return;
            }
        }
        // Another sanity check: if we have an excessive number of textures,
        // we're probably going to hit some memory constraints
        {
            // Complete arbitrary number
            if (md->textures.size() > 100) {
                SILOG(ogre,error, "Mesh with excessive number of textures: " << mAssetURI.toString() << " has " << md->textures.size() << " textures. Ignoring this mesh.");
                mAsset = Mesh::VisualPtr();
                mCB();
                return;
            }
        }

        // Special case for no dependent downloads
        if (md->textures.size() == 0) {
            mCB();
            return;
        }

        for(TextureList::const_iterator it = md->textures.begin(); it != md->textures.end(); it++) {
            const std::string& texName = *it;
            Transfer::URI texURI( getURL(mAssetURI, texName) );

            ProgressiveMipmapMap::const_iterator findProgTex;
            if (md->progressiveData) {
                findProgTex = md->progressiveData->mipmaps.find(texName);
            }

            if (md->progressiveData && findProgTex != md->progressiveData->mipmaps.end()) {
                const ProgressiveMipmaps& progMipmaps = findProgTex->second.mipmaps;
                uint32 mipmapLevel = 0;
                for ( ; mipmapLevel < progMipmaps.size(); mipmapLevel++) {
                    if (progMipmaps.find(mipmapLevel)->second.width >= 128 || progMipmaps.find(mipmapLevel)->second.height >= 128) {
                        break;
                    }
                }
                uint32 offset = progMipmaps.find(mipmapLevel)->second.offset;
                uint32 length = progMipmaps.find(mipmapLevel)->second.length;
                Transfer::Fingerprint hash = findProgTex->second.archiveHash;
                addDependentDownload(texURI, Transfer::Chunk(hash, Transfer::Range(offset, length, Transfer::LENGTH)));
            } else {
                addDependentDownload(texURI);
            }
        }

        startDependentDownloads();

        return;
    }

    BillboardPtr bboard( std::tr1::dynamic_pointer_cast<Billboard>(vis) );
    if (bboard) {
        // For billboards, we have to download at least the image to display on
        // it
        Transfer::URI texURI( getURL(mAssetURI, bboard->image) );
        addDependentDownload(texURI);
        startDependentDownloads();
        return;
    }

    // If we've gotten here, then we haven't handled the specific type of visual
    // and we need to issue a warning and callback.
    SILOG(ogre, error, "Tried to use AssetDownloadTask for a visual type it doesn't handle (" << vis->type() << "). Not downloading dependent resources.");
    mCB();
}