Merge remote-tracking branch 'lirusaito/master'
This commit is contained in:
@@ -244,15 +244,11 @@ protected:
|
||||
virtual void dirtyMesh(S32 priority) = 0; // Dirty the avatar mesh, with priority
|
||||
|
||||
protected:
|
||||
friend class WavefrontSaver;
|
||||
typedef std::multimap<std::string, LLPolyMesh*> polymesh_map_t;
|
||||
polymesh_map_t mPolyMeshes;
|
||||
avatar_joint_list_t mMeshLOD;
|
||||
|
||||
// <edit>
|
||||
public:
|
||||
const virtual avatar_joint_list_t& getMeshLOD() const { return mMeshLOD; }
|
||||
// </edit>
|
||||
|
||||
/** Meshes
|
||||
** **
|
||||
*******************************************************************************/
|
||||
|
||||
@@ -62,6 +62,7 @@ public:
|
||||
class LLAvatarJointMesh : public virtual LLAvatarJoint
|
||||
{
|
||||
protected:
|
||||
friend class WavefrontSaver;
|
||||
LLColor4 mColor; // color value
|
||||
// LLColor4 mSpecular; // specular color (always white for now)
|
||||
F32 mShiny; // shiny value
|
||||
@@ -131,10 +132,6 @@ public:
|
||||
|
||||
void setIsTransparent(BOOL is_transparent) { mIsTransparent = is_transparent; }
|
||||
|
||||
// <edit>
|
||||
public:
|
||||
LLFace* getFace() { return mFace; }
|
||||
// </edit>
|
||||
private:
|
||||
// Allocate skin data
|
||||
BOOL allocateSkinData( U32 numSkinJoints );
|
||||
|
||||
@@ -932,7 +932,6 @@ P2(groupMemberDataResponder, transfer_300s);
|
||||
P2(groupProposalBallotResponder, transfer_300s);
|
||||
P(homeLocationResponder);
|
||||
P2(HTTPGetResponder, reply_15s);
|
||||
P(iamHereLogin);
|
||||
P(iamHere);
|
||||
P(iamHereVoice);
|
||||
P2(inventoryModelFetchDescendentsResponder, transfer_300s);
|
||||
|
||||
@@ -642,6 +642,28 @@
|
||||
<key>Value</key>
|
||||
<boolean>0</boolean>
|
||||
</map>
|
||||
<key>OBJExportNotifyFailed</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Show a notification when exporting to OBJ fails (both partially and completely)</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>OBJExportNotifySuccess</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Show a notification when exporting to OBJ succeeds</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>OBJExportSwapYZ</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
@@ -653,5 +675,5 @@
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
</map>
|
||||
</map>
|
||||
</llsd>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @file awavefront.cpp
|
||||
* @brief A system which allows saving in-world objects to Wavefront .OBJ files for offline texturizing/shading.
|
||||
* @author Apelsin
|
||||
* @authors Apelsin, Lirusaito
|
||||
*
|
||||
* $LicenseInfo:firstyear=2011&license=LGPLV3$
|
||||
* Copyright (C) 2011-2013 Apelsin
|
||||
@@ -27,13 +27,14 @@
|
||||
|
||||
// library includes
|
||||
#include "aifilepicker.h"
|
||||
#include "llnotificationsutil.h"
|
||||
|
||||
// newview includes
|
||||
#include "lfsimfeaturehandler.h"
|
||||
#include "llavatarappearancedefines.h"
|
||||
#include "llface.h"
|
||||
#include "llvoavatar.h"
|
||||
|
||||
typedef std::vector<LLAvatarJoint*> avatar_joint_list_t;
|
||||
#include "llvovolume.h"
|
||||
|
||||
// menu includes
|
||||
#include "llevent.h"
|
||||
@@ -42,7 +43,10 @@ typedef std::vector<LLAvatarJoint*> avatar_joint_list_t;
|
||||
#include "llselectmgr.h"
|
||||
|
||||
LLVOAvatar* find_avatar_from_object(LLViewerObject* object);
|
||||
extern LLUUID gAgentID;
|
||||
|
||||
//Typedefs used in other files, using here for consistency.
|
||||
typedef std::vector<LLAvatarJoint*> avatar_joint_list_t;
|
||||
typedef LLMemberListener<LLView> view_listener_t;
|
||||
|
||||
namespace
|
||||
@@ -57,6 +61,8 @@ namespace
|
||||
{
|
||||
wfsaver->saveFile(fp);
|
||||
llinfos << "OBJ file saved to " << selected_filename << llendl;
|
||||
if (gSavedSettings.getBOOL("OBJExportNotifySuccess"))
|
||||
LLNotificationsUtil::add("WavefrontExportSuccess", LLSD().with("FILENAME", selected_filename));
|
||||
fclose(fp);
|
||||
}
|
||||
else llerrs << "can't open: " << selected_filename << llendl;
|
||||
@@ -192,22 +198,42 @@ void WavefrontSaver::Add(const LLViewerObject* some_vo)
|
||||
normfix.setRotation(v_form.getRotation()); //Should work...
|
||||
Add(some_vo->getVolume(), &v_form, &normfix);
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
class LLSaveSelectedObjects : public view_listener_t
|
||||
bool can_export_node(const LLSelectNode* node)
|
||||
{
|
||||
if (const LLPermissions* perms = node->mPermissions)
|
||||
{
|
||||
if (!(gAgentID == perms->getCreator() || (LFSimFeatureHandler::instance().simSupportsExport() && gAgentID == perms->getOwner() && perms->getMaskEveryone() & PERM_EXPORT)))
|
||||
{
|
||||
static const LLCachedControl<bool> notify("OBJExportNotifyFailed", false);
|
||||
if (notify) LLNotificationsUtil::add("WavefrontExportPartial", LLSD().with("OBJECT", node->mName));
|
||||
}
|
||||
else return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
class LFSaveSelectedObjects : public view_listener_t
|
||||
{
|
||||
bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata)
|
||||
{
|
||||
if (LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection())
|
||||
{
|
||||
WavefrontSaver* wfsaver = new WavefrontSaver; //deleted in callback
|
||||
WavefrontSaver* wfsaver = new WavefrontSaver; // deleted in callback
|
||||
wfsaver->offset = -selection->getFirstRootObject()->getRenderPosition();
|
||||
for (LLObjectSelection::iterator iter = selection->begin(); iter != selection->end(); ++iter)
|
||||
{
|
||||
LLSelectNode* node = *iter;
|
||||
if (!can_export_node(node)) continue;
|
||||
wfsaver->Add(node->getObject());
|
||||
}
|
||||
if (wfsaver->obj_v.empty())
|
||||
{
|
||||
if (gSavedSettings.getBOOL("OBJExportNotifyFailed"))
|
||||
LLNotificationsUtil::add("ExportFailed");
|
||||
delete wfsaver;
|
||||
return true;
|
||||
}
|
||||
|
||||
AIFilePicker* filepicker = AIFilePicker::create();
|
||||
filepicker->open(selection->getFirstNode()->mName.c_str()+OBJ);
|
||||
@@ -221,7 +247,7 @@ namespace
|
||||
void WavefrontSaver::Add(const LLVOAvatar* av_vo) //adds attachments, too!
|
||||
{
|
||||
offset = -av_vo->getRenderPosition();
|
||||
avatar_joint_list_t vjv = av_vo->getMeshLOD();
|
||||
avatar_joint_list_t vjv = av_vo->mMeshLOD;
|
||||
for (avatar_joint_list_t::const_iterator itervj = vjv.begin(); itervj != vjv.end(); ++itervj)
|
||||
{
|
||||
const LLViewerJoint* vj = dynamic_cast<LLViewerJoint*>(*itervj);
|
||||
@@ -231,7 +257,7 @@ void WavefrontSaver::Add(const LLVOAvatar* av_vo) //adds attachments, too!
|
||||
if (!vjm) continue;
|
||||
|
||||
vjm->updateJointGeometry();
|
||||
LLFace* face = vjm->getFace();
|
||||
LLFace* face = vjm->mFace;
|
||||
if (!face) continue;
|
||||
|
||||
//Beware: this is a hack because LLFace has multiple LODs
|
||||
@@ -271,6 +297,11 @@ void WavefrontSaver::Add(const LLVOAvatar* av_vo) //adds attachments, too!
|
||||
{
|
||||
const LLViewerObject* c = *iterc;
|
||||
if (!c) continue;
|
||||
if (const LLSelectNode* n = LLSelectMgr::getInstance()->getSelection()->findNode(const_cast<LLViewerObject*>(c)))
|
||||
{
|
||||
if (!can_export_node(n)) continue;
|
||||
}
|
||||
else continue;
|
||||
const LLVolume* vol = c->getVolume();
|
||||
if (!vol) continue;
|
||||
|
||||
@@ -293,17 +324,28 @@ void WavefrontSaver::Add(const LLVOAvatar* av_vo) //adds attachments, too!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
class LLSaveSelectedAvatar : public view_listener_t
|
||||
class LFSaveSelectedAvatar : public view_listener_t
|
||||
{
|
||||
bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata)
|
||||
{
|
||||
if (const LLVOAvatar* avatar = find_avatar_from_object(LLSelectMgr::getInstance()->getSelection()->getPrimaryObject()))
|
||||
{
|
||||
WavefrontSaver* wfsaver = new WavefrontSaver; //deleted in callback
|
||||
if (!avatar->isSelf())
|
||||
{
|
||||
if (gSavedSettings.getBOOL("OBJExportNotifyFailed")) LLNotificationsUtil::add("ExportFailed");
|
||||
return true;
|
||||
}
|
||||
WavefrontSaver* wfsaver = new WavefrontSaver; // deleted in callback
|
||||
wfsaver->Add(avatar);
|
||||
if (wfsaver->obj_v.empty())
|
||||
{
|
||||
if (gSavedSettings.getBOOL("OBJExportNotifyFailed"))
|
||||
LLNotificationsUtil::add("ExportFailed");
|
||||
delete wfsaver;
|
||||
return true;
|
||||
}
|
||||
|
||||
AIFilePicker* filepicker = AIFilePicker::create();
|
||||
filepicker->open(avatar->getFullname()+OBJ);
|
||||
@@ -383,9 +425,9 @@ bool WavefrontSaver::saveFile(LLFILE* fp)
|
||||
}
|
||||
|
||||
void addMenu(view_listener_t* menu, const std::string& name);
|
||||
void add_wave_listeners() //Called in llviewermenu with other addMenu calls, function linked against
|
||||
void add_wave_listeners() // Called in llviewermenu with other addMenu calls, function linked against
|
||||
{
|
||||
addMenu(new LLSaveSelectedObjects(), "Object.SaveAsOBJ");
|
||||
addMenu(new LLSaveSelectedAvatar(), "Avatar.SaveAsOBJ");
|
||||
addMenu(new LFSaveSelectedObjects(), "Object.SaveAsOBJ");
|
||||
addMenu(new LFSaveSelectedAvatar(), "Avatar.SaveAsOBJ");
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @file awavefront.h
|
||||
* @brief A system which allows saving in-world objects to Wavefront .OBJ files for offline texturizing/shading.
|
||||
* @author Apelsin
|
||||
* @authors Apelsin, Lirusaito
|
||||
*
|
||||
* $LicenseInfo:firstyear=2011&license=LGPLV3$
|
||||
* Copyright (C) 2011-2013 Apelsin
|
||||
@@ -24,14 +24,6 @@
|
||||
#ifndef AWAVEFRONT
|
||||
#define AWAVEFRONT
|
||||
|
||||
#include <vector>
|
||||
#include "v3math.h"
|
||||
#include "v2math.h"
|
||||
#include "llface.h"
|
||||
#include "llvolume.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
class LLFace;
|
||||
class LLPolyMesh;
|
||||
class LLViewerObject;
|
||||
|
||||
@@ -520,7 +520,7 @@ BOOL LLPanelAvatarSecondLife::postBuild(void)
|
||||
|
||||
getChild<LLUICtrl>("Add Friend...")->setCommitCallback(boost::bind(LLAvatarActions::requestFriendshipDialog, boost::bind(&LLPanelAvatar::getAvatarID, pa)));
|
||||
getChild<LLUICtrl>("Pay...")->setCommitCallback(boost::bind(LLAvatarActions::pay, boost::bind(&LLPanelAvatar::getAvatarID, pa)));
|
||||
childSetAction("Mute", LLPanelAvatar::onClickMute, pa);
|
||||
getChild<LLUICtrl>("Mute")->setCommitCallback(boost::bind(LLAvatarActions::toggleBlock, boost::bind(&LLPanelAvatar::getAvatarID, pa)));
|
||||
|
||||
getChild<LLUICtrl>("Offer Teleport...")->setCommitCallback(boost::bind(static_cast<void(*)(const LLUUID&)>(LLAvatarActions::offerTeleport), boost::bind(&LLPanelAvatar::getAvatarID, pa)));
|
||||
|
||||
@@ -1727,26 +1727,6 @@ void LLPanelAvatar::onClickGetKey(void *userdata)
|
||||
gViewerWindow->mWindow->copyTextToClipboard(utf8str_to_wstring(agent_id.asString()));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// onClickMute()
|
||||
//-----------------------------------------------------------------------------
|
||||
void LLPanelAvatar::onClickMute(void *userdata)
|
||||
{
|
||||
LLPanelAvatar* self = (LLPanelAvatar*) userdata;
|
||||
|
||||
LLUUID agent_id = self->getAvatarID();
|
||||
|
||||
LLFloaterMute::showInstance();
|
||||
if (LLAvatarActions::isBlocked(agent_id))
|
||||
{
|
||||
LLFloaterMute::getInstance()->selectMute(agent_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
LLAvatarActions::toggleBlock(agent_id);
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void LLPanelAvatar::onClickOK(void *userdata)
|
||||
{
|
||||
|
||||
@@ -40,23 +40,11 @@
|
||||
#include "llavatarpropertiesprocessor.h"
|
||||
|
||||
class LLAvatarName;
|
||||
class LLButton;
|
||||
class LLCheckBoxCtrl;
|
||||
class LLDropTarget;
|
||||
class LLInventoryItem;
|
||||
class LLLineEditor;
|
||||
class LLNameEditor;
|
||||
class LLPanelAvatar;
|
||||
class LLScrollListCtrl;
|
||||
class LLTabContainer;
|
||||
class LLTextBox;
|
||||
class LLTextEditor;
|
||||
class LLTextureCtrl;
|
||||
class LLUICtrl;
|
||||
class LLViewerTexture;
|
||||
class LLViewerObject;
|
||||
class LLMessageSystem;
|
||||
class LLIconCtrl;
|
||||
class LLMediaCtrl;
|
||||
class LLPanelPick;
|
||||
|
||||
@@ -328,7 +316,6 @@ public:
|
||||
static void onClickGetKey(void *userdata);
|
||||
static void onClickOK( void *userdata);
|
||||
static void onClickCancel( void *userdata);
|
||||
static void onClickMute( void *userdata);
|
||||
|
||||
private:
|
||||
void enableOKIfReady();
|
||||
|
||||
@@ -90,9 +90,6 @@
|
||||
#include "llstring.h"
|
||||
#include <cctype>
|
||||
|
||||
class AIHTTPTimeoutPolicy;
|
||||
extern AIHTTPTimeoutPolicy iamHereLogin_timeout;
|
||||
|
||||
const S32 BLACK_BORDER_HEIGHT = 160;
|
||||
const S32 MAX_PASSWORD = 16;
|
||||
|
||||
|
||||
@@ -171,7 +171,6 @@
|
||||
#include "shfloatermediaticker.h"
|
||||
#include "llpacketring.h"
|
||||
#include "aihttpview.h"
|
||||
#include "awavefront.h"
|
||||
// </edit>
|
||||
|
||||
#include "scriptcounter.h"
|
||||
@@ -225,6 +224,7 @@ void handle_test_load_url(void*);
|
||||
|
||||
class AIHTTPView;
|
||||
|
||||
void add_wave_listeners();
|
||||
//extern BOOL gHideSelectedObjects;
|
||||
//extern BOOL gAllowSelectAvatar;
|
||||
//extern BOOL gDebugAvatarRotation;
|
||||
@@ -489,11 +489,6 @@ void handle_mesh_save_obj(void*);
|
||||
void handle_mesh_load_obj(void*);
|
||||
void handle_morph_save_obj(void*);
|
||||
void handle_morph_load_obj(void*);
|
||||
void save_avatar_to_obj(LLVOAvatar *avatar);
|
||||
void save_selected_avatar_to_obj();
|
||||
void save_selected_objects_to_obj();
|
||||
void save_wavefront_continued(WavefrontSaver* wfsaver, AIFilePicker* filepicker);
|
||||
void handle_save_current_avatar_obj(void*);
|
||||
void handle_debug_avatar_textures(void*);
|
||||
void handle_dump_region_object_cache(void*);
|
||||
|
||||
@@ -706,8 +701,6 @@ void init_menus()
|
||||
gAttachSubMenu = gMenuBarView->getChildMenuByName("Attach Object", TRUE);
|
||||
gDetachSubMenu = gMenuBarView->getChildMenuByName("Detach Object", TRUE);
|
||||
|
||||
LLMenuGL*menu;
|
||||
|
||||
// <dogmode>
|
||||
// Add in the pose stand -------------------------------------------
|
||||
/*LLMenuGL* sub = new LLMenuGL("Pose Stand...");
|
||||
@@ -722,6 +715,9 @@ void init_menus()
|
||||
sub->addChild(new LLMenuItemCallGL( "Stop Pose Stand", &handle_pose_stand_stop, NULL));
|
||||
// </dogmode> ------------------------------------------------------*/
|
||||
|
||||
// TomY TODO convert these two
|
||||
LLMenuGL*menu;
|
||||
|
||||
menu = new LLMenuGL(CLIENT_MENU_NAME);
|
||||
menu->setCanTearOff(TRUE);
|
||||
init_client_menu(menu);
|
||||
@@ -6137,24 +6133,6 @@ class LLAvatarInviteToGroup : public view_listener_t
|
||||
}
|
||||
};
|
||||
|
||||
class LLAvatarSaveAsOBJ : public view_listener_t
|
||||
{
|
||||
bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
|
||||
{
|
||||
save_selected_avatar_to_obj();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class LLSelectionSaveAsOBJ : public view_listener_t
|
||||
{
|
||||
bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
|
||||
{
|
||||
save_selected_objects_to_obj();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class LLAvatarAddFriend : public view_listener_t
|
||||
{
|
||||
bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
|
||||
@@ -8538,104 +8516,6 @@ static void handle_morph_load_obj_continued(void* data, AIFilePicker* filepicker
|
||||
morph_data->setMorphFromMesh(&mesh);
|
||||
}
|
||||
|
||||
void handle_save_current_avatar_obj(void* data)
|
||||
{
|
||||
if(gAgentAvatarp)
|
||||
save_avatar_to_obj(gAgentAvatarp);
|
||||
}
|
||||
|
||||
void save_selected_avatar_to_obj()
|
||||
{
|
||||
LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() );
|
||||
if(avatar)
|
||||
save_avatar_to_obj(avatar);
|
||||
}
|
||||
|
||||
void save_avatar_to_obj(LLVOAvatar *avatar)
|
||||
{
|
||||
std::string file_name = llformat("%s.obj", avatar->getFullname().c_str());
|
||||
std::string full_path = gDirUtilp->getExpandedFilename(LL_PATH_NONE, file_name);
|
||||
|
||||
WavefrontSaver* wfsaver = new WavefrontSaver();
|
||||
wfsaver->Add((LLVOAvatar*)avatar);
|
||||
|
||||
AIFilePicker* filepicker = AIFilePicker::create();
|
||||
filepicker->open(full_path);
|
||||
filepicker->run(boost::bind(&save_wavefront_continued, wfsaver, filepicker));
|
||||
}
|
||||
|
||||
void save_selected_objects_to_obj()
|
||||
{
|
||||
struct ff : public LLSelectedNodeFunctor
|
||||
{
|
||||
virtual bool apply(LLSelectNode* node)
|
||||
{
|
||||
return LLObjectBackup::getInstance()->validatePerms(node->mPermissions);
|
||||
}
|
||||
} func;
|
||||
|
||||
LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
|
||||
|
||||
if(!selection)
|
||||
return;
|
||||
|
||||
if (!selection->applyToNodes(&func, false))
|
||||
{
|
||||
llwarns << "Incorrect permissions: Wavefront OBJ export aborted" << llendl;
|
||||
LLSD args;
|
||||
args["REASON"] = "Insufficient Permissions";
|
||||
LLNotificationsUtil::add("WavefrontExportFailed", args);
|
||||
return;
|
||||
}
|
||||
|
||||
std::string file_name = llformat("%s.obj", selection->getFirstNode()->mName.c_str());
|
||||
std::string full_path = gDirUtilp->getExpandedFilename(LL_PATH_NONE, file_name);
|
||||
|
||||
WavefrontSaver* wfsaver = new WavefrontSaver();
|
||||
LLSelectNode* root_one = (LLSelectNode *)*selection->root_begin();
|
||||
wfsaver->offset = -root_one->getObject()->getRenderPosition();
|
||||
for (LLObjectSelection::iterator iter = selection->begin();
|
||||
iter != selection->end(); iter++)
|
||||
{
|
||||
LLSelectNode* node = *iter;
|
||||
LLViewerObject* object = node->getObject();
|
||||
wfsaver->Add(object);
|
||||
}
|
||||
|
||||
AIFilePicker* filepicker = AIFilePicker::create();
|
||||
filepicker->open(full_path);
|
||||
filepicker->run(boost::bind(&save_wavefront_continued, wfsaver, filepicker));
|
||||
}
|
||||
|
||||
void save_wavefront_continued(WavefrontSaver* wfsaver, AIFilePicker* filepicker)
|
||||
{
|
||||
if (!filepicker->hasFilename())
|
||||
{
|
||||
llwarns << "No file; bailing" << llendl;
|
||||
return;
|
||||
}
|
||||
std::string selected_filename = filepicker->getFilename();
|
||||
LLFILE* fp = LLFile::fopen(selected_filename, "wb");
|
||||
if (!fp)
|
||||
{
|
||||
llerrs << "can't open: " << selected_filename << llendl;
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
wfsaver->saveFile(fp);
|
||||
}
|
||||
catch(int e)
|
||||
{
|
||||
llwarns << "An exception occurred while generating / saving OBJ file. Exception #" << e << llendl;
|
||||
}
|
||||
llinfos << "OBJ file saved to " << selected_filename << llendl;
|
||||
LLSD args;
|
||||
args["FILENAME"] = selected_filename;
|
||||
LLNotificationsUtil::add("WavefrontExportSuccess", args);
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
// Returns a pointer to the avatar give the UUID of the avatar OR of an attachment the avatar is wearing.
|
||||
// Returns NULL on failure.
|
||||
LLVOAvatar* find_avatar_from_object( LLViewerObject* object )
|
||||
@@ -9509,7 +9389,6 @@ void initialize_menus()
|
||||
addMenu(new LLAvatarEnableFreezeEject(), "Avatar.EnableFreezeEject");
|
||||
addMenu(new LLAvatarCopyUUID(), "Avatar.CopyUUID");
|
||||
addMenu(new LLAvatarClientUUID(), "Avatar.ClientID");
|
||||
addMenu(new LLAvatarSaveAsOBJ(), "Avatar.SaveAsOBJ");
|
||||
|
||||
// Object pie menu
|
||||
addMenu(new LLObjectOpen(), "Object.Open");
|
||||
@@ -9529,6 +9408,7 @@ void initialize_menus()
|
||||
addMenu(new LLPowerfulWizard(), "Object.Explode");
|
||||
addMenu(new LLCanIHasKillEmAll(), "Object.EnableDestroy");
|
||||
addMenu(new LLOHGOD(), "Object.EnableExplode");
|
||||
add_wave_listeners();
|
||||
// </edit>
|
||||
addMenu(new LLObjectMute(), "Object.Mute");
|
||||
addMenu(new LLObjectBuy(), "Object.Buy");
|
||||
@@ -9541,7 +9421,6 @@ void initialize_menus()
|
||||
addMenu(new LLObjectExport(), "Object.Export");
|
||||
addMenu(new LLObjectImport(), "Object.Import");
|
||||
addMenu(new LLObjectImportUpload(), "Object.ImportUpload");
|
||||
addMenu(new LLSelectionSaveAsOBJ(), "Object.SaveAsOBJ");
|
||||
|
||||
|
||||
addMenu(new LLObjectEnableOpen(), "Object.EnableOpen");
|
||||
|
||||
@@ -60,20 +60,17 @@
|
||||
<menu_item_call enabled="true" hidden="false" label="Data" mouse_opaque="true" name="Data">
|
||||
<on_click function="Object.Data" />
|
||||
</menu_item_call>
|
||||
<menu_item_call label="Export" mouse_opaque="true" name="Export">
|
||||
<on_click function="Object.Export" />
|
||||
<on_enable function="Object.EnableExport" />
|
||||
</menu_item_call>
|
||||
<menu_item_call label="Save OBJ..." mouse_opaque="true" name="Save OBJ...">
|
||||
<on_click function="Object.SaveAsOBJ" />
|
||||
<on_enable function="Object.EnableExport" />
|
||||
</menu_item_call>
|
||||
<menu_item_call enabled="true" label="Reload" mouse_opaque="true" name="Reload Textures">
|
||||
<on_click function="Object.ReloadTextures" />
|
||||
</menu_item_call>
|
||||
<menu_item_separator />
|
||||
<pie_menu label="Export >" name="Export Menu">
|
||||
<menu_item_call enabled="false" hidden="false" label="XML" mouse_opaque="true" name="ExportXML">
|
||||
<on_click function="Object.Export" />
|
||||
<on_enable function="Object.EnableExport" />
|
||||
</menu_item_call>
|
||||
<menu_item_call enabled="false" hidden="false" label="Wavefront" mouse_opaque="true" name="ExportOBJ">
|
||||
<on_click function="Object.SaveAsOBJ" />
|
||||
<on_enable function="Object.EnableExport" />
|
||||
</menu_item_call>
|
||||
</pie_menu>
|
||||
</pie_menu>
|
||||
<menu_item_call enabled="false" label="Mute" mouse_opaque="true" name="Object Mute">
|
||||
<on_click function="Object.Mute" />
|
||||
|
||||
@@ -119,4 +119,7 @@
|
||||
<on_click function="ShowFloater" userdata="appearance" />
|
||||
<on_enable function="Edit.EnableCustomizeAvatar" />
|
||||
</menu_item_call>
|
||||
<menu_item_call label="Save OBJ..." mouse_opaque="true" name="Save OBJ...">
|
||||
<on_click function="Avatar.SaveAsOBJ" />
|
||||
</menu_item_call>
|
||||
</pie_menu>
|
||||
|
||||
@@ -9638,21 +9638,17 @@ Would you like to enable announcing keys to objects in the sim?
|
||||
</notification>
|
||||
|
||||
<notification
|
||||
icon="alert.tga"
|
||||
name="WavefrontExportFailed"
|
||||
type="alert">
|
||||
Export to Wavefront OBJ file failed:
|
||||
|
||||
[REASON]
|
||||
icon="notify.tga"
|
||||
name="WavefrontExportPartial"
|
||||
type="notify">
|
||||
Unable to include [OBJECT] in export, insufficient permissions.
|
||||
</notification>
|
||||
|
||||
<notification
|
||||
icon="notify.tga"
|
||||
icon="notifytip.tga"
|
||||
name="WavefrontExportSuccess"
|
||||
type="notify">
|
||||
Object successfully exported in Wavefront OBJ format to:
|
||||
|
||||
[FILENAME]
|
||||
type="notifytip">
|
||||
Object successfully exported to: [FILENAME]
|
||||
</notification>
|
||||
|
||||
</notifications>
|
||||
|
||||
@@ -183,8 +183,8 @@
|
||||
label="Instant Message..." label_selected="Instant Message..."
|
||||
left_delta="71" mouse_opaque="true" name="Instant Message..."
|
||||
tool_tip="Instant Message (IM)" width="140" />
|
||||
<button bottom="-470" ffont="SansSerif" halign="center" height="20" label="Mute"
|
||||
label_selected="Mute" left_delta="141" mouse_opaque="true" name="Mute"
|
||||
<button bottom="-470" font="SansSerifSmall" halign="center" height="20" label="(Un)Mute"
|
||||
left_delta="141" mouse_opaque="true" name="Mute"
|
||||
width="60" />
|
||||
<button bottom="-470" font="SansSerif" halign="center" height="20" label="Invite to Group"
|
||||
label_selected="Invite to Group" left_delta="61" mouse_opaque="true"
|
||||
|
||||
Reference in New Issue
Block a user