void LLMaterialMgr::processPutQueue() { typedef std::map<LLViewerRegion*, LLSD> regionput_request_map; regionput_request_map requests; put_queue_t::iterator loopQueue = mPutQueue.begin(); while (mPutQueue.end() != loopQueue) { put_queue_t::iterator itQueue = loopQueue++; const LLUUID& object_id = itQueue->first; const LLViewerObject* objectp = gObjectList.findObject(object_id); if ( !objectp ) { LL_WARNS("Materials") << "Object is NULL" << LL_ENDL; mPutQueue.erase(itQueue); } else { LLViewerRegion* regionp = objectp->getRegion(); if ( !regionp ) { LL_WARNS("Materials") << "Object region is NULL" << LL_ENDL; mPutQueue.erase(itQueue); } else if ( regionp->capabilitiesReceived() && !regionp->materialsCapThrottled()) { LLSD& facesData = requests[regionp]; facematerial_map_t& face_map = itQueue->second; U32 max_entries = regionp->getMaxMaterialsPerTransaction(); facematerial_map_t::iterator itFace = face_map.begin(); while ( (face_map.end() != itFace) && (facesData.size() < (int)max_entries) ) { LLSD faceData = LLSD::emptyMap(); faceData[MATERIALS_CAP_FACE_FIELD] = static_cast<LLSD::Integer>(itFace->first); faceData[MATERIALS_CAP_OBJECT_ID_FIELD] = static_cast<LLSD::Integer>(objectp->getLocalID()); if (!itFace->second.isNull()) { faceData[MATERIALS_CAP_MATERIAL_FIELD] = itFace->second.asLLSD(); } facesData.append(faceData); face_map.erase(itFace++); } if (face_map.empty()) { mPutQueue.erase(itQueue); } } } } for (regionput_request_map::const_iterator itRequest = requests.begin(); itRequest != requests.end(); ++itRequest) { LLViewerRegion* regionp = itRequest->first; std::string capURL = regionp->getCapability(MATERIALS_CAPABILITY_NAME); if (capURL.empty()) { LL_WARNS("Materials") << "Capability '" << MATERIALS_CAPABILITY_NAME << "' is not defined on region '" << regionp->getName() << "'" << LL_ENDL; continue; } LLSD materialsData = LLSD::emptyMap(); materialsData[MATERIALS_CAP_FULL_PER_FACE_FIELD] = itRequest->second; std::string materialString = zip_llsd(materialsData); S32 materialSize = materialString.size(); if (materialSize > 0) { LLSD::Binary materialBinary; materialBinary.resize(materialSize); memcpy(materialBinary.data(), materialString.data(), materialSize); LLSD putData = LLSD::emptyMap(); putData[MATERIALS_CAP_ZIP_FIELD] = materialBinary; LL_DEBUGS("Materials") << "put for " << itRequest->second.size() << " faces to region " << itRequest->first->getName() << LL_ENDL; LLHTTPClient::ResponderPtr materialsResponder = new LLMaterialsResponder("PUT", capURL, boost::bind(&LLMaterialMgr::onPutResponse, this, _1, _2)); LLHTTPClient::put(capURL, putData, materialsResponder); regionp->resetMaterialsCapThrottle(); } else { LL_ERRS("debugMaterials") << "cannot zip LLSD binary content" << LL_ENDL; } } }
void FSFloaterObjectExport::onIdle() { switch(mExportState) { case IDLE: break; case INVENTORY_DOWNLOAD: if (gDisconnected) { return; } if (mInventoryRequests.empty()) { mLastRequest = mAssetRequests.size(); mWaitTimer.start(); mExportState = ASSET_DOWNLOAD; } else if (mLastRequest != mInventoryRequests.size()) { mWaitTimer.start(); mLastRequest = mInventoryRequests.size(); updateTitleProgress(INVENTORY_DOWNLOAD); } else if (mWaitTimer.getElapsedTimeF32() > MAX_INVENTORY_WAIT_TIME) { mWaitTimer.start(); for (uuid_vec_t::const_iterator iter = mInventoryRequests.begin(); iter != mInventoryRequests.end(); ++iter) { LLViewerObject* object = gObjectList.findObject((*iter)); object->dirtyInventory(); object->requestInventory(); LL_DEBUGS("export") << "re-requested inventory of " << (*iter).asString() << LL_ENDL; } } break; case ASSET_DOWNLOAD: if (gDisconnected) { return; } if (mAssetRequests.empty()) { mLastRequest = mRequestedTexture.size(); mWaitTimer.start(); mExportState = TEXTURE_DOWNLOAD; } else if (mLastRequest != mAssetRequests.size()) { mWaitTimer.start(); mLastRequest = mAssetRequests.size(); updateTitleProgress(ASSET_DOWNLOAD); } else if (mWaitTimer.getElapsedTimeF32() > MAX_ASSET_WAIT_TIME) { //abort for now LL_DEBUGS("export") << "Asset timeout with " << (S32)mAssetRequests.size() << " requests left." << LL_ENDL; for (uuid_vec_t::iterator iter = mAssetRequests.begin(); iter != mAssetRequests.end(); ++iter) { LL_DEBUGS("export") << "Asset: " << (*iter).asString() << LL_ENDL; } mAssetRequests.clear(); } break; case TEXTURE_DOWNLOAD: if (gDisconnected) { return; } if(mRequestedTexture.empty()) { mExportState = IDLE; if (!gIdleCallbacks.deleteFunction(onIdle, this)) { LL_WARNS("export") << "Failed to delete idle callback" << LL_ENDL; } mWaitTimer.stop(); llofstream file; file.open(mFilename.c_str(), std::ios_base::out | std::ios_base::binary); std::string zip_data = zip_llsd(mManifest); file.write(zip_data.data(), zip_data.size()); file.close(); LL_DEBUGS("export") << "Export finished and written to " << mFilename << LL_ENDL; LLSD args; args["FILENAME"] = mFilename; LLNotificationsUtil::add("ExportFinished", args); closeFloater(); } else if (mLastRequest != mRequestedTexture.size()) { mWaitTimer.start(); mLastRequest = mRequestedTexture.size(); updateTitleProgress(TEXTURE_DOWNLOAD); } else if (mWaitTimer.getElapsedTimeF32() > MAX_TEXTURE_WAIT_TIME) { mWaitTimer.start(); for (std::map<LLUUID, FSAssetResourceData>::iterator iter = mRequestedTexture.begin(); iter != mRequestedTexture.end(); ++iter) { LLUUID texture_id = iter->first; LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTexture(texture_id, FTT_DEFAULT, MIPMAP_TRUE); image->setBoostLevel(LLViewerTexture::BOOST_MAX_LEVEL); image->forceToSaveRawImage(0); image->setLoadedCallback(FSFloaterObjectExport::onImageLoaded, 0, TRUE, FALSE, this, &mCallbackTextureList); LL_DEBUGS("export") << "re-requested texture " << texture_id.asString() << LL_ENDL; } } break; default: break; } }
void LLMaterialMgr::processGetQueue() { get_queue_t::iterator loopRegionQueue = mGetQueue.begin(); while (mGetQueue.end() != loopRegionQueue) { get_queue_t::iterator itRegionQueue = loopRegionQueue++; const LLUUID& region_id = itRegionQueue->first; if (isGetAllPending(region_id)) { continue; } LLViewerRegion* regionp = LLWorld::instance().getRegionFromID(region_id); if (!regionp) { LL_WARNS("Materials") << "Unknown region with id " << region_id.asString() << LL_ENDL; mGetQueue.erase(itRegionQueue); continue; } else if (!regionp->capabilitiesReceived() || regionp->materialsCapThrottled()) { continue; } else if (mGetAllRequested.end() == mGetAllRequested.find(region_id)) { LL_DEBUGS("Materials") << "calling getAll for " << regionp->getName() << LL_ENDL; getAll(region_id); continue; } const std::string capURL = regionp->getCapability(MATERIALS_CAPABILITY_NAME); if (capURL.empty()) { LL_WARNS("Materials") << "Capability '" << MATERIALS_CAPABILITY_NAME << "' is not defined on region '" << regionp->getName() << "'" << LL_ENDL; mGetQueue.erase(itRegionQueue); continue; } LLSD materialsData = LLSD::emptyArray(); material_queue_t& materials = itRegionQueue->second; U32 max_entries = regionp->getMaxMaterialsPerTransaction(); material_queue_t::iterator loopMaterial = materials.begin(); while ( (materials.end() != loopMaterial) && (materialsData.size() < (int)max_entries) ) { material_queue_t::iterator itMaterial = loopMaterial++; materialsData.append((*itMaterial).asLLSD()); materials.erase(itMaterial); markGetPending(region_id, *itMaterial); } if (materials.empty()) { mGetQueue.erase(itRegionQueue); } std::string materialString = zip_llsd(materialsData); S32 materialSize = materialString.size(); if (materialSize <= 0) { LL_ERRS("Materials") << "cannot zip LLSD binary content" << LL_ENDL; return; } LLSD::Binary materialBinary; materialBinary.resize(materialSize); memcpy(materialBinary.data(), materialString.data(), materialSize); LLSD postData = LLSD::emptyMap(); postData[MATERIALS_CAP_ZIP_FIELD] = materialBinary; LLHTTPClient::ResponderPtr materialsResponder = new LLMaterialsResponder("POST", capURL, boost::bind(&LLMaterialMgr::onGetResponse, this, _1, _2, region_id)); LL_DEBUGS("Materials") << "POSTing to region '" << regionp->getName() << "' at '"<< capURL << " for " << materialsData.size() << " materials." << "\ndata: " << ll_pretty_print_sd(materialsData) << LL_ENDL; LLHTTPClient::post(capURL, postData, materialsResponder); regionp->resetMaterialsCapThrottle(); } }
LLSD LLModel::writeModelToStream(std::ostream& ostr, LLSD& mdl, BOOL nowrite, BOOL as_slm) { U32 bytes = 0; std::string::size_type cur_offset = 0; LLSD header; if (as_slm && mdl.has("material_list")) { //save material binding names to header header["material_list"] = mdl["material_list"]; } std::string skin; if (mdl.has("skin")) { //write out skin block skin = zip_llsd(mdl["skin"]); U32 size = skin.size(); if (size > 0) { header["skin"]["offset"] = (LLSD::Integer) cur_offset; header["skin"]["size"] = (LLSD::Integer) size; cur_offset += size; bytes += size; } } std::string decomposition; if (mdl.has("physics_convex")) { //write out convex decomposition decomposition = zip_llsd(mdl["physics_convex"]); U32 size = decomposition.size(); if (size > 0) { header["physics_convex"]["offset"] = (LLSD::Integer) cur_offset; header["physics_convex"]["size"] = (LLSD::Integer) size; cur_offset += size; bytes += size; } } if (mdl.has("submodel_id")) { //write out submodel id header["submodel_id"] = (LLSD::Integer)mdl["submodel_id"]; } std::string out[MODEL_NAMES_LENGTH]; for (S32 i = 0; i < MODEL_NAMES_LENGTH; i++) { if (mdl.has(model_names[i])) { out[i] = zip_llsd(mdl[model_names[i]]); U32 size = out[i].size(); header[model_names[i]]["offset"] = (LLSD::Integer) cur_offset; header[model_names[i]]["size"] = (LLSD::Integer) size; cur_offset += size; bytes += size; } } if (!nowrite) { LLSDSerialize::toBinary(header, ostr); if (!skin.empty()) { //write skin block ostr.write((const char*) skin.data(), header["skin"]["size"].asInteger()); } if (!decomposition.empty()) { //write decomposition block ostr.write((const char*) decomposition.data(), header["physics_convex"]["size"].asInteger()); } for (S32 i = 0; i < MODEL_NAMES_LENGTH; i++) { if (!out[i].empty()) { ostr.write((const char*) out[i].data(), header[model_names[i]]["size"].asInteger()); } } } return header; }