diff options
author | Jacek Antonelli | 2009-09-03 01:40:48 -0500 |
---|---|---|
committer | Jacek Antonelli | 2009-09-03 01:40:48 -0500 |
commit | d6a1eca66144e88fdd59ad230f1610e75f548cd7 (patch) | |
tree | da8bde4e457d47303c0c29babf2aaec4f836a1d7 /linden/indra/newview/primbackup.cpp | |
parent | Updated some python scripts to not use deprecated modules. (diff) | |
download | meta-impy-d6a1eca66144e88fdd59ad230f1610e75f548cd7.zip meta-impy-d6a1eca66144e88fdd59ad230f1610e75f548cd7.tar.gz meta-impy-d6a1eca66144e88fdd59ad230f1610e75f548cd7.tar.bz2 meta-impy-d6a1eca66144e88fdd59ad230f1610e75f548cd7.tar.xz |
Applied object import/export patch.
Diffstat (limited to 'linden/indra/newview/primbackup.cpp')
-rw-r--r-- | linden/indra/newview/primbackup.cpp | 1101 |
1 files changed, 1101 insertions, 0 deletions
diff --git a/linden/indra/newview/primbackup.cpp b/linden/indra/newview/primbackup.cpp new file mode 100644 index 0000000..cd21047 --- /dev/null +++ b/linden/indra/newview/primbackup.cpp | |||
@@ -0,0 +1,1101 @@ | |||
1 | |||
2 | #include "llviewerprecompiledheaders.h" | ||
3 | #include "llviewermenu.h" | ||
4 | |||
5 | |||
6 | // system library includes | ||
7 | #include <iostream> | ||
8 | #include <fstream> | ||
9 | #include <sstream> | ||
10 | |||
11 | // linden library includes | ||
12 | #include "llfilepicker.h" | ||
13 | #include "indra_constants.h" | ||
14 | #include "llsdserialize.h" | ||
15 | #include "llsdutil.h" | ||
16 | |||
17 | #include "llcallbacklist.h" | ||
18 | |||
19 | // newview includes | ||
20 | #include "llagent.h" | ||
21 | #include "llselectmgr.h" | ||
22 | #include "lltoolplacer.h" | ||
23 | |||
24 | #include "lltexturecache.h" | ||
25 | |||
26 | #include "llnotify.h" | ||
27 | |||
28 | #include "llapr.h" | ||
29 | #include "lldir.h" | ||
30 | #include "llimage.h" | ||
31 | #include "lllfsthread.h" | ||
32 | #include "llviewercontrol.h" | ||
33 | #include "llassetuploadresponders.h" | ||
34 | #include "lleconomy.h" | ||
35 | #include "llhttpclient.h" | ||
36 | #include "lluploaddialog.h" | ||
37 | #include "lldir.h" | ||
38 | #include "llinventorymodel.h" // gInventory | ||
39 | #include "llviewercontrol.h" // gSavedSettings | ||
40 | #include "llviewermenu.h" // gMenuHolder | ||
41 | #include "llagent.h" | ||
42 | #include "llfilepicker.h" | ||
43 | #include "llfloateranimpreview.h" | ||
44 | #include "llfloaterbuycurrency.h" | ||
45 | #include "llfloaterimagepreview.h" | ||
46 | #include "llfloaternamedesc.h" | ||
47 | #include "llfloatersnapshot.h" | ||
48 | #include "llinventorymodel.h" // gInventory | ||
49 | #include "llresourcedata.h" | ||
50 | #include "llstatusbar.h" | ||
51 | #include "llviewercontrol.h" // gSavedSettings | ||
52 | #include "llviewerimagelist.h" | ||
53 | #include "lluictrlfactory.h" | ||
54 | #include "llviewermenu.h" // gMenuHolder | ||
55 | #include "llviewerregion.h" | ||
56 | #include "llviewerstats.h" | ||
57 | #include "llviewerwindow.h" | ||
58 | #include "llappviewer.h" | ||
59 | #include "lluploaddialog.h" | ||
60 | // Included to allow LLTextureCache::purgeTextures() to pause watchdog timeout | ||
61 | #include "llappviewer.h" | ||
62 | #include "lltransactiontypes.h" | ||
63 | |||
64 | #include "primbackup.h" | ||
65 | |||
66 | #include "llviewerobjectlist.h" | ||
67 | |||
68 | primbackup* primbackup::sInstance = 0; | ||
69 | |||
70 | class importResponder: public LLNewAgentInventoryResponder | ||
71 | { | ||
72 | public: | ||
73 | |||
74 | importResponder(const LLSD& post_data, | ||
75 | const LLUUID& vfile_id, | ||
76 | LLAssetType::EType asset_type) | ||
77 | : LLNewAgentInventoryResponder(post_data, vfile_id, asset_type) | ||
78 | { | ||
79 | } | ||
80 | |||
81 | |||
82 | //virtual | ||
83 | virtual void uploadComplete(const LLSD& content) | ||
84 | { | ||
85 | lldebugs << "LLNewAgentInventoryResponder::result from capabilities" << llendl; | ||
86 | |||
87 | LLAssetType::EType asset_type = LLAssetType::lookup(mPostData["asset_type"].asString()); | ||
88 | LLInventoryType::EType inventory_type = LLInventoryType::lookup(mPostData["inventory_type"].asString()); | ||
89 | |||
90 | // Update L$ and ownership credit information | ||
91 | // since it probably changed on the server | ||
92 | if (asset_type == LLAssetType::AT_TEXTURE || | ||
93 | asset_type == LLAssetType::AT_SOUND || | ||
94 | asset_type == LLAssetType::AT_ANIMATION) | ||
95 | { | ||
96 | gMessageSystem->newMessageFast(_PREHASH_MoneyBalanceRequest); | ||
97 | gMessageSystem->nextBlockFast(_PREHASH_AgentData); | ||
98 | gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); | ||
99 | gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); | ||
100 | gMessageSystem->nextBlockFast(_PREHASH_MoneyData); | ||
101 | gMessageSystem->addUUIDFast(_PREHASH_TransactionID, LLUUID::null ); | ||
102 | gAgent.sendReliableMessage(); | ||
103 | |||
104 | // LLStringUtil::format_map_t args; | ||
105 | // args["[AMOUNT]"] = llformat("%d",LLGlobalEconomy::Singleton::getInstance()->getPriceUpload()); | ||
106 | // LLNotifyBox::showXml("UploadPayment", args); | ||
107 | } | ||
108 | |||
109 | // Actually add the upload to viewer inventory | ||
110 | llinfos << "Adding " << content["new_inventory_item"].asUUID() << " " | ||
111 | << content["new_asset"].asUUID() << " to inventory." << llendl; | ||
112 | if(mPostData["folder_id"].asUUID().notNull()) | ||
113 | { | ||
114 | LLPermissions perm; | ||
115 | U32 next_owner_perm; | ||
116 | perm.init(gAgent.getID(), gAgent.getID(), LLUUID::null, LLUUID::null); | ||
117 | if (mPostData["inventory_type"].asString() == "snapshot") | ||
118 | { | ||
119 | next_owner_perm = PERM_ALL; | ||
120 | } | ||
121 | else | ||
122 | { | ||
123 | next_owner_perm = PERM_MOVE | PERM_TRANSFER; | ||
124 | } | ||
125 | perm.initMasks(PERM_ALL, PERM_ALL, PERM_NONE, PERM_NONE, next_owner_perm); | ||
126 | S32 creation_date_now = time_corrected(); | ||
127 | LLPointer<LLViewerInventoryItem> item | ||
128 | = new LLViewerInventoryItem(content["new_inventory_item"].asUUID(), | ||
129 | mPostData["folder_id"].asUUID(), | ||
130 | perm, | ||
131 | content["new_asset"].asUUID(), | ||
132 | asset_type, | ||
133 | inventory_type, | ||
134 | mPostData["name"].asString(), | ||
135 | mPostData["description"].asString(), | ||
136 | LLSaleInfo::DEFAULT, | ||
137 | LLInventoryItem::II_FLAGS_NONE, | ||
138 | creation_date_now); | ||
139 | gInventory.updateItem(item); | ||
140 | gInventory.notifyObservers(); | ||
141 | } | ||
142 | else | ||
143 | { | ||
144 | llwarns << "Can't find a folder to put it in" << llendl; | ||
145 | } | ||
146 | |||
147 | // remove the "Uploading..." message | ||
148 | LLUploadDialog::modalUploadFinished(); | ||
149 | |||
150 | primbackup::getInstance()->update_map(content["new_asset"].asUUID()); | ||
151 | primbackup::getInstance()->upload_next_asset(); | ||
152 | |||
153 | } | ||
154 | |||
155 | }; | ||
156 | |||
157 | |||
158 | |||
159 | class CacheReadResponder : public LLTextureCache::ReadResponder | ||
160 | { | ||
161 | public: | ||
162 | CacheReadResponder(const LLUUID& id, LLImageFormatted* image) | ||
163 | : mFormattedImage(image), mID(id) | ||
164 | { | ||
165 | setImage(image); | ||
166 | } | ||
167 | void setData(U8* data, S32 datasize, S32 imagesize, S32 imageformat, BOOL imagelocal) | ||
168 | { | ||
169 | if(imageformat==IMG_CODEC_TGA && mFormattedImage->getCodec()==IMG_CODEC_J2C) | ||
170 | { | ||
171 | llwarns<<"Bleh its a tga not saving"<<llendl; | ||
172 | mFormattedImage=NULL; | ||
173 | mImageSize=0; | ||
174 | return; | ||
175 | } | ||
176 | |||
177 | if (mFormattedImage.notNull()) | ||
178 | { | ||
179 | llassert_always(mFormattedImage->getCodec() == imageformat); | ||
180 | mFormattedImage->appendData(data, datasize); | ||
181 | } | ||
182 | else | ||
183 | { | ||
184 | mFormattedImage = LLImageFormatted::createFromType(imageformat); | ||
185 | mFormattedImage->setData(data,datasize); | ||
186 | } | ||
187 | mImageSize = imagesize; | ||
188 | mImageLocal = imagelocal; | ||
189 | } | ||
190 | |||
191 | virtual void completed(bool success) | ||
192 | { | ||
193 | if(success && (mFormattedImage.notNull()) && mImageSize>0) | ||
194 | { | ||
195 | |||
196 | llinfos << "SUCCESS getting texture "<<mID<< llendl; | ||
197 | |||
198 | std::string name; | ||
199 | mID.toString(name); | ||
200 | llinfos << "Saving to "<<(primbackup::getInstance()->getfolder()+"//"+name)<<llendl; | ||
201 | if(!mFormattedImage->save(primbackup::getInstance()->getfolder()+"//"+name)) | ||
202 | { | ||
203 | llinfos << "FAIL saving texture "<<mID<< llendl; | ||
204 | } | ||
205 | |||
206 | } | ||
207 | else | ||
208 | { | ||
209 | if(!success) | ||
210 | llwarns << "FAIL NOT SUCCESSFUL getting texture "<<mID<< llendl; | ||
211 | if(mFormattedImage.isNull()) | ||
212 | llwarns << "FAIL image is NULL "<<mID<< llendl; | ||
213 | } | ||
214 | |||
215 | primbackup::getInstance()->m_nexttextureready=true; | ||
216 | //JUST SAY NO TO APR DEADLOCKING | ||
217 | //primbackup::getInstance()->export_next_texture(); | ||
218 | } | ||
219 | private: | ||
220 | LLPointer<LLImageFormatted> mFormattedImage; | ||
221 | LLUUID mID; | ||
222 | }; | ||
223 | |||
224 | |||
225 | |||
226 | primbackup::primbackup() | ||
227 | : LLFloater( std::string("Prim Import Floater") ) | ||
228 | { | ||
229 | LLUICtrlFactory::getInstance()->buildFloater( this, "floater_prim_import.xml" ); | ||
230 | |||
231 | // reposition floater from saved settings | ||
232 | LLRect rect = gSavedSettings.getRect( "FloaterPrimImport" ); | ||
233 | reshape( rect.getWidth(), rect.getHeight(), FALSE ); | ||
234 | setRect( rect ); | ||
235 | |||
236 | running=false; | ||
237 | textures.clear(); | ||
238 | assetmap.clear(); | ||
239 | current_asset=LLUUID::null; | ||
240 | m_retexture=false; | ||
241 | close(); | ||
242 | } | ||
243 | |||
244 | |||
245 | //////////////////////////////////////////////////////////////////////////////// | ||
246 | // | ||
247 | primbackup* primbackup::getInstance() | ||
248 | { | ||
249 | if ( ! sInstance ) | ||
250 | sInstance = new primbackup(); | ||
251 | |||
252 | return sInstance; | ||
253 | } | ||
254 | |||
255 | primbackup::~primbackup() | ||
256 | { | ||
257 | // save position of floater | ||
258 | gSavedSettings.setRect( "FloaterPrimImport", getRect() ); | ||
259 | sInstance = 0; | ||
260 | } | ||
261 | |||
262 | void primbackup::draw() | ||
263 | { | ||
264 | LLFloater::draw(); | ||
265 | } | ||
266 | |||
267 | void primbackup::show() | ||
268 | { | ||
269 | // set the title | ||
270 | setTitle( "stuff" ); | ||
271 | m_curobject=1; | ||
272 | m_curprim=0; | ||
273 | m_objects=0; | ||
274 | m_prims=0; | ||
275 | m_textures=0; | ||
276 | m_curtexture=0; | ||
277 | rezcount=0; | ||
278 | |||
279 | // make floater appear | ||
280 | setVisibleAndFrontmost(); | ||
281 | } | ||
282 | |||
283 | |||
284 | void primbackup::onClose( bool app_quitting ) | ||
285 | { | ||
286 | setVisible( false ); | ||
287 | // HACK for fast XML iteration replace with: | ||
288 | // destroy(); | ||
289 | } | ||
290 | |||
291 | void primbackup::updateexportnumbers() | ||
292 | { | ||
293 | |||
294 | std::stringstream sstr; | ||
295 | LLUICtrl * ctrl=this->getChild<LLUICtrl>("name_label"); | ||
296 | |||
297 | sstr<<"Export Progress \n"; | ||
298 | |||
299 | sstr << "Remaining Textures "<<textures.size()<<"\n"; | ||
300 | ctrl->setValue(LLSD("Text")=sstr.str()); | ||
301 | |||
302 | } | ||
303 | |||
304 | |||
305 | void primbackup::updateimportnumbers() | ||
306 | { | ||
307 | std::stringstream sstr; | ||
308 | LLUICtrl * ctrl=this->getChild<LLUICtrl>("name_label"); | ||
309 | |||
310 | if(m_retexture) | ||
311 | { | ||
312 | sstr << " Textures uploads remaining : "<<textures.size()<<"\n"; | ||
313 | ctrl->setValue(LLSD("Text")=sstr.str()); | ||
314 | } | ||
315 | else | ||
316 | { | ||
317 | sstr << " Textures uploads N/A \n"; | ||
318 | ctrl->setValue(LLSD("Text")=sstr.str()); | ||
319 | } | ||
320 | sstr << " Objects "<<this->m_curobject<<"/"<<this->m_objects<<"\n"; | ||
321 | ctrl->setValue(LLSD("Text")=sstr.str()); | ||
322 | |||
323 | sstr << " Rez "<<this->rezcount<<"/"<<this->m_prims; | ||
324 | ctrl->setValue(LLSD("Text")=sstr.str()); | ||
325 | |||
326 | sstr << " Build "<<this->m_curprim<<"/"<<this->m_prims; | ||
327 | ctrl->setValue(LLSD("Text")=sstr.str()); | ||
328 | |||
329 | |||
330 | } | ||
331 | |||
332 | void primbackup::pre_export_object() | ||
333 | { | ||
334 | textures.clear(); | ||
335 | llsd.clear(); | ||
336 | this_group.clear(); | ||
337 | |||
338 | // Open the file save dialog | ||
339 | LLFilePicker& file_picker = LLFilePicker::instance(); | ||
340 | if( !file_picker.getSaveFile( LLFilePicker::FFSAVE_XML ) ) | ||
341 | { | ||
342 | // User canceled save. | ||
343 | return; | ||
344 | } | ||
345 | |||
346 | file_name = file_picker.getCurFile(); | ||
347 | folder = gDirUtilp->getDirName(file_name); | ||
348 | |||
349 | export_state=EXPORT_INIT; | ||
350 | gIdleCallbacks.addFunction(exportworker, NULL); | ||
351 | } | ||
352 | |||
353 | void primbackup::exportworker(void *userdata) | ||
354 | { | ||
355 | primbackup::getInstance()->updateexportnumbers(); | ||
356 | |||
357 | switch(primbackup::getInstance()->export_state) | ||
358 | { | ||
359 | case EXPORT_INIT: | ||
360 | { | ||
361 | primbackup::getInstance()->show(); | ||
362 | LLSelectMgr::getInstance()->getSelection()->ref(); | ||
363 | |||
364 | struct ff : public LLSelectedNodeFunctor | ||
365 | { | ||
366 | virtual bool apply(LLSelectNode* node) | ||
367 | { | ||
368 | if(gAgent.getID()!=node->mPermissions->getCreator()) | ||
369 | { | ||
370 | #ifdef LL_GRID_PERMISSIONS | ||
371 | return false; | ||
372 | #else | ||
373 | return true; | ||
374 | #endif | ||
375 | } | ||
376 | return true; | ||
377 | } | ||
378 | } func; | ||
379 | |||
380 | if(LLSelectMgr::getInstance()->getSelection()->applyToNodes(&func,false)) | ||
381 | primbackup::getInstance()->export_state=EXPORT_STRUCTURE; | ||
382 | else | ||
383 | { | ||
384 | llwarns<<"Incorrect permission to export"<<llendl; | ||
385 | primbackup::getInstance()->export_state=EXPORT_DONE; | ||
386 | primbackup::getInstance()->close(); | ||
387 | gIdleCallbacks.deleteFunction(exportworker); | ||
388 | LLSelectMgr::getInstance()->getSelection()->unref(); | ||
389 | |||
390 | } | ||
391 | break; | ||
392 | } | ||
393 | |||
394 | break; | ||
395 | case EXPORT_STRUCTURE: | ||
396 | { | ||
397 | struct ff : public LLSelectedObjectFunctor | ||
398 | { | ||
399 | virtual bool apply(LLViewerObject* object) | ||
400 | { | ||
401 | object->boostTexturePriority(TRUE); | ||
402 | LLViewerObject::child_list_t children = object->getChildren(); | ||
403 | children.push_front(object); //push root onto list | ||
404 | LLSD prim_llsd=primbackup::getInstance()->prims_to_llsd(children); | ||
405 | LLSD stuff; | ||
406 | stuff["root_position"] = object->getPosition().getValue(); | ||
407 | stuff["root_rotation"] = ll_sd_from_quaternion(object->getRotation()); | ||
408 | stuff["group_body"] = prim_llsd; | ||
409 | primbackup::getInstance()->llsd["data"].append(stuff); | ||
410 | return true; | ||
411 | } | ||
412 | } func; | ||
413 | |||
414 | primbackup::getInstance()->export_state=EXPORT_LLSD; | ||
415 | LLSelectMgr::getInstance()->getSelection()->applyToRootObjects(&func,false); | ||
416 | LLSelectMgr::getInstance()->getSelection()->unref(); | ||
417 | |||
418 | break; | ||
419 | } | ||
420 | case EXPORT_TEXTURES: | ||
421 | if(primbackup::getInstance()->m_nexttextureready==false) | ||
422 | return; | ||
423 | |||
424 | //Ok we got work to do | ||
425 | primbackup::getInstance()->m_nexttextureready=false; | ||
426 | |||
427 | if(primbackup::getInstance()->textures.empty()) | ||
428 | { | ||
429 | primbackup::getInstance()->export_state=EXPORT_DONE; | ||
430 | return; | ||
431 | } | ||
432 | |||
433 | primbackup::getInstance()->export_next_texture(); | ||
434 | break; | ||
435 | |||
436 | case EXPORT_LLSD: | ||
437 | { | ||
438 | // Create a file stream and write to it | ||
439 | llofstream export_file(primbackup::getInstance()->file_name); | ||
440 | LLSDSerialize::toPrettyXML(primbackup::getInstance()->llsd, export_file); | ||
441 | export_file.close(); | ||
442 | primbackup::getInstance()->m_nexttextureready=true; | ||
443 | primbackup::getInstance()->export_state=EXPORT_TEXTURES; | ||
444 | } | ||
445 | break; | ||
446 | case EXPORT_DONE: | ||
447 | llinfos<<"Backup complete"<<llendl | ||
448 | gIdleCallbacks.deleteFunction(exportworker); | ||
449 | primbackup::getInstance()->close(); | ||
450 | break; | ||
451 | } | ||
452 | } | ||
453 | |||
454 | LLSD primbackup::prims_to_llsd(LLViewerObject::child_list_t child_list) | ||
455 | { | ||
456 | |||
457 | LLViewerObject* object; | ||
458 | LLSD llsd; | ||
459 | |||
460 | char localid[16]; | ||
461 | |||
462 | for (LLViewerObject::child_list_t::iterator i = child_list.begin(); i != child_list.end(); ++i) | ||
463 | { | ||
464 | object=(*i); | ||
465 | LLUUID id = object->getID(); | ||
466 | |||
467 | llinfos << "Exporting prim " << object->getID().asString() << llendl; | ||
468 | |||
469 | // Create an LLSD object that represents this prim. It will be injected in to the overall LLSD | ||
470 | // tree structure | ||
471 | LLSD prim_llsd; | ||
472 | |||
473 | if (!object->isRoot()) | ||
474 | { | ||
475 | |||
476 | // Parent id | ||
477 | snprintf(localid, sizeof(localid), "%u", object->getSubParent()->getLocalID()); | ||
478 | prim_llsd["parent"] = localid; | ||
479 | } | ||
480 | |||
481 | // Transforms | ||
482 | prim_llsd["position"] = object->getPosition().getValue(); | ||
483 | prim_llsd["scale"] = object->getScale().getValue(); | ||
484 | prim_llsd["rotation"] = ll_sd_from_quaternion(object->getRotation()); | ||
485 | |||
486 | // Flags | ||
487 | prim_llsd["shadows"] = object->flagCastShadows(); | ||
488 | prim_llsd["phantom"] = object->flagPhantom(); | ||
489 | prim_llsd["physical"] = (BOOL)(object->mFlags & FLAGS_USE_PHYSICS); | ||
490 | |||
491 | // Volume params | ||
492 | LLVolumeParams params = object->getVolume()->getParams(); | ||
493 | prim_llsd["volume"] = params.asLLSD(); | ||
494 | |||
495 | // Extra paramsb6fab961-af18-77f8-cf08-f021377a7244 | ||
496 | if (object->isFlexible()) | ||
497 | { | ||
498 | // Flexible | ||
499 | LLFlexibleObjectData* flex = (LLFlexibleObjectData*)object->getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE); | ||
500 | prim_llsd["flexible"] = flex->asLLSD(); | ||
501 | } | ||
502 | if (object->getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT)) | ||
503 | { | ||
504 | // Light | ||
505 | LLLightParams* light = (LLLightParams*)object->getParameterEntry(LLNetworkData::PARAMS_LIGHT); | ||
506 | prim_llsd["light"] = light->asLLSD(); | ||
507 | } | ||
508 | if (object->getParameterEntryInUse(LLNetworkData::PARAMS_SCULPT)) | ||
509 | { | ||
510 | // Sculpt | ||
511 | LLSculptParams* sculpt = (LLSculptParams*)object->getParameterEntry(LLNetworkData::PARAMS_SCULPT); | ||
512 | prim_llsd["sculpt"] = sculpt->asLLSD(); | ||
513 | |||
514 | LLUUID sculpt_texture=sculpt->getSculptTexture(); | ||
515 | bool alreadyseen=false; | ||
516 | std::list<LLUUID>::iterator iter; | ||
517 | for(iter = textures.begin(); iter != textures.end() ; iter++) | ||
518 | { | ||
519 | if( (*iter)==sculpt_texture) | ||
520 | alreadyseen=true; | ||
521 | } | ||
522 | if(alreadyseen==false) | ||
523 | { | ||
524 | llinfos << "Found a sculpt texture, adding to list "<<sculpt_texture<<llendl; | ||
525 | textures.push_back(sculpt_texture); | ||
526 | } | ||
527 | } | ||
528 | |||
529 | // Textures | ||
530 | LLSD te_llsd; | ||
531 | U8 te_count = object->getNumTEs(); | ||
532 | for (U8 i = 0; i < te_count; i++) | ||
533 | { | ||
534 | bool alreadyseen=false; | ||
535 | te_llsd.append(object->getTE(i)->asLLSD()); | ||
536 | std::list<LLUUID>::iterator iter; | ||
537 | for(iter = textures.begin(); iter != textures.end() ; iter++) | ||
538 | { | ||
539 | if( (*iter)==object->getTE(i)->getID()) | ||
540 | alreadyseen=true; | ||
541 | } | ||
542 | if(alreadyseen==false) | ||
543 | textures.push_back(object->getTE(i)->getID()); | ||
544 | } | ||
545 | prim_llsd["textures"] = te_llsd; | ||
546 | |||
547 | // The keys in the primitive maps do not have to be localids, they can be any | ||
548 | // string. We simply use localids because they are a unique identifier | ||
549 | snprintf(localid, sizeof(localid), "%u", object->getLocalID()); | ||
550 | llsd[(const char*)localid] = prim_llsd; | ||
551 | } | ||
552 | |||
553 | updateexportnumbers(); | ||
554 | |||
555 | return llsd; | ||
556 | } | ||
557 | |||
558 | |||
559 | void primbackup::export_next_texture() | ||
560 | { | ||
561 | if(textures.empty()) | ||
562 | { | ||
563 | llinfos << "Finished exporting textures "<<llendl; | ||
564 | return; | ||
565 | } | ||
566 | |||
567 | std::list<LLUUID>::iterator iter; | ||
568 | iter = textures.begin(); | ||
569 | |||
570 | LLUUID id; | ||
571 | |||
572 | while(1) | ||
573 | { | ||
574 | if(iter==textures.end()) | ||
575 | { | ||
576 | m_nexttextureready=true; | ||
577 | return; | ||
578 | } | ||
579 | |||
580 | id=(*iter); | ||
581 | |||
582 | LLViewerImage * imagep = gImageList.hasImage(id); | ||
583 | if(imagep!=NULL) | ||
584 | { | ||
585 | S32 cur_discard = imagep->getDiscardLevel(); | ||
586 | if(cur_discard>0) | ||
587 | { | ||
588 | if(imagep->getBoostLevel()!=LLViewerImage::BOOST_PREVIEW) | ||
589 | imagep->setBoostLevel(LLViewerImage::BOOST_PREVIEW); //we want to force discard 0 this one does this. | ||
590 | } | ||
591 | else | ||
592 | { | ||
593 | break; | ||
594 | } | ||
595 | } | ||
596 | else | ||
597 | { | ||
598 | llwarns<<" We *DONT* have the texture "<<llendl; | ||
599 | } | ||
600 | iter++; | ||
601 | } | ||
602 | |||
603 | textures.remove(id); | ||
604 | |||
605 | llinfos<<"Requesting texture "<<id<<llendl; | ||
606 | LLImageJ2C * mFormattedImage = new LLImageJ2C; | ||
607 | CacheReadResponder* responder = new CacheReadResponder(id, mFormattedImage); | ||
608 | LLAppViewer::getTextureCache()->readFromCache(id,LLWorkerThread::PRIORITY_HIGH,0,999999,responder); | ||
609 | } | ||
610 | |||
611 | |||
612 | |||
613 | void primbackup::import_object(bool upload) | ||
614 | { | ||
615 | textures.clear(); | ||
616 | assetmap.clear(); | ||
617 | current_asset=LLUUID::null; | ||
618 | |||
619 | this->m_retexture=upload; | ||
620 | |||
621 | // Open the file open dialog | ||
622 | LLFilePicker& file_picker = LLFilePicker::instance(); | ||
623 | if( !file_picker.getOpenFile( LLFilePicker::FFLOAD_XML ) ) | ||
624 | { | ||
625 | // User canceled save. | ||
626 | return; | ||
627 | } | ||
628 | std::string file_name = file_picker.getFirstFile().c_str(); | ||
629 | folder = gDirUtilp->getDirName(file_name); | ||
630 | |||
631 | llifstream import_file(file_name); | ||
632 | LLSDSerialize::fromXML(llsd, import_file); | ||
633 | import_file.close(); | ||
634 | |||
635 | show(); | ||
636 | |||
637 | //Get the texture map | ||
638 | |||
639 | LLSD::map_const_iterator prim_it; | ||
640 | LLSD::array_const_iterator prim_arr_it; | ||
641 | |||
642 | this->m_curobject=1; | ||
643 | this->m_curprim=1; | ||
644 | this->m_objects=llsd["data"].size(); | ||
645 | this->m_prims=0; | ||
646 | rezcount=0; | ||
647 | |||
648 | updateimportnumbers(); | ||
649 | |||
650 | for( prim_arr_it = llsd["data"].beginArray(); prim_arr_it != llsd["data"].endArray(); prim_arr_it++) | ||
651 | { | ||
652 | |||
653 | LLSD llsd2; | ||
654 | llsd2=(*prim_arr_it)["group_body"]; | ||
655 | |||
656 | for( prim_it = llsd2.beginMap(); prim_it != llsd2.endMap(); prim_it++) | ||
657 | { | ||
658 | LLSD prim_llsd; | ||
659 | prim_llsd=llsd2[prim_it->first]; | ||
660 | LLSD::array_iterator text_it; | ||
661 | std::list<LLUUID>::iterator iter; | ||
662 | |||
663 | if(prim_llsd.has("sculpt")) | ||
664 | { | ||
665 | LLSculptParams* sculpt=new LLSculptParams(); | ||
666 | sculpt->fromLLSD(prim_llsd["sculpt"]); | ||
667 | LLUUID orig=sculpt->getSculptTexture(); | ||
668 | bool alreadyseen=false; | ||
669 | for(iter = textures.begin(); iter != textures.end() ; iter++) | ||
670 | { | ||
671 | if( (*iter)==orig) | ||
672 | alreadyseen=true; | ||
673 | } | ||
674 | if(alreadyseen==false) | ||
675 | { | ||
676 | llinfos << "Found a new SCULPT texture to upload "<<orig<<llendl; | ||
677 | textures.push_back(orig); | ||
678 | } | ||
679 | } | ||
680 | |||
681 | |||
682 | LLSD te_llsd; | ||
683 | te_llsd=prim_llsd["textures"]; | ||
684 | |||
685 | |||
686 | for(text_it=te_llsd.beginArray(); text_it !=te_llsd.endArray(); text_it++) | ||
687 | { | ||
688 | LLSD the_te; | ||
689 | the_te=(*text_it); | ||
690 | LLTextureEntry te; | ||
691 | te.fromLLSD(the_te); | ||
692 | |||
693 | te.getID(); | ||
694 | bool alreadyseen=false; | ||
695 | |||
696 | for(iter = textures.begin(); iter != textures.end() ; iter++) | ||
697 | { | ||
698 | if( (*iter)==te.getID()) | ||
699 | alreadyseen=true; | ||
700 | } | ||
701 | if(alreadyseen==false) | ||
702 | { | ||
703 | llinfos << "Found a new texture to upload "<<te.getID()<<llendl; | ||
704 | textures.push_back(te.getID()); | ||
705 | } | ||
706 | } | ||
707 | |||
708 | } | ||
709 | } | ||
710 | |||
711 | if(m_retexture==TRUE) | ||
712 | upload_next_asset(); | ||
713 | else | ||
714 | import_object1a(); | ||
715 | } | ||
716 | |||
717 | LLVector3 primbackup::offset_agent(LLVector3 offset) | ||
718 | { | ||
719 | LLVector3 pos= gAgent.getPositionAgent(); | ||
720 | LLQuaternion agent_rot=LLQuaternion(gAgent.getAtAxis(),gAgent.getLeftAxis(),gAgent.getUpAxis()); | ||
721 | pos=(offset*agent_rot+pos); | ||
722 | return pos; | ||
723 | } | ||
724 | |||
725 | void primbackup::rez_agent_offset(LLVector3 offset) | ||
726 | { | ||
727 | // This will break for a sitting agent | ||
728 | LLToolPlacer* mPlacer = new LLToolPlacer(); | ||
729 | mPlacer->setObjectType(LL_PCODE_CUBE); | ||
730 | //LLVector3 pos=offset_agent(offset); | ||
731 | mPlacer->placeObject(offset.mV[0], offset.mV[1],offset.mV[2]); | ||
732 | } | ||
733 | |||
734 | void primbackup::import_object1a() | ||
735 | { | ||
736 | running=true; | ||
737 | |||
738 | show(); | ||
739 | |||
740 | group_prim_import_iter=llsd["data"].beginArray(); | ||
741 | root_root_pos=(*group_prim_import_iter)["root_position"]; | ||
742 | |||
743 | this->m_objects=llsd["data"].size(); | ||
744 | this->m_curobject=1; | ||
745 | import_next_object(); | ||
746 | } | ||
747 | |||
748 | void primbackup::import_next_object() | ||
749 | { | ||
750 | toselect.clear(); | ||
751 | rezcount=0; | ||
752 | |||
753 | this_group=(*group_prim_import_iter)["group_body"]; | ||
754 | prim_import_iter=this_group.beginMap(); | ||
755 | |||
756 | m_curprim=0; | ||
757 | m_prims=this_group.size(); | ||
758 | updateimportnumbers(); | ||
759 | LLVector3 lgpos=(*group_prim_import_iter)["root_position"]; | ||
760 | |||
761 | group_offset=lgpos-root_root_pos; | ||
762 | root_pos=offset_agent(LLVector3(2.0,0,0)); | ||
763 | root_rot=ll_quaternion_from_sd((*group_prim_import_iter)["root_rotation"]); | ||
764 | |||
765 | rez_agent_offset(LLVector3(0.0,2.0,0.0)); | ||
766 | // Now we must wait for the callback when ViewerObjectList gets the new objects and we have the correct number selected | ||
767 | } | ||
768 | |||
769 | // This function takes a pointer to a viewerobject and applys the prim definition that prim_llsd has | ||
770 | void primbackup::xmltoprim(LLSD prim_llsd,LLViewerObject * object) | ||
771 | { | ||
772 | LLUUID id = object->getID(); | ||
773 | expecting_update = object->getID(); | ||
774 | LLSelectMgr::getInstance()->selectObjectAndFamily(object); | ||
775 | |||
776 | if(prim_llsd.has("parent")) | ||
777 | { | ||
778 | //we are not the root node. | ||
779 | LLVector3 pos=prim_llsd["position"]; | ||
780 | LLQuaternion rot=ll_quaternion_from_sd(prim_llsd["rotation"]); | ||
781 | object->setPositionRegion((pos*root_rot)+(root_pos+group_offset)); | ||
782 | object->setRotation(rot*root_rot); | ||
783 | } | ||
784 | else | ||
785 | { | ||
786 | object->setPositionRegion(root_pos+group_offset); | ||
787 | LLQuaternion rot=ll_quaternion_from_sd(prim_llsd["rotation"]); | ||
788 | object->setRotation(rot); | ||
789 | } | ||
790 | |||
791 | object->setScale(prim_llsd["scale"]); | ||
792 | |||
793 | if(prim_llsd.has("shadows")) | ||
794 | if(prim_llsd["shadows"].asInteger()==1) | ||
795 | object->setFlags(FLAGS_CAST_SHADOWS,true); | ||
796 | |||
797 | if(prim_llsd.has("phantom")) | ||
798 | if(prim_llsd["phantom"].asInteger()==1) | ||
799 | object->setFlags(FLAGS_PHANTOM,true); | ||
800 | |||
801 | if(prim_llsd.has("physical")) | ||
802 | if(prim_llsd["physical"].asInteger()==1) | ||
803 | object->setFlags(FLAGS_USE_PHYSICS,true); | ||
804 | |||
805 | // Volume params | ||
806 | LLVolumeParams volume_params = object->getVolume()->getParams(); | ||
807 | volume_params.fromLLSD(prim_llsd["volume"]) ; | ||
808 | object->updateVolume(volume_params); | ||
809 | |||
810 | if(prim_llsd.has("sculpt")) | ||
811 | { | ||
812 | LLSculptParams* sculpt=new LLSculptParams(); | ||
813 | sculpt->fromLLSD(prim_llsd["sculpt"]); | ||
814 | |||
815 | //TODO check if map is valid and only set texture is map is valid and changes | ||
816 | |||
817 | if(assetmap[sculpt->getSculptTexture()].notNull()) | ||
818 | { | ||
819 | LLUUID replacment=assetmap[sculpt->getSculptTexture()]; | ||
820 | sculpt->setSculptTexture(replacment); | ||
821 | } | ||
822 | |||
823 | object->setParameterEntry(LLNetworkData::PARAMS_SCULPT,(LLNetworkData&)(*sculpt),true); | ||
824 | } | ||
825 | |||
826 | if(prim_llsd.has("light")) | ||
827 | { | ||
828 | LLLightParams * light=new LLLightParams(); | ||
829 | light->fromLLSD(prim_llsd["light"]); | ||
830 | object->setParameterEntry(LLNetworkData::PARAMS_LIGHT,(LLNetworkData&)(*light),true); | ||
831 | } | ||
832 | |||
833 | if(prim_llsd.has("flexible")) | ||
834 | { | ||
835 | LLFlexibleObjectData* flex=new LLFlexibleObjectData(); | ||
836 | flex->fromLLSD(prim_llsd["flexible"]); | ||
837 | object->setParameterEntry(LLNetworkData::PARAMS_FLEXIBLE,(LLNetworkData&)(*flex),true); | ||
838 | } | ||
839 | |||
840 | |||
841 | // Textures | ||
842 | LLSD te_llsd; | ||
843 | llinfos << "Processing textures for prim" << llendl; | ||
844 | |||
845 | te_llsd=prim_llsd["textures"]; | ||
846 | |||
847 | LLSD::array_iterator text_it; | ||
848 | U8 i=0; | ||
849 | i=0; | ||
850 | |||
851 | for(text_it=te_llsd.beginArray(); text_it !=te_llsd.endArray(); text_it++) | ||
852 | { | ||
853 | LLSD the_te; | ||
854 | the_te=(*text_it); | ||
855 | LLTextureEntry te; | ||
856 | te.fromLLSD(the_te); | ||
857 | |||
858 | if(assetmap[te.getID()].notNull()) | ||
859 | { | ||
860 | LLUUID replacment=assetmap[te.getID()]; | ||
861 | te.setID(replacment); | ||
862 | } | ||
863 | |||
864 | object->setTE(i,te); // | ||
865 | i++; | ||
866 | } | ||
867 | |||
868 | llinfos << "Textures done!" << llendl; | ||
869 | |||
870 | //bump the iterator now so the callbacks hook together nicely | ||
871 | //if(prim_import_iter!=this_group.endMap()) | ||
872 | // prim_import_iter++; | ||
873 | |||
874 | object->sendRotationUpdate(); | ||
875 | object->sendTEUpdate(); | ||
876 | object->sendShapeUpdate(); | ||
877 | LLSelectMgr::getInstance()->sendMultipleUpdate(UPD_SCALE |UPD_POSITION); | ||
878 | |||
879 | LLSelectMgr::getInstance()->deselectAll(); | ||
880 | } | ||
881 | |||
882 | //This is fired when the update packet is processed so we know the prim settings have stuck | ||
883 | void primbackup::prim_update(LLViewerObject* object) | ||
884 | { | ||
885 | if(!running) | ||
886 | return; | ||
887 | |||
888 | if(object!=NULL) | ||
889 | if(object->mID!=expecting_update) | ||
890 | return; | ||
891 | |||
892 | m_curprim++; | ||
893 | updateimportnumbers(); | ||
894 | |||
895 | prim_import_iter++; | ||
896 | |||
897 | LLUUID x; | ||
898 | expecting_update=x.null; | ||
899 | |||
900 | if(prim_import_iter==this_group.endMap()) | ||
901 | { | ||
902 | llinfos<<"Trying to link"<<llendl; | ||
903 | |||
904 | if(toselect.size()>1) | ||
905 | { | ||
906 | std::reverse(toselect.begin(),toselect.end()); | ||
907 | //Now link | ||
908 | LLSelectMgr::getInstance()->deselectAll(); | ||
909 | LLSelectMgr::getInstance()->selectObjectAndFamily(toselect,true); | ||
910 | LLSelectMgr::getInstance()->sendLink(); | ||
911 | LLViewerObject * root=toselect.back(); | ||
912 | root->setRotation(root_rot); | ||
913 | } | ||
914 | |||
915 | this->m_curobject++; | ||
916 | group_prim_import_iter++; | ||
917 | if(group_prim_import_iter!=llsd["data"].endArray()) | ||
918 | { | ||
919 | import_next_object(); | ||
920 | return; | ||
921 | } | ||
922 | |||
923 | running=false; | ||
924 | this->close(); | ||
925 | return; | ||
926 | } | ||
927 | |||
928 | LLSD prim_llsd; | ||
929 | prim_llsd=this_group[prim_import_iter->first]; | ||
930 | |||
931 | if(toselect.empty()) | ||
932 | { | ||
933 | llwarns << "error: ran out of objects to mod" << llendl; | ||
934 | return; | ||
935 | } | ||
936 | |||
937 | if(prim_import_iter!=this_group.endMap()) | ||
938 | { | ||
939 | //rez_agent_offset(LLVector3(1.0,0,0)); | ||
940 | LLSD prim_llsd=this_group[prim_import_iter->first]; | ||
941 | process_iter++; | ||
942 | xmltoprim(prim_llsd,(*process_iter)); | ||
943 | } | ||
944 | } | ||
945 | |||
946 | // Callback when we rez a new object when the importer is running. | ||
947 | bool primbackup::newprim(LLViewerObject * pobject) | ||
948 | { | ||
949 | if(running) | ||
950 | { | ||
951 | rezcount++; | ||
952 | toselect.push_back(pobject); | ||
953 | updateimportnumbers(); | ||
954 | prim_import_iter++; | ||
955 | |||
956 | if(prim_import_iter!=this_group.endMap()) | ||
957 | { | ||
958 | |||
959 | pobject->setPosition(this->offset_agent(LLVector3(0,1.0,0))); | ||
960 | LLSelectMgr::getInstance()->sendMultipleUpdate(UPD_POSITION); | ||
961 | |||
962 | rez_agent_offset(LLVector3(1.0,0,0)); | ||
963 | } | ||
964 | else | ||
965 | { | ||
966 | llinfos << "All prims rezed, moving to build stage" <<llendl; | ||
967 | prim_import_iter=this_group.beginMap(); | ||
968 | LLSD prim_llsd=this_group[prim_import_iter->first]; | ||
969 | process_iter=toselect.begin(); | ||
970 | xmltoprim(prim_llsd,(*process_iter)); | ||
971 | } | ||
972 | } | ||
973 | |||
974 | return true; | ||
975 | } | ||
976 | |||
977 | void primbackup::update_map(LLUUID uploaded_asset) | ||
978 | { | ||
979 | if(current_asset.isNull()) | ||
980 | return; | ||
981 | |||
982 | assetmap.insert(std::pair<LLUUID,LLUUID>(current_asset,uploaded_asset)); | ||
983 | llinfos << "Mapping "<<current_asset<<" to "<<uploaded_asset<<llendl; | ||
984 | |||
985 | } | ||
986 | |||
987 | |||
988 | void myupload_new_resource(const LLTransactionID &tid, LLAssetType::EType asset_type, | ||
989 | std::string name, | ||
990 | std::string desc, S32 compression_info, | ||
991 | LLAssetType::EType destination_folder_type, | ||
992 | LLInventoryType::EType inv_type, | ||
993 | U32 next_owner_perm, | ||
994 | const std::string& display_name, | ||
995 | LLAssetStorage::LLStoreAssetCallback callback, | ||
996 | void *userdata) | ||
997 | { | ||
998 | if(gDisconnected) | ||
999 | { | ||
1000 | return ; | ||
1001 | } | ||
1002 | |||
1003 | LLAssetID uuid = tid.makeAssetID(gAgent.getSecureSessionID()); | ||
1004 | |||
1005 | // At this point, we're ready for the upload. | ||
1006 | std::string upload_message = "Uploading...\n\n"; | ||
1007 | upload_message.append(display_name); | ||
1008 | LLUploadDialog::modalUploadDialog(upload_message); | ||
1009 | |||
1010 | std::string url = gAgent.getRegion()->getCapability("NewFileAgentInventory"); | ||
1011 | if (!url.empty()) | ||
1012 | { | ||
1013 | LLSD body; | ||
1014 | body["folder_id"] = gInventory.findCategoryUUIDForType((destination_folder_type == LLAssetType::AT_NONE) ? asset_type : destination_folder_type); | ||
1015 | body["asset_type"] = LLAssetType::lookup(asset_type); | ||
1016 | body["inventory_type"] = LLInventoryType::lookup(inv_type); | ||
1017 | body["name"] = name; | ||
1018 | body["description"] = desc; | ||
1019 | |||
1020 | std::ostringstream llsdxml; | ||
1021 | LLSDSerialize::toXML(body, llsdxml); | ||
1022 | lldebugs << "posting body to capability: " << llsdxml.str() << llendl; | ||
1023 | //LLHTTPClient::post(url, body, new LLNewAgentInventoryResponder(body, uuid, asset_type)); | ||
1024 | LLHTTPClient::post(url, body, new importResponder(body, uuid, asset_type)); | ||
1025 | |||
1026 | } | ||
1027 | else | ||
1028 | { | ||
1029 | llinfos << "NewAgentInventory capability not found, FUCK!" << llendl; | ||
1030 | } | ||
1031 | } | ||
1032 | |||
1033 | |||
1034 | |||
1035 | void primbackup::upload_next_asset() | ||
1036 | { | ||
1037 | if(textures.empty()) | ||
1038 | { | ||
1039 | llinfos<<" Texture list is empty, moving to rez statge"<< llendl; | ||
1040 | current_asset=LLUUID::null; | ||
1041 | import_object1a(); | ||
1042 | return; | ||
1043 | } | ||
1044 | |||
1045 | this->updateimportnumbers(); | ||
1046 | |||
1047 | std::list<LLUUID>::iterator iter; | ||
1048 | iter=textures.begin(); | ||
1049 | LLUUID id=(*iter); | ||
1050 | textures.pop_front(); | ||
1051 | |||
1052 | llinfos<<"Got texture ID "<<id<< "trying to upload"<<llendl; | ||
1053 | |||
1054 | current_asset=id; | ||
1055 | std::string struid; | ||
1056 | id.toString(struid); | ||
1057 | std::string filename=folder+"//"+struid; | ||
1058 | |||
1059 | |||
1060 | LLAssetID uuid; | ||
1061 | LLTransactionID tid; | ||
1062 | |||
1063 | // gen a new transaction ID for this asset | ||
1064 | tid.generate(); | ||
1065 | uuid = tid.makeAssetID(gAgent.getSecureSessionID()); | ||
1066 | |||
1067 | S32 file_size; | ||
1068 | apr_file_t* fp = ll_apr_file_open(filename, LL_APR_RB, &file_size); | ||
1069 | if (fp) | ||
1070 | { | ||
1071 | const S32 buf_size = 65536; | ||
1072 | U8 copy_buf[buf_size]; | ||
1073 | LLVFile file(gVFS, uuid, LLAssetType::AT_TEXTURE, LLVFile::WRITE); | ||
1074 | file.setMaxSize(file_size); | ||
1075 | |||
1076 | while ((file_size = ll_apr_file_read(fp, copy_buf, buf_size))) | ||
1077 | { | ||
1078 | file.write(copy_buf, file_size); | ||
1079 | } | ||
1080 | apr_file_close(fp); | ||
1081 | } | ||
1082 | else | ||
1083 | { | ||
1084 | llwarns<<"Unable to access output file "<<filename<<llendl; | ||
1085 | upload_next_asset(); | ||
1086 | return; | ||
1087 | } | ||
1088 | |||
1089 | myupload_new_resource( | ||
1090 | tid, LLAssetType::AT_TEXTURE, struid, | ||
1091 | struid, 0, | ||
1092 | LLAssetType::AT_TEXTURE, | ||
1093 | LLInventoryType::defaultForAssetType(LLAssetType::AT_TEXTURE), | ||
1094 | 0x0, | ||
1095 | "Uploaded texture", | ||
1096 | NULL, | ||
1097 | NULL); | ||
1098 | |||
1099 | |||
1100 | } | ||
1101 | |||