void llsdutil_object::test<7>()
	{
		LLSD sd;
		LLQuaternion quat((F32) 1., (F32) -0.98, (F32) 2.3, (F32) 0xffff);
		sd = ll_sd_from_quaternion(quat); 
		LLQuaternion quat1 = ll_quaternion_from_sd(sd);
		ensure_equals("LLQuaternion -> sd -> LLQuaternion", quat, quat1);
		
		LLSD sd2 = ll_sd_from_quaternion(quat1); 
		ensure_equals("sd -> LLQuaternion -> sd ", sd, sd2);
	}
	void LLSDMessageReaderTestObject::test<17>()
		// Quaternion
	{
		 LLQuaternion outValue, inValue = LLQuaternion(1,2,3,4);
		LLSD sdValue = ll_sd_from_quaternion(inValue);
		LLSDMessageReader msg = testType(sdValue);
		msg.getQuat("block", "var", outValue);
		ensure_equals("Ensure Quaternion", outValue, inValue);
	}
					virtual bool apply(LLViewerObject* object)
					{
						bool is_attachment = object->isAttachment();
						object->boostTexturePriority(TRUE);
						LLViewerObject::child_list_t children = object->getChildren();
						children.push_front(object); //push root onto list
						LLSD prim_llsd = LLObjectBackup::getInstance()->primsToLLSD(children, is_attachment);				
						LLSD stuff;
						if (is_attachment)
						{
							stuff["root_position"] = object->getPositionEdit().getValue();
							stuff["root_rotation"] = ll_sd_from_quaternion(object->getRotationEdit());
						}
						else
						{
							stuff["root_position"] = object->getPosition().getValue();
							stuff["root_rotation"] = ll_sd_from_quaternion(object->getRotation());
						}
						stuff["group_body"] = prim_llsd;
						LLObjectBackup::getInstance()->mLLSD["data"].append(stuff);
						return true;
					}
				virtual bool apply(LLViewerObject* object)
				{
					object->boostTexturePriority(TRUE);
					LLViewerObject::child_list_t children = object->getChildren();
					children.push_front(object); //push root onto list
					LLSD prim_llsd=primbackup::getInstance()->prims_to_llsd(children);
					LLSD stuff;
					stuff["root_position"] = object->getPosition().getValue();
					stuff["root_rotation"] = ll_sd_from_quaternion(object->getRotation());
					stuff["group_body"] = prim_llsd;
					primbackup::getInstance()->llsd["data"].append(stuff);
					return true;
				}
void LLSDMessageBuilder::addQuat(const char* varname, const LLQuaternion& v)
{
	(*mCurrentBlock)[varname] = ll_sd_from_quaternion(v);
}
Exemple #6
0
LLSD JCExportTracker::subserialize(LLViewerObject* linkset)
{
	//Chalice - Changed to support exporting linkset groups.
	LLViewerObject* object = linkset;
	//if(!linkset)return LLSD();
	
	// Create an LLSD object that will hold the entire tree structure that can be serialized to a file
	LLSD llsd;

	//if (!node)
	//	return llsd;

	//object = root_object = node->getObject();
	
	if (!object)
		return llsd;
	if(!(!object->isAvatar() && object->permYouOwner() && object->permModify() && object->permCopy() && object->permTransfer() && !gAgent.getGodLevel()))
		return llsd;
	// Build a list of everything that we'll actually be exporting
	LLDynamicArray<LLViewerObject*> export_objects;
	
	// Add the root object to the export list
	export_objects.put(object);
	
	// Iterate over all of this objects children
	LLViewerObject::child_list_t child_list = object->getChildren();
	
	for (LLViewerObject::child_list_t::iterator i = child_list.begin(); i != child_list.end(); ++i)
	{
		LLViewerObject* child = *i;
		if(!child->isAvatar())
		{
			// Put the child objects on the export list
			export_objects.put(child);
		}
	}
		
	S32 object_index = 0;
	
	while ((object_index < export_objects.count()))
	{
		object = export_objects.get(object_index++);
		LLUUID id = object->getID();
	
		llinfos << "Exporting prim " << object->getID().asString() << llendl;
	
		// Create an LLSD object that represents this prim. It will be injected in to the overall LLSD
		// tree structure
		LLSD prim_llsd;
	
		if (object_index == 1)
		{
			LLVOAvatar* avatar = find_avatar_from_object(object);
			if (avatar)
			{
				LLViewerJointAttachment* attachment = avatar->getTargetAttachmentPoint(object);
				U8 attachment_id = 0;
				
				if (attachment)
				{
					for (LLVOAvatar::attachment_map_t::iterator iter = avatar->mAttachmentPoints.begin();
										iter != avatar->mAttachmentPoints.end(); ++iter)
					{
						if (iter->second == attachment)
						{
							attachment_id = iter->first;
							break;
						}
					}
				}
				else
				{
					// interpret 0 as "default location"
					attachment_id = 0;
				}
				
				prim_llsd["Attachment"] = attachment_id;
				prim_llsd["attachpos"] = object->getPosition().getValue();
				prim_llsd["attachrot"] = ll_sd_from_quaternion(object->getRotation());
			}
			
			prim_llsd["position"] = LLVector3(0, 0, 0).getValue();
			prim_llsd["rotation"] = ll_sd_from_quaternion(object->getRotation());
		}
		else
		{
			prim_llsd["position"] = object->getPosition().getValue();
			prim_llsd["rotation"] = ll_sd_from_quaternion(object->getRotation());
		}
		//prim_llsd["name"] = "";//node->mName;
		//prim_llsd["description"] = "";//node->mDescription;
		// Transforms
		prim_llsd["scale"] = object->getScale().getValue();
		// Flags
		prim_llsd["shadows"] = object->flagCastShadows();
		prim_llsd["phantom"] = object->flagPhantom();
		prim_llsd["physical"] = (BOOL)(object->mFlags & FLAGS_USE_PHYSICS);
		LLVolumeParams params = object->getVolume()->getParams();
		prim_llsd["volume"] = params.asLLSD();
		if (object->isFlexible())
		{
			LLFlexibleObjectData* flex = (LLFlexibleObjectData*)object->getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE);
			prim_llsd["flexible"] = flex->asLLSD();
		}
		if (object->getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT))
		{
			LLLightParams* light = (LLLightParams*)object->getParameterEntry(LLNetworkData::PARAMS_LIGHT);
			prim_llsd["light"] = light->asLLSD();
		}
		if (object->getParameterEntryInUse(LLNetworkData::PARAMS_SCULPT))
		{
			LLSculptParams* sculpt = (LLSculptParams*)object->getParameterEntry(LLNetworkData::PARAMS_SCULPT);
			prim_llsd["sculpt"] = sculpt->asLLSD();
		}

		// Textures
		LLSD te_llsd;
		U8 te_count = object->getNumTEs();
		
		for (U8 i = 0; i < te_count; i++)
		{
			te_llsd.append(object->getTE(i)->asLLSD());
		}

		if(export_textures)
		{
			std::string path = asset_dir + gDirUtilp->getDirDelimiter();
			for (U8 i = 0; i < te_count; i++)
			{
				LLUUID asset_id = object->getTE(i)->getID();
				JCAssetInfo* info = new JCAssetInfo;
				info->path = path + asset_id.asString() + ".j2c";
				info->name = "Prim Texture";
				//gAssetStorage->getAssetData(asset_id, LLAssetType::AT_TEXTURE, JCAssetExportCallback, info,1);
				if(requested_textures.count(asset_id) == 0)
				{
					requested_textures.insert(asset_id);
					LLViewerImage* img = gImageList.getImage(asset_id, MIPMAP_TRUE, FALSE);
					img->setBoostLevel(LLViewerImageBoostLevel::BOOST_MAX_LEVEL);
					img->setLoadedCallback( JCExportTracker::onFileLoadedForSave, 
									0, TRUE, FALSE, info );
					llinfos << "Requesting texture " << asset_id.asString() << llendl;
				}
			}
		}

		//JCExportTracker::mirror(asset, obj, asset_dir, asset->getUUID().asString());
		
		prim_llsd["textures"] = te_llsd;

		prim_llsd["id"] = object->getID().asString();
		if(export_properties)
		{
			////cmdline_printchat(llformat("yes %d",export_properties));
			propertyqueries += 1;
			gMessageSystem->newMessageFast(_PREHASH_ObjectSelect);
			gMessageSystem->nextBlockFast(_PREHASH_AgentData);
			gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
			gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());

			gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
            gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, object->getLocalID());
            
            gMessageSystem->sendReliable(gAgent.getRegionHost());

			if(export_inventory)
			{
				object->registerInventoryListener(sInstance,NULL);
				object->dirtyInventory();
				object->requestInventory();
				invqueries += 1;
			}
		}//else //cmdline_printchat(llformat("no %d",export_properties));
		totalprims += 1;

		// Changed to use link numbers zero-indexed.
		llsd[object_index - 1] = prim_llsd;
	}
	return llsd;
}
LLSD LLObjectBackup::primsToLLSD(LLViewerObject::child_list_t child_list, bool is_attachment)
{
	LLViewerObject* object;
	LLSD llsd;
	char localid[16];

	for (LLViewerObject::child_list_t::iterator i = child_list.begin(); i != child_list.end(); ++i)
	{
		object = (*i);
		LLUUID id = object->getID();

		LL_INFOS("ObjectBackup") << "Exporting prim " << object->getID().asString() << LL_ENDL;

		// Create an LLSD object that represents this prim. It will be injected in to the overall LLSD
		// tree structure
		LLSD prim_llsd;

		if (!object->isRoot())
		{
			// Parent id
			snprintf(localid, sizeof(localid), "%u", object->getSubParent()->getLocalID());
			prim_llsd["parent"] = localid;
		}

		// Name and description
		LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->findNode(object);
		if (node)
		{
			prim_llsd["name"] = node->mName;
			prim_llsd["description"] = node->mDescription;
		}

		// Transforms
		if (is_attachment)
		{
			prim_llsd["position"] = object->getPositionEdit().getValue();
			prim_llsd["rotation"] = ll_sd_from_quaternion(object->getRotationEdit());
		}
		else
		{
			prim_llsd["position"] = object->getPosition().getValue();
			prim_llsd["rotation"] = ll_sd_from_quaternion(object->getRotation());
		}
		prim_llsd["scale"] = object->getScale().getValue();

		// Flags
		prim_llsd["shadows"] = FALSE;
		prim_llsd["phantom"] = object->flagPhantom();
		prim_llsd["physical"] = object->flagUsePhysics();

		// Volume params
		LLVolumeParams params = object->getVolume()->getParams();
		prim_llsd["volume"] = params.asLLSD();

		// Extra paramsb6fab961-af18-77f8-cf08-f021377a7244
		if (object->isFlexible())
		{
			// Flexible
			LLFlexibleObjectData* flex = (LLFlexibleObjectData*)object->getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE);
			prim_llsd["flexible"] = flex->asLLSD();
		}
		if (object->getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT))
		{
			// Light
			LLLightParams* light = (LLLightParams*)object->getParameterEntry(LLNetworkData::PARAMS_LIGHT);
			prim_llsd["light"] = light->asLLSD();
		}
		if (object->getParameterEntryInUse(LLNetworkData::PARAMS_SCULPT))
		{
			// Sculpt
			LLSculptParams* sculpt = (LLSculptParams*)object->getParameterEntry(LLNetworkData::PARAMS_SCULPT);
			prim_llsd["sculpt"] = sculpt->asLLSD();

			LLUUID sculpt_texture = sculpt->getSculptTexture();
			if (sculpt_texture == validateTextureID(sculpt_texture))
			{
				bool alreadyseen = false;
				std::list<LLUUID>::iterator iter;
				for (iter = mTexturesList.begin(); iter != mTexturesList.end(); iter++) 
				{
					if ((*iter) == sculpt_texture)
						alreadyseen = true;
				}
				if (alreadyseen == false)
				{
					LL_INFOS("ObjectBackup") << "Found a sculpt texture, adding to list " << sculpt_texture << LL_ENDL;
					mTexturesList.push_back(sculpt_texture);
				}
			}
			else
			{
				LL_WARNS("ObjectBackup") << "Incorrect permission to export a sculpt texture." << LL_ENDL;
				LLObjectBackup::getInstance()->mExportState = EXPORT_FAILED;
			}
		}

		// Textures
		LLSD te_llsd;
		LLSD this_te_llsd;
		LLUUID t_id;
		U8 te_count = object->getNumTEs();
		for (U8 i = 0; i < te_count; i++)
		{
			bool alreadyseen = false;
			t_id = validateTextureID(object->getTE(i)->getID());
			this_te_llsd = object->getTE(i)->asLLSD();
			this_te_llsd["imageid"] = t_id;
			te_llsd.append(this_te_llsd);
			// Do not export Linden textures even though they don't taint creation.
			if (t_id != LL_TEXTURE_PLYWOOD && 
			    t_id != LL_TEXTURE_BLANK && 
			    t_id != LL_TEXTURE_TRANSPARENT &&
			    t_id != LL_TEXTURE_INVISIBLE &&
			    t_id != LL_TEXTURE_MEDIA)
 			{
				std::list<LLUUID>::iterator iter;
				for (iter = mTexturesList.begin(); iter != mTexturesList.end(); iter++) 
				{
					if ((*iter) == t_id)
						alreadyseen = true;
				}
				if (alreadyseen == false)
					mTexturesList.push_back(t_id);
			}
		}
		prim_llsd["textures"] = te_llsd;

		// The keys in the primitive maps do not have to be localids, they can be any
		// string. We simply use localids because they are a unique identifier
		snprintf(localid, sizeof(localid), "%u", object->getLocalID());
		llsd[(const char*)localid] = prim_llsd;
	}
	updateExportNumbers();
	return llsd;
}
void FSFloaterObjectExport::addPrim(LLViewerObject* object, bool root)
{
	LLSD prim;
	LLUUID object_id = object->getID();
	bool default_prim = true;

	struct f : public LLSelectedNodeFunctor
	{
		LLUUID mID;
		f(const LLUUID& id) : mID(id) {}
		virtual bool apply(LLSelectNode* node)
		{
			return (node->getObject() && node->getObject()->mID == mID);
		}
	} func(object_id);
	
	LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstNode(&func);
	default_prim = (!FSExportPermsCheck::canExportNode(node, false));

	if (root)
	{
		if (object->isAttachment())
		{
			prim["attachment_point"] = ATTACHMENT_ID_FROM_STATE(object->getState());
		}
	}
	else
	{
		LLViewerObject* parent_object = (LLViewerObject*)object->getParent();
		prim["parent"] = parent_object->getID();
	}
	prim["position"] = object->getPosition().getValue();
	prim["scale"] = object->getScale().getValue();
	prim["rotation"] = ll_sd_from_quaternion(object->getRotation());

	if (default_prim)
	{
		LL_DEBUGS("export") << object_id.asString() << " failed export check. Using default prim" << LL_ENDL;
		prim["flags"] = ll_sd_from_U32((U32)0);
		prim["volume"]["path"] = LLPathParams().asLLSD();
		prim["volume"]["profile"] = LLProfileParams().asLLSD();
		prim["material"] = (S32)LL_MCODE_WOOD;
	}
	else
	{
		mExported = true;
		prim["flags"] = ll_sd_from_U32(object->getFlags());
		prim["volume"]["path"] = object->getVolume()->getParams().getPathParams().asLLSD();
		prim["volume"]["profile"] = object->getVolume()->getParams().getProfileParams().asLLSD();
		prim["material"] = (S32)object->getMaterial();
		if (object->getClickAction() != 0)
		{
			prim["clickaction"] = (S32)object->getClickAction();
		}

		LLVOVolume *volobjp = NULL;
		if (object->getPCode() == LL_PCODE_VOLUME)
		{
			volobjp = (LLVOVolume *)object;
		}
		if(volobjp)
		{
			if(volobjp->isSculpted())
			{
				const LLSculptParams *sculpt_params = (const LLSculptParams *)object->getParameterEntry(LLNetworkData::PARAMS_SCULPT);
				if (sculpt_params)
				{
					if(volobjp->isMesh())
					{
						if (!mAborted)
						{
							mAborted = true;
						}
						return;
					}
					else
					{
						if (exportTexture(sculpt_params->getSculptTexture()))
						{
							prim["sculpt"] = sculpt_params->asLLSD();
						}
						else
						{
							LLSculptParams default_sculpt;
							prim["sculpt"] = default_sculpt.asLLSD();
						}
					}
				}
			}

			if(volobjp->isFlexible())
			{
				const LLFlexibleObjectData *flexible_param_block = (const LLFlexibleObjectData *)object->getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE);
				if (flexible_param_block)
				{
					prim["flexible"] = flexible_param_block->asLLSD();
				}
			}

			if (volobjp->getIsLight())
			{
				const LLLightParams *light_param_block = (const LLLightParams *)object->getParameterEntry(LLNetworkData::PARAMS_LIGHT);
				if (light_param_block)
				{
					prim["light"] = light_param_block->asLLSD();
				}
			}

			if (volobjp->hasLightTexture())
			{
				const LLLightImageParams* light_image_param_block = (const LLLightImageParams*)object->getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE);
				if (light_image_param_block)
				{
					prim["light_texture"] = light_image_param_block->asLLSD();
				}
			}
			
		}

		if(object->isParticleSource())
		{
			LLViewerPartSourceScript* partSourceScript = object->getPartSourceScript();
			prim["particle"] = partSourceScript->mPartSysData.asLLSD();
			if (!exportTexture(partSourceScript->mPartSysData.mPartImageID))
			{
				prim["particle"]["PartImageID"] = LLUUID::null.asString();
			}
		}

		U8 texture_count = object->getNumTEs();
		for(U8 i = 0; i < texture_count; ++i)
		{
			LLTextureEntry *checkTE = object->getTE(i);
			LL_DEBUGS("export") << "Checking texture number " << (S32)i
				<< ", ID " << checkTE->getID() << LL_ENDL;
			if (FSCommon::isDefaultTexture(checkTE->getID()))	// <FS:CR> Check against default textures
			{
				LL_DEBUGS("export") << "...is a default texture." << LL_ENDL;
				prim["texture"].append(checkTE->asLLSD());
			}
			else if (exportTexture(checkTE->getID()))
			{
				LL_DEBUGS("export") << "...export check passed." << LL_ENDL;
				prim["texture"].append(checkTE->asLLSD());
			}
			else
			{
				LL_DEBUGS("export") << "...export check failed." << LL_ENDL;
				checkTE->setID(LL_DEFAULT_WOOD_UUID); // TODO: use user option of default texture.
				prim["texture"].append(checkTE->asLLSD());
			}
			
			// [FS:CR] Materials support
			if (checkTE->getMaterialParams().notNull())
			{
				LL_DEBUGS("export") << "found materials. Checking permissions..." << LL_ENDL;
				LLSD params = checkTE->getMaterialParams().get()->asLLSD();
				/// *TODO: Feeling lazy so I made it check both. This is incorrect and needs to be expanded
				/// to retain exportable textures not just failing both when one is non-exportable (or unset).
				if (exportTexture(params["NormMap"].asUUID()) &&
					exportTexture(params["SpecMap"].asUUID()))
				{
					LL_DEBUGS("export") << "...passed check." << LL_ENDL;
					prim["materials"].append(params);
				}
			}
		}

		if (!object->getPhysicsShapeUnknown())
		{
			prim["ExtraPhysics"]["PhysicsShapeType"] = (S32)object->getPhysicsShapeType();
			prim["ExtraPhysics"]["Density"] = (F64)object->getPhysicsDensity();
			prim["ExtraPhysics"]["Friction"] = (F64)object->getPhysicsFriction();
			prim["ExtraPhysics"]["Restitution"] = (F64)object->getPhysicsRestitution();
			prim["ExtraPhysics"]["GravityMultiplier"] = (F64)object->getPhysicsGravity();
		}

		prim["name"] = node->mName;
		prim["description"] = node->mDescription;
		prim["creation_date"] = ll_sd_from_U64(node->mCreationDate);

		LLAvatarName avatar_name;
		LLUUID creator_id = node->mPermissions->getCreator();
		if (creator_id.notNull())
		{
			prim["creator_id"] = creator_id;
			if (LLAvatarNameCache::get(creator_id, &avatar_name))
			{
				prim["creator_name"] = avatar_name.asLLSD();
			}
		}
		LLUUID owner_id = node->mPermissions->getOwner();
		if (owner_id.notNull())
		{
			prim["owner_id"] = owner_id;
			if (LLAvatarNameCache::get(owner_id, &avatar_name))
			{
				prim["owner_name"] = avatar_name.asLLSD();
			}
		}
		LLUUID group_id = node->mPermissions->getGroup();
		if (group_id.notNull())
		{
			prim["group_id"] = group_id;
			if (LLAvatarNameCache::get(group_id, &avatar_name))
			{
				prim["group_name"] = avatar_name.asLLSD();
			}
		}
		LLUUID last_owner_id = node->mPermissions->getLastOwner();
		if (last_owner_id.notNull())
		{
			prim["last_owner_id"] = last_owner_id;
			if (LLAvatarNameCache::get(last_owner_id, &avatar_name))
			{
				prim["last_owner_name"] = avatar_name.asLLSD();
			}
		}
		prim["base_mask"] = ll_sd_from_U32(node->mPermissions->getMaskBase());
		prim["owner_mask"] = ll_sd_from_U32(node->mPermissions->getMaskOwner());
		prim["group_mask"] = ll_sd_from_U32(node->mPermissions->getMaskGroup());
		prim["everyone_mask"] = ll_sd_from_U32(node->mPermissions->getMaskEveryone());
		prim["next_owner_mask"] = ll_sd_from_U32(node->mPermissions->getMaskNextOwner());
		
		prim["sale_info"] = node->mSaleInfo.asLLSD();
		prim["touch_name"] = node->mTouchName;
		prim["sit_name"] = node->mSitName;

		static LLCachedControl<bool> sExportContents(gSavedSettings, "FSExportContents");
		if (sExportContents)
		{
			mInventoryRequests.push_back(object_id);
			object->registerInventoryListener(this, NULL);
			object->dirtyInventory();
			object->requestInventory();
		}
	}

	mManifest["prim"][object_id.asString()] = prim;
}
LLSD LLObjectBackup::primsToLLSD(LLViewerObject::child_list_t child_list,
								 bool is_attachment)
{
	LLViewerObject* object;
	LLSD llsd;
	char localid[16];
	LLUUID t_id;

	for (LLViewerObject::child_list_t::iterator i = child_list.begin();
		 i != child_list.end(); ++i)
	{
		object = (*i);
		LLUUID id = object->getID();

		LL_INFOS() << "Exporting prim " << object->getID().asString() << LL_ENDL;

		// Create an LLSD object that represents this prim. It will be injected
		// in to the overall LLSD tree structure
		LLSD prim_llsd;

		if (!object->isRoot())
		{
			// Parent id
			snprintf(localid, sizeof(localid), "%u",
					 object->getSubParent()->getLocalID());
			prim_llsd["parent"] = localid;
		}

		// Name and description
		LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->findNode(object);
		if (node)
		{
			prim_llsd["name"] = node->mName;
			prim_llsd["description"] = node->mDescription;
		}

		// Transforms
		if (is_attachment)
		{
			prim_llsd["position"] = object->getPositionEdit().getValue();
			prim_llsd["rotation"] = ll_sd_from_quaternion(object->getRotationEdit());
		}
		else
		{
			prim_llsd["position"] = object->getPosition().getValue();
			prim_llsd["rotation"] = ll_sd_from_quaternion(object->getRotation());
		}
		prim_llsd["scale"] = object->getScale().getValue();

		// Flags
		prim_llsd["phantom"] = object->flagPhantom();		// legacy
		prim_llsd["physical"] = object->flagUsePhysics();	// legacy
		prim_llsd["flags"] = (S32)object->getFlags();		// new way

		// Extra physics flags
		if (mGotExtraPhysics)
		{
			LLSD& physics = prim_llsd["ExtraPhysics"];
			physics["PhysicsShapeType"] = object->getPhysicsShapeType();
			physics["Gravity"] = object->getPhysicsGravity();
			physics["Friction"] = object->getPhysicsFriction();
			physics["Density"] = object->getPhysicsDensity();
			physics["Restitution"] = object->getPhysicsRestitution();
		}

		// Click action
		if (S32 action = object->getClickAction()) // Non-zero
			prim_llsd["clickaction"] = action;

		// Prim material
		prim_llsd["material"] = object->getMaterial();

		// Volume params
		LLVolumeParams params = object->getVolume()->getParams();
		prim_llsd["volume"] = params.asLLSD();

		// Extra paramsb6fab961-af18-77f8-cf08-f021377a7244

		if (object->isFlexible())
		{
			// Flexible
			LLFlexibleObjectData* flex;
			flex = (LLFlexibleObjectData*)object->getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE);
			prim_llsd["flexible"] = flex->asLLSD();
		}

		if (object->getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT))
		{
			// Light
			LLLightParams* light;
			light = (LLLightParams*)object->getParameterEntry(LLNetworkData::PARAMS_LIGHT);
			prim_llsd["light"] = light->asLLSD();
		}
		if (object->getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE))
		{
			// Light image
			LLLightImageParams* light_param;
			light_param = (LLLightImageParams*)object->getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE);
			t_id = validateTextureID(light_param->getLightTexture());
			if (mTexturesList.count(t_id) == 0)
			{
				LL_INFOS() << "Found a light texture, adding to list " << t_id
						<< LL_ENDL;
				mTexturesList.insert(t_id);
			}
			prim_llsd["light_texture"] = light_param->asLLSD();
		}

		if (object->getParameterEntryInUse(LLNetworkData::PARAMS_SCULPT))
		{
			// Sculpt
			LLSculptParams* sculpt;
			sculpt = (LLSculptParams*)object->getParameterEntry(LLNetworkData::PARAMS_SCULPT);
			prim_llsd["sculpt"] = sculpt->asLLSD();
			if ((sculpt->getSculptType() & LL_SCULPT_TYPE_MASK) != LL_SCULPT_TYPE_MESH)
			{
				LLUUID sculpt_texture = sculpt->getSculptTexture();
				if (sculpt_texture == validateTextureID(sculpt_texture))
				{
					if (mTexturesList.count(sculpt_texture) == 0)
					{
						LL_INFOS() << "Found a sculpt texture, adding to list "
								<< sculpt_texture << LL_ENDL;
						mTexturesList.insert(sculpt_texture);
					}
				}
				else
				{
					LL_WARNS() << "Incorrect permission to export a sculpt texture."
							<< LL_ENDL;
					mExportState = EXPORT_FAILED;
				}
			}
		}

		// Textures and materials
		LLSD te_llsd;
		LLSD this_te_llsd;
		LLSD te_mat_llsd;
		LLSD this_te_mat_llsd;
		bool has_materials = false;
		for (U8 i = 0, count = object->getNumTEs(); i < count; ++i)
		{
			LLTextureEntry* te = object->getTE(i);
			if (!te) continue;	// Paranoia

			// Normal texture/diffuse map
			t_id = validateTextureID(te->getID());
			this_te_llsd = te->asLLSD();
			this_te_llsd["imageid"] = t_id;
			te_llsd.append(this_te_llsd);
			// Do not export non-existent default textures
			if (t_id != LL_TEXTURE_BLANK && t_id != LL_TEXTURE_INVISIBLE)
			{
				if (mTexturesList.count(t_id) == 0)
				{
					mTexturesList.insert(t_id);
				}
			}

			// Materials
			LLMaterial* mat = te->getMaterialParams().get();
			if (mat)
			{
				has_materials = true;
				this_te_mat_llsd = mat->asLLSD();

				t_id = validateTextureID(mat->getNormalID());
				this_te_mat_llsd["NormMap"] = t_id;
				if (mTexturesList.count(t_id) == 0)
				{
					mTexturesList.insert(t_id);
				}

				t_id = validateTextureID(mat->getSpecularID());
				this_te_mat_llsd["SpecMap"] = t_id;
				if (mTexturesList.count(t_id) == 0)
				{
					mTexturesList.insert(t_id);
				}

				te_mat_llsd.append(this_te_mat_llsd);
			}
		}
		prim_llsd["textures"] = te_llsd;
		if (has_materials)
		{
			prim_llsd["materials"] = te_mat_llsd;
		}

		// The keys in the primitive maps do not have to be localids, they can
		// be any string. We simply use localids because they are a unique
		// identifier
		snprintf(localid, sizeof(localid), "%u", object->getLocalID());
		llsd[(const char*)localid] = prim_llsd;
	}

	updateExportNumbers();

	return llsd;
}
LLSD primbackup::prims_to_llsd(LLViewerObject::child_list_t child_list)
{

	LLViewerObject* object;
	LLSD llsd;

	char localid[16];

	for (LLViewerObject::child_list_t::iterator i = child_list.begin(); i != child_list.end(); ++i)
	{
		object=(*i);
		LLUUID id = object->getID();

		llinfos << "Exporting prim " << object->getID().asString() << llendl;

		// Create an LLSD object that represents this prim. It will be injected in to the overall LLSD
		// tree structure
		LLSD prim_llsd;

		if (!object->isRoot())
		{

			// Parent id
			snprintf(localid, sizeof(localid), "%u", object->getSubParent()->getLocalID());
			prim_llsd["parent"] = localid;
		}

		// Transforms
		prim_llsd["position"] = object->getPosition().getValue();
		prim_llsd["scale"] = object->getScale().getValue();
		prim_llsd["rotation"] = ll_sd_from_quaternion(object->getRotation());

		// Flags
		prim_llsd["shadows"] = object->flagCastShadows();
		prim_llsd["phantom"] = object->flagPhantom();
		prim_llsd["physical"] = (BOOL)(object->mFlags & FLAGS_USE_PHYSICS);

		// Volume params
		LLVolumeParams params = object->getVolume()->getParams();
		prim_llsd["volume"] = params.asLLSD();

		// Extra paramsb6fab961-af18-77f8-cf08-f021377a7244
		if (object->isFlexible())
		{
			// Flexible
			LLFlexibleObjectData* flex = (LLFlexibleObjectData*)object->getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE);
			prim_llsd["flexible"] = flex->asLLSD();
		}
		if (object->getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT))
		{
			// Light
			LLLightParams* light = (LLLightParams*)object->getParameterEntry(LLNetworkData::PARAMS_LIGHT);
			prim_llsd["light"] = light->asLLSD();
		}
		if (object->getParameterEntryInUse(LLNetworkData::PARAMS_SCULPT))
		{
			// Sculpt
			LLSculptParams* sculpt = (LLSculptParams*)object->getParameterEntry(LLNetworkData::PARAMS_SCULPT);
			prim_llsd["sculpt"] = sculpt->asLLSD();
			
			LLUUID sculpt_texture=sculpt->getSculptTexture();
			bool alreadyseen=false;
			std::list<LLUUID>::iterator iter;
			for(iter = textures.begin(); iter != textures.end() ; iter++) 
			{
				if( (*iter)==sculpt_texture)
					alreadyseen=true;
			}
			if(alreadyseen==false)
			{
				llinfos << "Found a sculpt texture, adding to list "<<sculpt_texture<<llendl;
				textures.push_back(sculpt_texture);
			}
		}

		// Textures
		LLSD te_llsd;
		U8 te_count = object->getNumTEs();
		for (U8 i = 0; i < te_count; i++)
		{
			bool alreadyseen=false;
			te_llsd.append(object->getTE(i)->asLLSD());
			std::list<LLUUID>::iterator iter;
			for(iter = textures.begin(); iter != textures.end() ; iter++) 
			{
				if( (*iter)==object->getTE(i)->getID())
					alreadyseen=true;
			}
			if(alreadyseen==false)
				textures.push_back(object->getTE(i)->getID());
		}
		prim_llsd["textures"] = te_llsd;

		// The keys in the primitive maps do not have to be localids, they can be any
		// string. We simply use localids because they are a unique identifier
		snprintf(localid, sizeof(localid), "%u", object->getLocalID());
		llsd[(const char*)localid] = prim_llsd;
	}

	updateexportnumbers();

	return llsd;
}
void FSExport::addPrim(LLViewerObject* object, bool root)
{
	LLSD prim;
	LLUUID object_id = object->getID();
	bool default_prim = true;

	struct f : public LLSelectedNodeFunctor
	{
		LLUUID mID;
		f(const LLUUID& id) : mID(id) {}
		virtual bool apply(LLSelectNode* node)
		{
			return (node->getObject() && node->getObject()->mID == mID);
		}
	} func(object_id);
	LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstNode(&func);
	if (node)
	{
		if ((LLGridManager::getInstance()->isInSecondLife())
			&& object->permYouOwner()
			&& (gAgentID == node->mPermissions->getCreator() || megaPrimCheck(node->mPermissions->getCreator(), object)))
		{
			default_prim = false;
		}
#if OPENSIM
		if (LLGridManager::getInstance()->isInOpenSim()
		      && object->permYouOwner()
		      && object->permModify()
		      && object->permCopy()
		      && object->permTransfer())
		{
			default_prim = false;
		}
#endif
	}
	else
	{
		LL_WARNS("export") << "LLSelect node for " << object_id.asString() << " not found. Using default prim instead." << LL_ENDL;
		default_prim = true;
	}

	if (root)
	{
		if (object->isAttachment())
		{
			prim["attachment_point"] = ATTACHMENT_ID_FROM_STATE(object->getState());
		}
	}
	else
	{
		LLViewerObject* parent_object = (LLViewerObject*)object->getParent();
		prim["parent"] = parent_object->getID();
	}
	prim["position"] = object->getPosition().getValue();
	prim["scale"] = object->getScale().getValue();
	prim["rotation"] = ll_sd_from_quaternion(object->getRotation());

	if (default_prim)
	{
		LL_DEBUGS("export") << object_id.asString() << " failed export check. Using default prim" << LL_ENDL;
		prim["flags"] = ll_sd_from_U32((U32)0);
		prim["volume"]["path"] = LLPathParams().asLLSD();
		prim["volume"]["profile"] = LLProfileParams().asLLSD();
		prim["material"] = (S32)LL_MCODE_WOOD;
	}
	else
	{
		mExported = true;
		prim["flags"] = ll_sd_from_U32(object->getFlags());
		prim["volume"]["path"] = object->getVolume()->getParams().getPathParams().asLLSD();
		prim["volume"]["profile"] = object->getVolume()->getParams().getProfileParams().asLLSD();
		prim["material"] = (S32)object->getMaterial();
		if (object->getClickAction() != 0)
		{
			prim["clickaction"] = (S32)object->getClickAction();
		}

		LLVOVolume *volobjp = NULL;
		if (object->getPCode() == LL_PCODE_VOLUME)
		{
			volobjp = (LLVOVolume *)object;
		}
		if(volobjp)
		{
			if(volobjp->isSculpted())
			{
				const LLSculptParams *sculpt_params = (const LLSculptParams *)object->getParameterEntry(LLNetworkData::PARAMS_SCULPT);
				if (sculpt_params)
				{
					if(volobjp->isMesh())
					{
						if (!mAborted)
						{
							reportToNearbyChat(LLTrans::getString("export_fail_no_mesh"));
							mAborted = true;
						}
						return;
					}
					else
					{
						if (exportTexture(sculpt_params->getSculptTexture()))
						{
							prim["sculpt"] = sculpt_params->asLLSD();
						}
						else
						{
							LLSculptParams default_sculpt;
							prim["sculpt"] = default_sculpt.asLLSD();
						}
					}
				}
			}

			if(volobjp->isFlexible())
			{
				const LLFlexibleObjectData *flexible_param_block = (const LLFlexibleObjectData *)object->getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE);
				if (flexible_param_block)
				{
					prim["flexible"] = flexible_param_block->asLLSD();
				}
			}

			if (volobjp->getIsLight())
			{
				const LLLightParams *light_param_block = (const LLLightParams *)object->getParameterEntry(LLNetworkData::PARAMS_LIGHT);
				if (light_param_block)
				{
					prim["light"] = light_param_block->asLLSD();
				}
			}

			if (volobjp->hasLightTexture())
			{
				const LLLightImageParams* light_image_param_block = (const LLLightImageParams*)object->getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE);
				if (light_image_param_block)
				{
					prim["light_texture"] = light_image_param_block->asLLSD();
				}
			}
			
		}

		if(object->isParticleSource())
		{
			LLViewerPartSourceScript* partSourceScript = object->getPartSourceScript();
			prim["particle"] = partSourceScript->mPartSysData.asLLSD();
			if (!exportTexture(partSourceScript->mPartSysData.mPartImageID))
			{
				prim["particle"]["PartImageID"] = LLUUID::null.asString();
			}
		}

		U8 texture_count = object->getNumTEs();
		for(U8 i = 0; i < texture_count; ++i)
		{
			if (exportTexture(object->getTE(i)->getID()))
			{
				prim["texture"].append(object->getTE(i)->asLLSD());
			}
			else
			{
				LLTextureEntry te(LL_DEFAULT_WOOD_UUID); // TODO: use user option of default texture.
				prim["texture"].append(te.asLLSD());
			}
		}

		if (!object->getPhysicsShapeUnknown())
		{
			prim["ExtraPhysics"]["PhysicsShapeType"] = (S32)object->getPhysicsShapeType();
			prim["ExtraPhysics"]["Density"] = (F64)object->getPhysicsDensity();
			prim["ExtraPhysics"]["Friction"] = (F64)object->getPhysicsFriction();
			prim["ExtraPhysics"]["Restitution"] = (F64)object->getPhysicsRestitution();
			prim["ExtraPhysics"]["GravityMultiplier"] = (F64)object->getPhysicsGravity();
		}

		prim["name"] = node->mName;
		prim["description"] = node->mDescription;
		prim["creation_date"] = ll_sd_from_U64(node->mCreationDate);

		LLAvatarName avatar_name;
		LLUUID creator_id = node->mPermissions->getCreator();
		if (creator_id.notNull())
		{
			prim["creator_id"] = creator_id;
			if (LLAvatarNameCache::get(creator_id, &avatar_name))
			{
				prim["creator_name"] = avatar_name.asLLSD();
			}
		}
		LLUUID owner_id = node->mPermissions->getOwner();
		if (owner_id.notNull())
		{
			prim["owner_id"] = owner_id;
			if (LLAvatarNameCache::get(owner_id, &avatar_name))
			{
				prim["owner_name"] = avatar_name.asLLSD();
			}
		}
		LLUUID group_id = node->mPermissions->getGroup();
		if (group_id.notNull())
		{
			prim["group_id"] = group_id;
			if (LLAvatarNameCache::get(group_id, &avatar_name))
			{
				prim["group_name"] = avatar_name.asLLSD();
			}
		}
		LLUUID last_owner_id = node->mPermissions->getLastOwner();
		if (last_owner_id.notNull())
		{
			prim["last_owner_id"] = last_owner_id;
			if (LLAvatarNameCache::get(last_owner_id, &avatar_name))
			{
				prim["last_owner_name"] = avatar_name.asLLSD();
			}
		}
		prim["base_mask"] = ll_sd_from_U32(node->mPermissions->getMaskBase());
		prim["owner_mask"] = ll_sd_from_U32(node->mPermissions->getMaskOwner());
		prim["group_mask"] = ll_sd_from_U32(node->mPermissions->getMaskGroup());
		prim["everyone_mask"] = ll_sd_from_U32(node->mPermissions->getMaskEveryone());
		prim["next_owner_mask"] = ll_sd_from_U32(node->mPermissions->getMaskNextOwner());
		
		prim["sale_info"] = node->mSaleInfo.asLLSD();
		prim["touch_name"] = node->mTouchName;
		prim["sit_name"] = node->mSitName;

		mInventoryRequests.push_back(object_id);
		object->registerInventoryListener(this, NULL);
		object->dirtyInventory();
		object->requestInventory();
	}

	mFile["prim"][object_id.asString()] = prim;
}