Preparing to add mesh upload.

This commit is contained in:
Siana Gearz
2011-12-02 09:30:12 +01:00
parent aeb766ee37
commit 697dd7e929
22 changed files with 7700 additions and 453 deletions

View File

@@ -111,7 +111,7 @@ void *APR_THREAD_FUNC LLThread::staticRun(apr_thread_t *apr_threadp, void *datap
// after the LLCurl::Multi::run() function exits and we actually
// change this variable (which really SHOULD have been inside
// the critical area of the mSignal lock)].
llinfos << "LLThread::staticRun() Exiting: " << name << llendl;
lldebugs << "LLThread::staticRun() Exiting: " << name << llendl;
return NULL;
}

View File

@@ -265,7 +265,7 @@ void LLCubeMap::setMatrix(S32 stage)
if (mMatrixStage < 0) return;
//if (stage > 0)
if (stage > 0)
{
gGL.getTexUnit(stage)->activate();
}
@@ -284,17 +284,17 @@ void LLCubeMap::setMatrix(S32 stage)
gGL.loadMatrix((F32 *)trans.mMatrix);
gGL.matrixMode(LLRender::MM_MODELVIEW);
/*if (stage > 0)
if (stage > 0)
{
gGL.getTexUnit(0)->activate();
}*/
}
}
void LLCubeMap::restoreMatrix()
{
if (mMatrixStage < 0) return;
//if (mMatrixStage > 0)
if (mMatrixStage > 0)
{
gGL.getTexUnit(mMatrixStage)->activate();
}
@@ -302,10 +302,10 @@ void LLCubeMap::restoreMatrix()
gGL.popMatrix();
gGL.matrixMode(LLRender::MM_MODELVIEW);
/*if (mMatrixStage > 0)
if (mMatrixStage > 0)
{
gGL.getTexUnit(0)->activate();
}*/
}
}
void LLCubeMap::setReflection (void)

View File

@@ -217,6 +217,7 @@ set(viewer_SOURCE_FILES
llfloatermap.cpp
llfloatermemleak.cpp
llfloatermessagelog.cpp
llfloatermodeluploadbase.cpp
llfloatermute.cpp
llfloaternamedesc.cpp
llfloaternewim.cpp
@@ -419,6 +420,7 @@ set(viewer_SOURCE_FILES
lltrans.cpp
lltranslate.cpp
lluploaddialog.cpp
lluploadfloaterobservers.cpp
llurl.cpp
llurldispatcher.cpp
llurlhistory.cpp
@@ -701,6 +703,7 @@ set(viewer_HEADER_FILES
llfloaterlandmark.h
llfloatermap.h
llfloatermemleak.h
llfloatermodeluploadbase.h
llfloatermessagelog.h
llfloatermute.h
llfloaternamedesc.h
@@ -907,6 +910,7 @@ set(viewer_HEADER_FILES
lltranslate.h
lluiconstants.h
lluploaddialog.h
lluploadfloaterobservers.h
llurl.h
llurldispatcher.h
llurlhistory.h

View File

@@ -8075,6 +8075,17 @@
<key>Value</key>
<real>0</real>
</map>
<key>MeshUploadTimeOut</key>
<map>
<key>Comment</key>
<string>Maximum time in seconds for llcurl to execute a mesh uploading request</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>S32</string>
<key>Value</key>
<real>600</real>
</map>
<key>MeshUploadFakeErrors</key>
<map>
<key>Comment</key>

View File

@@ -4163,8 +4163,6 @@ static F32 CheckMessagesMaxTime = CHECK_MESSAGES_DEFAULT_MAX_TIME;
void LLAppViewer::idleNetwork()
{
pingMainloopTimeout("idleNetwork");
LLError::LLCallStacks::clear() ;
llpushcallstacks ;
gObjectList.mNumNewObjects = 0;
S32 total_decoded = 0;
@@ -4259,15 +4257,14 @@ void LLAppViewer::idleNetwork()
{
LLUUID this_region_id = agent_region->getRegionID();
bool this_region_alive = agent_region->isAlive();
if ((mAgentRegionLastAlive && !this_region_alive) // newly dead
&& (mAgentRegionLastID == this_region_id)) // same region
if (mAgentRegionLastAlive && !this_region_alive // newly dead
&& mAgentRegionLastID == this_region_id) // same region
{
forceDisconnect(LLTrans::getString("AgentLostConnection"));
}
mAgentRegionLastID = this_region_id;
mAgentRegionLastAlive = this_region_alive;
}
llpushcallstacks ;
}
void LLAppViewer::disconnectViewer()

File diff suppressed because it is too large Load Diff

View File

@@ -34,6 +34,16 @@
#define LL_LLASSETUPLOADRESPONDER_H
#include "llhttpclient.h"
#include "llinventory.h"
void on_new_single_inventory_upload_complete(LLAssetType::EType asset_type,
LLInventoryType::EType inventory_type,
const std::string inventory_type_string,
const LLUUID& item_folder_id,
const std::string& item_name,
const std::string& item_description,
const LLSD& server_response,
S32 upload_price);
// Abstract class for supporting asset upload
// via capabilities
@@ -66,14 +76,50 @@ public:
LLNewAgentInventoryResponder(const LLSD& post_data,
const LLUUID& vfile_id,
LLAssetType::EType asset_type);
LLNewAgentInventoryResponder(const LLSD& post_data, const std::string& file_name,
LLNewAgentInventoryResponder(const LLSD& post_data,
const std::string& file_name,
LLAssetType::EType asset_type);
virtual void error(U32 statusNum, const std::string& reason);
virtual void uploadComplete(const LLSD& content);
virtual void uploadFailure(const LLSD& content);
};
// A base class which goes through and performs some default
// actions for variable price uploads. If more specific actions
// are needed (such as different confirmation messages, etc.)
// the functions onApplicationLevelError and showConfirmationDialog.
class LLNewAgentInventoryVariablePriceResponder :
public LLHTTPClient::Responder
{
public:
LLNewAgentInventoryVariablePriceResponder(const LLUUID& vfile_id,
LLAssetType::EType asset_type,
const LLSD& inventory_info);
LLNewAgentInventoryVariablePriceResponder(const std::string& file_name,
LLAssetType::EType asset_type,
const LLSD& inventory_info);
virtual ~LLNewAgentInventoryVariablePriceResponder();
void errorWithContent(U32 statusNum,
const std::string& reason,
const LLSD& content);
void result(const LLSD& content);
virtual void onApplicationLevelError(const LLSD& error);
virtual void showConfirmationDialog(S32 upload_price,
S32 resource_cost,
const std::string& confirmation_url);
private:
class Impl;
Impl* mImpl;
};
class LLBakedUploadData;
class LLSendTexLayerResponder : public LLAssetUploadResponder
{
LOG_CLASS(LLSendTexLayerResponder);
public:
LLSendTexLayerResponder(const LLSD& post_data,
const LLUUID& vfile_id,

View File

@@ -180,12 +180,6 @@ private:
bool_func_t mCallable;
};
void doOnIdleRepeating(bool_func_t callable)
{
OnIdleCallbackRepeating* cb_functor = new OnIdleCallbackRepeating(callable);
gIdleCallbacks.addFunction(&OnIdleCallbackRepeating::onIdle,cb_functor);
}
#ifdef _DEBUG
void test1(void *data)

View File

@@ -72,7 +72,6 @@ public:
virtual void render(S32 pass = 0);
/*virtual*/ void prerender();
void renderGroupAlpha(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture = TRUE);
void renderAlpha(U32 mask);
void renderAlphaHighlight(U32 mask);

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,474 @@
/**
* @file llfloatermodelpreview.h
* @brief LLFloaterModelPreview class definition
*
* $LicenseInfo:firstyear=2004&license=viewergpl$
*
* Copyright (c) 2010, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#ifndef LL_LLFLOATERMODELPREVIEW_H
#define LL_LLFLOATERMODELPREVIEW_H
#include "llmodel.h"
#include "llquaternion.h"
#include "llthread.h"
#include "lldynamictexture.h"
#include "llfloatermodeluploadbase.h"
#include "llmeshrepository.h"
#include "llviewermenufile.h"
class LLComboBox;
class LLVOAvatar;
class LLVertexBuffer;
class LLModelPreview;
class LLFloaterModelPreview;
class daeElement;
class domProfile_COMMON;
class domInstance_geometry;
class domNode;
class domTranslate;
class domController;
typedef std::map<std::string, LLMatrix4> JointTransformMap;
typedef std::map<std::string, LLMatrix4>:: iterator JointTransformMapIt;
const S32 NUM_LOD = 4;
class LLModelLoader : public LLThread
{
public:
typedef enum
{
STARTING = 0,
READING_FILE,
CREATING_FACES,
GENERATING_VERTEX_BUFFERS,
GENERATING_LOD,
DONE,
ERROR_PARSING //basically loading failed
} eLoadState;
U32 mState;
std::string mFilename;
S32 mLod;
LLModelPreview* mPreview;
LLMatrix4 mTransform;
BOOL mFirstTransform;
LLVector3 mExtents[2];
bool mTrySLM;
std::map<daeElement*, LLPointer<LLModel> > mModel;
typedef std::vector<LLPointer<LLModel> > model_list;
model_list mModelList;
typedef std::vector<LLModelInstance> model_instance_list;
typedef std::map<LLMatrix4, model_instance_list > scene;
scene mScene;
typedef std::queue<LLPointer<LLModel> > model_queue;
//queue of models that need a physics rep
model_queue mPhysicsQ;
LLModelLoader(std::string filename, S32 lod, LLModelPreview* preview, JointTransformMap& jointMap,
std::deque<std::string>& jointsFromNodes);
~LLModelLoader() ;
virtual void run();
bool doLoadModel();
bool loadFromSLM(const std::string& filename);
void loadModelCallback();
void loadTextures() ; //called in the main thread.
void processElement(daeElement* element, bool& badElement);
std::map<std::string, LLImportMaterial> getMaterials(LLModel* model, domInstance_geometry* instance_geo);
LLImportMaterial profileToMaterial(domProfile_COMMON* material);
std::string getElementLabel(daeElement *element);
LLColor4 getDaeColor(daeElement* element);
daeElement* getChildFromElement(daeElement* pElement, std::string const & name);
bool isNodeAJoint(domNode* pNode);
void processJointNode(domNode* pNode, std::map<std::string,LLMatrix4>& jointTransforms);
void extractTranslation(domTranslate* pTranslate, LLMatrix4& transform);
void extractTranslationViaElement(daeElement* pTranslateElement, LLMatrix4& transform);
void extractTranslationViaSID(daeElement* pElement, LLMatrix4& transform);
void setLoadState(U32 state);
void buildJointToNodeMappingFromScene(daeElement* pRoot);
void processJointToNodeMapping(domNode* pNode);
void processChildJoints(domNode* pParentNode);
//map of avatar joints as named in COLLADA assets to internal joint names
std::map<std::string, std::string> mJointMap;
JointTransformMap& mJointList;
std::deque<std::string>& mJointsFromNode;
S32 mNumOfFetchingTextures ; //updated in the main thread
bool areTexturesReady() { return !mNumOfFetchingTextures; } //called in the main thread.
private:
static std::list<LLModelLoader*> sActiveLoaderList;
static bool isAlive(LLModelLoader* loader) ;
};
class LLFloaterModelPreview : public LLFloaterModelUploadBase
{
public:
class DecompRequest : public LLPhysicsDecomp::Request
{
public:
S32 mContinue;
LLPointer<LLModel> mModel;
DecompRequest(const std::string& stage, LLModel* mdl);
virtual S32 statusCallback(const char* status, S32 p1, S32 p2);
virtual void completed();
};
static LLFloaterModelPreview* sInstance;
LLFloaterModelPreview(const std::string& name);
virtual ~LLFloaterModelPreview();
virtual BOOL postBuild();
void initModelPreview();
BOOL handleMouseDown(S32 x, S32 y, MASK mask);
BOOL handleMouseUp(S32 x, S32 y, MASK mask);
BOOL handleHover(S32 x, S32 y, MASK mask);
BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
/*virtual*/ void onOpen(const LLSD& key);
static void onMouseCaptureLostModelPreview(LLMouseHandler*);
static void setUploadAmount(S32 amount) { sUploadAmount = amount; }
void setDetails(F32 x, F32 y, F32 z, F32 streaming_cost, F32 physics_cost);
static void onBrowseLOD(void* user_data);
static void onReset(void* data);
static void onUpload(void* data);
void refresh();
void loadModel(S32 lod);
void loadModel(S32 lod, const std::string& file_name, bool force_disable_slm = false);
bool isViewOptionChecked(const LLSD& userdata);
bool isViewOptionEnabled(const LLSD& userdata);
void setViewOptionEnabled(const std::string& option, bool enabled);
void enableViewOption(const std::string& option);
void disableViewOption(const std::string& option);
// shows warning message if agent has no permissions to upload model
/*virtual*/ void onPermissionsReceived(const LLSD& result);
// called when error occurs during permissions request
/*virtual*/ void setPermissonsErrorStatus(U32 status, const std::string& reason);
/*virtual*/ void onModelPhysicsFeeReceived(const LLSD& result, std::string upload_url);
void handleModelPhysicsFeeReceived();
/*virtual*/ void setModelPhysicsFeeErrorStatus(U32 status, const std::string& reason);
/*virtual*/ void onModelUploadSuccess();
/*virtual*/ void onModelUploadFailure();
protected:
friend class LLModelPreview;
friend class LLMeshFilePicker;
friend class LLPhysicsDecomp;
static void onImportScaleCommit(LLUICtrl* ctrl, void*);
static void onPelvisOffsetCommit(LLUICtrl* ctrl, void*);
static void onUploadJointsCommit(LLUICtrl* ctrl, void*);
static void onUploadSkinCommit(LLUICtrl* ctrl, void*);
static void onPreviewLODCommit(LLUICtrl* ctrl, void*);
static void onGenerateNormalsCommit(LLUICtrl* ctrl, void*);
static void toggleGenerateNormals(LLUICtrl* ctrl, void*);
static void onAutoFillCommit(LLUICtrl* ctrl, void*);
static void toggleCalculateButtonCallBack(LLUICtrl* ctrl, void* userdata);
static void onClickCalculateBtn(void* userdata);
static void onLoDSourceCommit(LLUICtrl* ctrl, void* userdata);
static void onViewOptionChecked(LLUICtrl* ctrl, void* userdata);
static void onLODParamCommit(LLUICtrl* ctrl, void* userdata);
static void onLODParamCommitEnforceTriLimit(LLUICtrl* ctrl, void* userdata);
static void onExplodeCommit(LLUICtrl* ctrl, void*);
static void onPhysicsParamCommit(LLUICtrl* ctrl, void* userdata);
static void onPhysicsStageExecute(LLUICtrl* ctrl, void* userdata);
static void onCancel(LLUICtrl* ctrl, void* userdata);
static void onPhysicsStageCancel(LLUICtrl* ctrl, void* userdata);
static void onPhysicsBrowse(LLUICtrl* ctrl, void* userdata);
static void onPhysicsUseLOD(LLUICtrl* ctrl, void* userdata);
static void onPhysicsOptimize(LLUICtrl* ctrl, void* userdata);
static void onPhysicsDecomposeBack(LLUICtrl* ctrl, void* userdata);
static void onPhysicsSimplifyBack(LLUICtrl* ctrl, void* userdata);
void draw();
void initDecompControls();
void setStatusMessage(const std::string& msg);
LLModelPreview* mModelPreview;
LLPhysicsDecomp::decomp_params mDecompParams;
S32 mLastMouseX;
S32 mLastMouseY;
LLRect mPreviewRect;
U32 mGLName;
static S32 sUploadAmount;
std::set<LLPointer<DecompRequest> > mCurRequest;
std::string mStatusMessage;
//use "disabled" as false by default
std::map<std::string, bool> mViewOptionDisabled;
//store which lod mode each LOD is using
// 0 - load from file
// 1 - auto generate
// 2 - use LoD above
S32 mLODMode[4];
LLMutex* mStatusLock;
LLSD mModelPhysicsFee;
private:
// Toggles between "Calculate weights & fee" and "Upload" buttons.
void toggleCalculateButton(bool visible);
// resets display options of model preview to their defaults.
void resetDisplayOptions();
void createSmoothComboBox(LLComboBox* combo_box, float min, float max);
LLButton* mUploadBtn;
LLButton* mCalculateBtn;
};
class LLMeshFilePicker : public LLFilePickerThread
{
public:
LLMeshFilePicker(LLModelPreview* mp, S32 lod);
virtual void notify(const std::string& filename);
private:
LLModelPreview* mMP;
S32 mLOD;
};
class LLModelPreview : public LLViewerDynamicTexture, public LLMutex
{
typedef boost::signals2::signal<void (F32 x, F32 y, F32 z, F32 streaming_cost, F32 physics_cost)> details_signal_t;
typedef boost::signals2::signal<void (void)> model_loaded_signal_t;
typedef boost::signals2::signal<void (bool)> model_updated_signal_t;
public:
LLModelPreview(S32 width, S32 height, LLFloater* fmp);
virtual ~LLModelPreview();
void resetPreviewTarget();
void setPreviewTarget(F32 distance);
void setTexture(U32 name) { mTextureName = name; }
void setPhysicsFromLOD(S32 lod);
BOOL render();
void update();
void genBuffers(S32 lod, bool skinned);
void clearBuffers();
void refresh();
void rotate(F32 yaw_radians, F32 pitch_radians);
void zoom(F32 zoom_amt);
void pan(F32 right, F32 up);
virtual BOOL needsRender() { return mNeedsUpdate; }
void setPreviewLOD(S32 lod);
void clearModel(S32 lod);
void loadModel(std::string filename, S32 lod, bool force_disable_slm = false);
void loadModelCallback(S32 lod);
void genLODs(S32 which_lod = -1, U32 decimation = 3, bool enforce_tri_limit = false);
void generateNormals();
U32 calcResourceCost();
void rebuildUploadData();
void saveUploadData(bool save_skinweights, bool save_joint_poisitions);
void saveUploadData(const std::string& filename, bool save_skinweights, bool save_joint_poisitions);
void clearIncompatible(S32 lod);
void updateStatusMessages();
void updateLodControls(S32 lod);
void clearGLODGroup();
void onLODParamCommit(S32 lod, bool enforce_tri_limit);
void addEmptyFace(LLModel* pTarget);
const bool getModelPivot(void) const { return mHasPivot; }
void setHasPivot(bool val) { mHasPivot = val; }
void setModelPivot(const LLVector3& pivot) { mModelPivot = pivot; }
//Determines the viability of an asset to be used as an avatar rig (w or w/o joint upload caps)
void critiqueRigForUploadApplicability(const std::vector<std::string> &jointListFromAsset);
void critiqueJointToNodeMappingFromScene(void);
//Is a rig valid so that it can be used as a criteria for allowing for uploading of joint positions
//Accessors for joint position upload friendly rigs
const bool isRigValidForJointPositionUpload(void) const { return mRigValidJointUpload; }
void setRigValidForJointPositionUpload(bool rigValid) { mRigValidJointUpload = rigValid; }
bool isRigSuitableForJointPositionUpload(const std::vector<std::string> &jointListFromAsset);
//Determines if a rig is a legacy from the joint list
bool isRigLegacy(const std::vector<std::string> &jointListFromAsset);
//Accessors for the legacy rigs
const bool isLegacyRigValid(void) const { return mLegacyRigValid; }
void setLegacyRigValid(bool rigValid) { mLegacyRigValid = rigValid; }
//Verify that a controller matches vertex counts
bool verifyController(domController* pController);
static void textureLoadedCallback(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* userdata);
boost::signals2::connection setDetailsCallback(const details_signal_t::slot_type& cb){ return mDetailsSignal.connect(cb); }
boost::signals2::connection setModelLoadedCallback(const model_loaded_signal_t::slot_type& cb){ return mModelLoadedSignal.connect(cb); }
boost::signals2::connection setModelUpdatedCallback(const model_updated_signal_t::slot_type& cb){ return mModelUpdatedSignal.connect(cb); }
void setLoadState(U32 state) { mLoadState = state; }
U32 getLoadState() { return mLoadState; }
void setRigWithSceneParity(bool state) { mRigParityWithScene = state; }
const bool getRigWithSceneParity(void) const { return mRigParityWithScene; }
LLVector3 getTranslationForJointOffset(std::string joint);
private:
//Utility function for controller vertex compare
bool verifyCount(int expected, int result);
//Creates the dummy avatar for the preview window
void createPreviewAvatar(void);
//Accessor for the dummy avatar
LLVOAvatar* getPreviewAvatar(void) { return mPreviewAvatar; }
protected:
friend class LLModelLoader;
friend class LLFloaterModelPreview;
friend class LLFloaterModelPreview::DecompRequest;
friend class LLPhysicsDecomp;
LLFloater* mFMP;
BOOL mNeedsUpdate;
bool mDirty;
bool mGenLOD;
U32 mTextureName;
F32 mCameraDistance;
F32 mCameraYaw;
F32 mCameraPitch;
F32 mCameraZoom;
LLVector3 mCameraOffset;
LLVector3 mPreviewTarget;
LLVector3 mPreviewScale;
S32 mPreviewLOD;
U32 mResourceCost;
std::string mLODFile[LLModel::NUM_LODS];
bool mLoading;
U32 mLoadState;
bool mResetJoints;
bool mRigParityWithScene;
std::map<std::string, bool> mViewOption;
//GLOD object parameters (must rebuild object if these change)
bool mLODFrozen;
F32 mBuildShareTolerance;
U32 mBuildQueueMode;
U32 mBuildOperator;
U32 mBuildBorderMode;
U32 mRequestedLoDMode[LLModel::NUM_LODS];
S32 mRequestedTriangleCount[LLModel::NUM_LODS];
F32 mRequestedErrorThreshold[LLModel::NUM_LODS];
U32 mRequestedBuildOperator[LLModel::NUM_LODS];
U32 mRequestedQueueMode[LLModel::NUM_LODS];
U32 mRequestedBorderMode[LLModel::NUM_LODS];
F32 mRequestedShareTolerance[LLModel::NUM_LODS];
F32 mRequestedCreaseAngle[LLModel::NUM_LODS];
LLModelLoader* mModelLoader;
LLModelLoader::scene mScene[LLModel::NUM_LODS];
LLModelLoader::scene mBaseScene;
LLModelLoader::model_list mModel[LLModel::NUM_LODS];
LLModelLoader::model_list mBaseModel;
U32 mGroup;
std::map<LLPointer<LLModel>, U32> mObject;
U32 mMaxTriangleLimit;
LLMeshUploadThread::instance_list mUploadData;
std::set<LLViewerFetchedTexture* > mTextureSet;
//map of vertex buffers to models (one vertex buffer in vector per face in model
std::map<LLModel*, std::vector<LLPointer<LLVertexBuffer> > > mVertexBuffer[LLModel::NUM_LODS+1];
details_signal_t mDetailsSignal;
model_loaded_signal_t mModelLoadedSignal;
model_updated_signal_t mModelUpdatedSignal;
LLVector3 mModelPivot;
bool mHasPivot;
float mPelvisZOffset;
bool mRigValidJointUpload;
bool mLegacyRigValid;
bool mLastJointUpdate;
std::deque<std::string> mMasterJointList;
std::deque<std::string> mMasterLegacyJointList;
std::deque<std::string> mJointsFromNode;
JointTransformMap mJointTransformMap;
LLPointer<LLVOAvatar> mPreviewAvatar;
};
#endif // LL_LLFLOATERMODELPREVIEW_H

View File

@@ -0,0 +1,66 @@
/**
* @file llfloatermodeluploadbase.cpp
* @brief LLFloaterUploadModelBase class definition
*
* $LicenseInfo:firstyear=2011&license=viewergpl$
*
* Copyright (c) 2011, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "llfloatermodeluploadbase.h"
#include "llnotifications.h"
#include "llagent.h"
#include "llviewerregion.h"
LLFloaterModelUploadBase::LLFloaterModelUploadBase(const LLSD& key)
: LLFloater(key),
mHasUploadPerm(false)
{
}
void LLFloaterModelUploadBase::requestAgentUploadPermissions()
{
std::string capability = "MeshUploadFlag";
std::string url = gAgent.getRegion()->getCapability(capability);
if (!url.empty())
{
llinfos<< typeid(*this).name() <<"::requestAgentUploadPermissions() requesting for upload model permissions from: "<< url <<llendl;
LLHTTPClient::get(url, new LLUploadModelPremissionsResponder(getPermObserverHandle()));
}
else
{
LLSD args;
args["CAPABILITY"] = capability;
LLNotifications::instance().add("RegionCapabilityRequestError", args);
// BAP HACK avoid being blocked by broken server side stuff
mHasUploadPerm = true;
}
}

View File

@@ -0,0 +1,69 @@
/**
* @file llfloatermodeluploadbase.h
* @brief LLFloaterUploadModelBase class declaration
*
* $LicenseInfo:firstyear=2011&license=viewergpl$
*
* Copyright (c) 2011, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#ifndef LL_LLFLOATERMODELUPLOADBASE_H
#define LL_LLFLOATERMODELUPLOADBASE_H
#include "lluploadfloaterobservers.h"
class LLFloaterModelUploadBase
: public LLFloater,
public LLUploadPermissionsObserver,
public LLWholeModelFeeObserver,
public LLWholeModelUploadObserver
{
public:
LLFloaterModelUploadBase(const LLSD& key);
virtual ~LLFloaterModelUploadBase(){};
virtual void setPermissonsErrorStatus(U32 status, const std::string& reason) = 0;
virtual void onPermissionsReceived(const LLSD& result) = 0;
virtual void onModelPhysicsFeeReceived(const LLSD& result, std::string upload_url) = 0;
virtual void setModelPhysicsFeeErrorStatus(U32 status, const std::string& reason) = 0;
virtual void onModelUploadSuccess() {};
virtual void onModelUploadFailure() {};
protected:
// requests agent's permissions to upload model
void requestAgentUploadPermissions();
std::string mUploadModelUrl;
bool mHasUploadPerm;
};
#endif /* LL_LLFLOATERMODELUPLOADBASE_H */

View File

@@ -52,6 +52,7 @@
#include "llthread.h"
#include "llvfile.h"
#include "llviewercontrol.h"
#include "llviewerinventory.h"
#include "llviewermenufile.h"
#include "llviewerobjectlist.h"
#include "llviewerregion.h"
@@ -130,7 +131,7 @@ U32 get_volume_memory_size(const LLVolume* volume)
}
return indices*2+vertices*11+sizeof(LLVolume)+sizeof(LLVolumeFace)*volume->getNumVolumeFaces();
return indices * 2 + vertices * 11 + sizeof(LLVolume) + sizeof(LLVolumeFace) * volume->getNumVolumeFaces();
}
void get_vertex_buffer_from_mesh(LLCDMeshData& mesh, LLModel::PhysicsMesh& res, F32 scale = 1.f)
@@ -492,7 +493,7 @@ void LLMeshRepoThread::run()
static F32 last_hundred = gFrameTimeSeconds;
if (gFrameTimeSeconds - last_hundred > 1.f)
{ //a second has gone by, clear count
{ //a second has gone by, clear count
last_hundred = gFrameTimeSeconds;
count = 0;
}
@@ -527,7 +528,7 @@ void LLMeshRepoThread::run()
}
}
{ //mSkinRequests is protected by mSignal
{ //mSkinRequests is protected by mSignal
std::set<LLUUID> incomplete;
for (std::set<LLUUID>::iterator iter = mSkinRequests.begin(); iter != mSkinRequests.end(); ++iter)
{
@@ -540,7 +541,7 @@ void LLMeshRepoThread::run()
mSkinRequests = incomplete;
}
{ //mDecompositionRequests is protected by mSignal
{ //mDecompositionRequests is protected by mSignal
std::set<LLUUID> incomplete;
for (std::set<LLUUID>::iterator iter = mDecompositionRequests.begin(); iter != mDecompositionRequests.end(); ++iter)
{
@@ -553,7 +554,7 @@ void LLMeshRepoThread::run()
mDecompositionRequests = incomplete;
}
{ //mPhysicsShapeRequests is protected by mSignal
{ //mPhysicsShapeRequests is protected by mSignal
std::set<LLUUID> incomplete;
for (std::set<LLUUID>::iterator iter = mPhysicsShapeRequests.begin(); iter != mPhysicsShapeRequests.end(); ++iter)
{
@@ -571,7 +572,7 @@ void LLMeshRepoThread::run()
}
if (mSignal->isLocked())
{ //make sure to let go of the mutex associated with the given signal before shutting down
{ //make sure to let go of the mutex associated with the given signal before shutting down
mSignal->unlock();
}
@@ -622,12 +623,12 @@ void LLMeshRepoThread::loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod)
pending_lod_map::iterator pending = mPendingLOD.find(mesh_params);
if (pending != mPendingLOD.end())
{ //append this lod request to existing header request
{ //append this lod request to existing header request
pending->second.push_back(lod);
llassert(pending->second.size() <= LLModel::NUM_LODS)
}
else
{ //if no header request is pending, fetch header
{ //if no header request is pending, fetch header
LLMutexLock lock(mMutex);
mHeaderReqQ.push(req);
mPendingLOD[mesh_params].push_back(lod);
@@ -659,11 +660,11 @@ std::string LLMeshRepoThread::constructUrl(LLUUID mesh_id)
}
bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id)
{ //protected by mMutex
{ //protected by mMutex
mHeaderMutex->lock();
if (mMeshHeader.find(mesh_id) == mMeshHeader.end())
{ //we have no header info for this mesh, do nothing
{ //we have no header info for this mesh, do nothing
mHeaderMutex->unlock();
return false;
}
@@ -697,7 +698,7 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id)
}
if (!zero)
{ //attempt to parse
{ //attempt to parse
if (skinInfoReceived(mesh_id, buffer, size))
{
delete[] buffer;
@@ -732,11 +733,11 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id)
}
bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id)
{ //protected by mMutex
{ //protected by mMutex
mHeaderMutex->lock();
if (mMeshHeader.find(mesh_id) == mMeshHeader.end())
{ //we have no header info for this mesh, do nothing
{ //we have no header info for this mesh, do nothing
mHeaderMutex->unlock();
return false;
}
@@ -770,7 +771,7 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id)
}
if (!zero)
{ //attempt to parse
{ //attempt to parse
if (decompositionReceived(mesh_id, buffer, size))
{
delete[] buffer;
@@ -805,11 +806,11 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id)
}
bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id)
{ //protected by mMutex
{ //protected by mMutex
mHeaderMutex->lock();
if (mMeshHeader.find(mesh_id) == mMeshHeader.end())
{ //we have no header info for this mesh, do nothing
{ //we have no header info for this mesh, do nothing
mHeaderMutex->unlock();
return false;
}
@@ -843,7 +844,7 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id)
}
if (!zero)
{ //attempt to parse
{ //attempt to parse
if (physicsShapeReceived(mesh_id, buffer, size))
{
delete[] buffer;
@@ -868,7 +869,7 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id)
}
}
else
{ //no physics shape whatsoever, report back NULL
{ //no physics shape whatsoever, report back NULL
physicsShapeReceived(mesh_id, NULL, 0);
}
}
@@ -898,7 +899,7 @@ bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params)
LLMeshRepository::sCacheBytesRead += bytes;
file.read(buffer, bytes);
if (headerReceived(mesh_params, buffer, bytes))
{ //did not do an HTTP request, return false
{ //did not do an HTTP request, return false
return false;
}
}
@@ -924,7 +925,7 @@ bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params)
}
bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod)
{ //protected by mMutex
{ //protected by mMutex
mHeaderMutex->lock();
bool retval = false;
@@ -960,7 +961,7 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod)
}
if (!zero)
{ //attempt to parse
{ //attempt to parse
if (lodReceived(mesh_params, lod, buffer, size))
{
delete[] buffer;
@@ -1144,7 +1145,7 @@ bool LLMeshRepoThread::physicsShapeReceived(const LLUUID& mesh_id, U8* data, S32
d->mMeshID = mesh_id;
if (data == NULL)
{ //no data, no physics shape exists
{ //no data, no physics shape exists
d->mPhysicsShapeMesh.clear();
}
else
@@ -1258,7 +1259,8 @@ void LLMeshUploadThread::DecompRequest::completed()
void LLMeshUploadThread::preStart()
{
//build map of LLModel refs to instances for callbacks
for (instance_list::iterator iter = mInstanceList.begin(); iter != mInstanceList.end(); ++iter)
for (instance_list::iterator iter = mInstanceList.begin();
iter != mInstanceList.end(); ++iter)
{
mInstance[iter->mModel].push_back(*iter);
}
@@ -1620,7 +1622,7 @@ void LLMeshRepoThread::notifyLoadedMeshes()
else
{
gMeshRepo.notifyMeshUnavailable(mesh.mMeshParams,
LLVolumeLODGroup::getVolumeDetailFromScale(mesh.mVolume->getDetail()));
LLVolumeLODGroup::getVolumeDetailFromScale(mesh.mVolume->getDetail()));
}
}
@@ -1648,7 +1650,7 @@ void LLMeshRepoThread::notifyLoadedMeshes()
}
S32 LLMeshRepoThread::getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lod)
{ //only ever called from main thread
{ //only ever called from main thread
LLMutexLock lock(mHeaderMutex);
mesh_header_map::iterator iter = mMeshHeader.find(mesh_params.getSculptID());
@@ -1716,7 +1718,8 @@ void LLMeshRepository::cacheOutgoingMesh(LLMeshUploadData& data, LLSD& header)
{
if (data.mModel[i].notNull())
{
LLPointer<LLVolume> volume = new LLVolume(volume_params, LLVolumeLODGroup::getVolumeScaleFromDetail(i));
LLPointer<LLVolume> volume = new LLVolume(volume_params,
LLVolumeLODGroup::getVolumeScaleFromDetail(i));
volume->copyVolumeFaces(data.mModel[i]);
volume->setMeshAssetLoaded(TRUE);
}
@@ -1741,7 +1744,7 @@ void LLMeshLODResponder::completedRaw(U32 status, const std::string& reason,
if (data_size < (S32)mRequestedBytes)
{
if (status == 499 || status == 503)
{ //timeout or service unavailable, try again
{ //timeout or service unavailable, try again
LLMeshRepository::sHTTPRetryCount++;
gMeshRepo.mThread->loadMeshLOD(mMeshParams, mLOD);
}
@@ -1795,7 +1798,7 @@ void LLMeshSkinInfoResponder::completedRaw(U32 status, const std::string& reason
if (data_size < (S32)mRequestedBytes)
{
if (status == 499 || status == 503)
{ //timeout or service unavailable, try again
{ //timeout or service unavailable, try again
LLMeshRepository::sHTTPRetryCount++;
gMeshRepo.mThread->loadMeshSkinInfo(mMeshID);
}
@@ -1849,7 +1852,7 @@ void LLMeshDecompositionResponder::completedRaw(U32 status, const std::string& r
if (data_size < (S32)mRequestedBytes)
{
if (status == 499 || status == 503)
{ //timeout or service unavailable, try again
{ //timeout or service unavailable, try again
LLMeshRepository::sHTTPRetryCount++;
gMeshRepo.mThread->loadMeshDecomposition(mMeshID);
}
@@ -1903,7 +1906,7 @@ void LLMeshPhysicsShapeResponder::completedRaw(U32 status, const std::string& re
if (data_size < (S32)mRequestedBytes)
{
if (status == 499 || status == 503)
{ //timeout or service unavailable, try again
{ //timeout or service unavailable, try again
LLMeshRepository::sHTTPRetryCount++;
gMeshRepo.mThread->loadMeshPhysicsShape(mMeshID);
}
@@ -1961,7 +1964,7 @@ void LLMeshHeaderResponder::completedRaw(U32 status, const std::string& reason,
// and (somewhat more optional than the others) retries
// again after some set period of time
if (status == 503 || status == 499)
{ //retry
{ //retry
LLMeshRepository::sHTTPRetryCount++;
LLMeshRepoThread::HeaderRequest req(mMeshParams);
LLMutexLock lock(gMeshRepo.mThread->mMutex);
@@ -2071,7 +2074,7 @@ void LLMeshRepository::init()
mDecompThread->start();
while (!mDecompThread->mInited)
{ //wait for physics decomp thread to init
{ //wait for physics decomp thread to init
apr_sleep(100);
}
@@ -2169,7 +2172,7 @@ S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_para
//add volume to list of loading meshes
mesh_load_map::iterator iter = mLoadingMeshes[detail].find(mesh_params);
if (iter != mLoadingMeshes[detail].end())
{ //request pending for this mesh, append volume id to list
{ //request pending for this mesh, append volume id to list
iter->second.insert(vobj->getID());
}
else
@@ -2464,11 +2467,11 @@ void LLMeshRepository::notifyDecompositionReceived(LLModel::Decomposition* decom
{
decomposition_map::iterator iter = mDecompositionMap.find(decomp->mMeshID);
if (iter == mDecompositionMap.end())
{ //just insert decomp into map
{ //just insert decomp into map
mDecompositionMap[decomp->mMeshID] = decomp;
}
else
{ //merge decomp with existing entry
{ //merge decomp with existing entry
iter->second->merge(decomp);
delete decomp;
}
@@ -2477,7 +2480,7 @@ void LLMeshRepository::notifyDecompositionReceived(LLModel::Decomposition* decom
}
void LLMeshRepository::notifyMeshLoaded(const LLVolumeParams& mesh_params, LLVolume* volume)
{ //called from main thread
{ //called from main thread
S32 detail = LLVolumeLODGroup::getVolumeDetailFromScale(volume->getDetail());
//get list of objects waiting to be notified this mesh is loaded
@@ -2520,7 +2523,7 @@ void LLMeshRepository::notifyMeshLoaded(const LLVolumeParams& mesh_params, LLVol
}
void LLMeshRepository::notifyMeshUnavailable(const LLVolumeParams& mesh_params, S32 lod)
{ //called from main thread
{ //called from main thread
//get list of objects waiting to be notified this mesh is loaded
mesh_load_map::iterator obj_iter = mLoadingMeshes[lod].find(mesh_params);
@@ -2538,7 +2541,7 @@ void LLMeshRepository::notifyMeshUnavailable(const LLVolumeParams& mesh_params,
if (obj_volume &&
obj_volume->getDetail() == detail &&
obj_volume->getParams() == mesh_params)
{ //should force volume to find most appropriate LOD
{ //should force volume to find most appropriate LOD
vobj->setVolume(obj_volume->getParams(), lod);
}
}
@@ -2597,7 +2600,7 @@ void LLMeshRepository::fetchPhysicsShape(const LLUUID& mesh_id)
//add volume to list of loading meshes
std::set<LLUUID>::iterator iter = mLoadingPhysicsShapes.find(mesh_id);
if (iter == mLoadingPhysicsShapes.end())
{ //no request pending for this skin info
{ //no request pending for this skin info
mLoadingPhysicsShapes.insert(mesh_id);
mPendingPhysicsShapeRequests.push(mesh_id);
}
@@ -2625,7 +2628,7 @@ LLModel::Decomposition* LLMeshRepository::getDecomposition(const LLUUID& mesh_id
//add volume to list of loading meshes
std::set<LLUUID>::iterator iter = mLoadingDecompositions.find(mesh_id);
if (iter == mLoadingDecompositions.end())
{ //no request pending for this skin info
{ //no request pending for this skin info
mLoadingDecompositions.insert(mesh_id);
mPendingDecompositionRequests.push(mesh_id);
}
@@ -2918,7 +2921,7 @@ F32 LLMeshRepository::getStreamingCost(LLSD& header, F32 radius, S32* bytes, S32
LLPhysicsDecomp::LLPhysicsDecomp()
: LLThread("Physics Decomp")
: LLThread("Physics Decomp")
{
mInited = false;
mQuitting = false;
@@ -3044,7 +3047,7 @@ void LLPhysicsDecomp::doDecomposition()
const LLCDParam* param = param_map[name];
if (param == NULL)
{ //couldn't find valid parameter
{ //couldn't find valid parameter
continue;
}
@@ -3055,7 +3058,7 @@ void LLPhysicsDecomp::doDecomposition()
ret = LLConvexDecomposition::getInstance()->setParam(param->mName, (F32) value.asReal());
}
else if (param->mType == LLCDParam::LLCD_INTEGER ||
param->mType == LLCDParam::LLCD_ENUM)
param->mType == LLCDParam::LLCD_ENUM)
{
ret = LLConvexDecomposition::getInstance()->setParam(param->mName, value.asInteger());
}
@@ -3260,6 +3263,7 @@ void LLPhysicsDecomp::doDecompositionSingleHull()
{
decomp->setParam(params[i].mName, params[i].mDefault.mIntOrEnumValue);
}
#endif
const S32 STAGE_DECOMPOSE = mStageID["Decompose"];
const S32 STAGE_SIMPLIFY = mStageID["Simplify"];
@@ -3565,7 +3569,7 @@ void LLMeshRepository::buildPhysicsMesh(LLModel::Decomposition& decomp)
}
if (!decomp.mBaseHull.empty() && decomp.mBaseHullMesh.empty())
{ //get mesh for base hull
{ //get mesh for base hull
LLCDHull hull;
hull.mNumVertices = decomp.mBaseHull.size();
hull.mVertexBase = decomp.mBaseHull[0].mV;
@@ -3608,5 +3612,4 @@ bool LLMeshRepository::meshRezEnabled()
}
return false;
}
#endif //MESH_ENABLED

View File

@@ -128,7 +128,7 @@ public:
LLImportMaterial()
: mFullbright(false)
{
mDiffuseColor.set(1,1,1,1);
mDiffuseColor.set(1, 1, 1, 1);
}
LLImportMaterial(LLSD& data);
@@ -246,10 +246,10 @@ public:
static S32 sActiveLODRequests;
static U32 sMaxConcurrentRequests;
LLCurlRequest* mCurlRequest;
LLMutex* mMutex;
LLMutex* mHeaderMutex;
LLCondition* mSignal;
LLCurlRequest* mCurlRequest;
LLMutex* mMutex;
LLMutex* mHeaderMutex;
LLCondition* mSignal;
bool mWaiting;
@@ -464,6 +464,9 @@ private:
class LLMeshRepository
{
private:
S32 mMeshUploadTimeOut ; //maximum time in seconds to execute an uploading request.
public:
//metrics
@@ -587,4 +590,3 @@ public:
extern LLMeshRepository gMeshRepo;
#endif

View File

@@ -0,0 +1,63 @@
/**
* @file lluploadfloaterobservers.cpp
* @brief LLUploadModelPremissionsResponder definition
*
* $LicenseInfo:firstyear=2011&license=viewergpl$
*
* Copyright (c) 2011, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "lluploadfloaterobservers.h"
LLUploadModelPremissionsResponder::LLUploadModelPremissionsResponder(const LLHandle<LLUploadPermissionsObserver>& observer)
: mObserverHandle(observer)
{
}
void LLUploadModelPremissionsResponder::error(U32 status, const std::string& reason)
{
llwarns << "LLUploadModelPremissionsResponder::error("
<< status << ": " << reason << ")" << llendl;
LLUploadPermissionsObserver* observer = mObserverHandle.get();
if (observer)
{
observer->setPermissonsErrorStatus(status, reason);
}
}
void LLUploadModelPremissionsResponder::result(const LLSD& content)
{
LLUploadPermissionsObserver* observer = mObserverHandle.get();
if (observer)
{
observer->onPermissionsReceived(content);
}
}

View File

@@ -0,0 +1,112 @@
/**
* @file lluploadfloaterobservers.h
* @brief LLUploadModelPremissionsResponder declaration
*
* $LicenseInfo:firstyear=2011&license=viewergpl$
*
* Copyright (c) 2011, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#ifndef LL_LLUPLOADFLOATEROBSERVERS_H
#define LL_LLUPLOADFLOATEROBSERVERS_H
#include "llfloater.h"
#include "llhttpclient.h"
#include "llui.h"
class LLUploadPermissionsObserver
{
public:
LLUploadPermissionsObserver() { mUploadPermObserverHandle.bind(this); }
virtual ~LLUploadPermissionsObserver() {}
virtual void onPermissionsReceived(const LLSD& result) = 0;
virtual void setPermissonsErrorStatus(U32 status, const std::string& reason) = 0;
LLHandle<LLUploadPermissionsObserver> getPermObserverHandle() const
{
return mUploadPermObserverHandle;
}
protected:
LLRootHandle<LLUploadPermissionsObserver> mUploadPermObserverHandle;
};
class LLWholeModelFeeObserver
{
public:
LLWholeModelFeeObserver() { mWholeModelFeeObserverHandle.bind(this); }
virtual ~LLWholeModelFeeObserver() {}
virtual void onModelPhysicsFeeReceived(const LLSD& result, std::string upload_url) = 0;
virtual void setModelPhysicsFeeErrorStatus(U32 status, const std::string& reason) = 0;
LLHandle<LLWholeModelFeeObserver> getWholeModelFeeObserverHandle() const
{
return mWholeModelFeeObserverHandle;
}
protected:
LLRootHandle<LLWholeModelFeeObserver> mWholeModelFeeObserverHandle;
};
class LLWholeModelUploadObserver
{
public:
LLWholeModelUploadObserver() { mWholeModelUploadObserverHandle.bind(this); }
virtual ~LLWholeModelUploadObserver() {}
virtual void onModelUploadSuccess() = 0;
virtual void onModelUploadFailure() = 0;
LLHandle<LLWholeModelUploadObserver> getWholeModelUploadObserverHandle() const
{
return mWholeModelUploadObserverHandle;
}
protected:
LLRootHandle<LLWholeModelUploadObserver> mWholeModelUploadObserverHandle;
};
class LLUploadModelPremissionsResponder : public LLHTTPClient::Responder
{
public:
LLUploadModelPremissionsResponder(const LLHandle<LLUploadPermissionsObserver>& observer);
void error(U32 status, const std::string& reason);
void result(const LLSD& content);
private:
LLHandle<LLUploadPermissionsObserver> mObserverHandle;
};
#endif /* LL_LLUPLOADFLOATEROBSERVERS_H */

View File

@@ -8996,7 +8996,7 @@ static void handle_load_from_xml_continued(AIFilePicker* filepicker)
void handle_web_browser_test(void*)
{
LLWeb::loadURL("http://secondlife.com/app/search/slurls.html");
LLFloaterMediaBrowser::showInstance("http://secondlife.com/app/search/slurls.html");
}
void handle_buy_currency_test(void*)

View File

@@ -32,11 +32,34 @@
#include "llviewerprecompiledheaders.h"
// system libraries
#include <boost/tokenizer.hpp>
#include "llviewermenufile.h"
// linden libraries
#include "lleconomy.h"
#include "llhttpclient.h"
#include "llimage.h"
#include "llmemberlistener.h"
#include "llnotificationsutil.h"
#include "llsdserialize.h"
#include "llsdutil.h"
#include "llstring.h"
#include "lltransactiontypes.h"
#include "lluictrlfactory.h"
#include "lluuid.h"
#include "llvorbisencode.h"
#include "message.h"
// project includes
#include "llagent.h"
#include "llagentcamera.h"
#include "llappviewer.h"
#include "llassetuploadresponders.h"
#ifdef MESH_UPLOAD
#include "llfloatermodelpreview.h"
#endif
#include "llimagejpeg.h"
#include "llimagepng.h"
@@ -62,7 +85,6 @@
#include "llviewerregion.h"
#include "llviewerstats.h"
#include "llviewerwindow.h"
#include "llappviewer.h"
#include "lluploaddialog.h"
// <edit>
#include "llselectmgr.h"
@@ -72,23 +94,9 @@
#include "lllocalinventory.h"
// </edit>
#include "importtracker.h"
// linden libraries
#include "llassetuploadresponders.h"
#include "lleconomy.h"
#include "llhttpclient.h"
#include "llnotificationsutil.h"
#include "llmemberlistener.h"
#include "llsdserialize.h"
#include "llstring.h"
#include "lltransactiontypes.h"
#include "lluuid.h"
#include "llvorbisencode.h"
// system libraries
#include <boost/tokenizer.hpp>
//#include "importtracker.h"
std::deque<std::string> gUploadQueue;
typedef LLMemberListener<LLView> view_listener_t;
@@ -97,7 +105,8 @@ class LLFileEnableSaveAs : public view_listener_t
{
bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
{
bool new_value = gFloaterView->getFrontmost() && gFloaterView->getFrontmost()->canSaveAs();
bool new_value = gFloaterView->getFrontmost() &&
gFloaterView->getFrontmost()->canSaveAs();
gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
return true;
}
@@ -107,7 +116,8 @@ class LLFileEnableUpload : public view_listener_t
{
bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
{
bool new_value = gStatusBar && LLGlobalEconomy::Singleton::getInstance() && (gStatusBar->getBalance() >= LLGlobalEconomy::Singleton::getInstance()->getPriceUpload());
bool new_value = gStatusBar && LLGlobalEconomy::Singleton::getInstance() &&
gStatusBar->getBalance() >= LLGlobalEconomy::Singleton::getInstance()->getPriceUpload();
gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
return true;
}
@@ -207,7 +217,7 @@ bool AIFileUpload::is_valid(std::string const& filename, ELoadFilter type)
// No extension
LLSD args;
args["FILE"] = short_name;
LLNotificationsUtil::add("NoFileExtension", args);
LLNotifications::instance().add("NoFileExtension", args);
return false;
}
else
@@ -250,7 +260,7 @@ bool AIFileUpload::is_valid(std::string const& filename, ELoadFilter type)
LLSD args;
args["EXTENSION"] = ext;
args["VALIDS"] = valid_extensions;
LLNotificationsUtil::add("InvalidFileExtension", args);
LLNotifications::instance().add("InvalidFileExtension", args);
return false;
}
}//end else (non-null extension)
@@ -355,7 +365,7 @@ class LLFileUploadBulk : public view_listener_t
if(expected_upload_cost)
msg.append(llformat("\nWARNING: Each upload costs L$%d if it's not temporary.",expected_upload_cost));
args["MESSAGE"] = msg;
LLNotificationsUtil::add("GenericAlertYesNoCancel", args, LLSD(), onConfirmBulkUploadTemp);
LLNotifications::instance().add("GenericAlertYesNoCancel", args, LLSD(), onConfirmBulkUploadTemp);
return true;
}
@@ -640,6 +650,7 @@ void upload_new_resource(const std::string& src_filename, std::string name,
LLSD args;
std::string exten = gDirUtilp->getExtension(src_filename);
U32 codec = LLImageBase::getCodecFromExtension(exten);
LLAssetType::EType asset_type = LLAssetType::AT_NONE;
std::string error_message;
@@ -657,12 +668,11 @@ void upload_new_resource(const std::string& src_filename, std::string name,
upload_error(error_message, "NofileExtension", filename, args);
return;
}
else if( exten == "bmp")
else if (codec != IMG_CODEC_INVALID)
{
// It's an image file, the upload procedure is the same for all
asset_type = LLAssetType::AT_TEXTURE;
if (!LLViewerTextureList::createUploadFile(src_filename,
filename,
IMG_CODEC_BMP ))
if (!LLViewerTextureList::createUploadFile(src_filename, filename, codec))
{
error_message = llformat( "Problem with file %s:\n\n%s\n",
src_filename.c_str(), LLImage::getLastError().c_str());
@@ -672,51 +682,6 @@ void upload_new_resource(const std::string& src_filename, std::string name,
return;
}
}
else if( exten == "tga")
{
asset_type = LLAssetType::AT_TEXTURE;
if (!LLViewerTextureList::createUploadFile(src_filename,
filename,
IMG_CODEC_TGA ))
{
error_message = llformat("Problem with file %s:\n\n%s\n",
src_filename.c_str(), LLImage::getLastError().c_str());
args["FILE"] = src_filename;
args["ERROR"] = LLImage::getLastError();
upload_error(error_message, "ProblemWithFile", filename, args);
return;
}
}
else if( exten == "jpg" || exten == "jpeg")
{
asset_type = LLAssetType::AT_TEXTURE;
if (!LLViewerTextureList::createUploadFile(src_filename,
filename,
IMG_CODEC_JPEG ))
{
error_message = llformat("Problem with file %s:\n\n%s\n",
src_filename.c_str(), LLImage::getLastError().c_str());
args["FILE"] = src_filename;
args["ERROR"] = LLImage::getLastError();
upload_error(error_message, "ProblemWithFile", filename, args);
return;
}
}
else if( exten == "png")
{
asset_type = LLAssetType::AT_TEXTURE;
if (!LLViewerTextureList::createUploadFile(src_filename,
filename,
IMG_CODEC_PNG ))
{
error_message = llformat("Problem with file %s:\n\n%s\n",
src_filename.c_str(), LLImage::getLastError().c_str());
args["FILE"] = src_filename;
args["ERROR"] = LLImage::getLastError();
upload_error(error_message, "ProblemWithFile", filename, args);
return;
}
}
else if(exten == "wav")
{
asset_type = LLAssetType::AT_SOUND; // tag it as audio
@@ -1122,6 +1087,52 @@ void upload_done_callback(const LLUUID& uuid, void* user_data, S32 result, LLExt
data = NULL;
}
static LLAssetID upload_new_resource_prep(const LLTransactionID& tid,
LLAssetType::EType asset_type,
LLInventoryType::EType& inventory_type,
std::string& name,
const std::string& display_name,
std::string& description)
{
LLAssetID uuid = generate_asset_id_for_new_upload(tid);
increase_new_upload_stats(asset_type);
assign_defaults_and_show_upload_message(asset_type,
inventory_type,
name,
display_name,
description);
return uuid;
}
LLSD generate_new_resource_upload_capability_body(LLAssetType::EType asset_type,
const std::string& name,
const std::string& desc,
LLFolderType::EType destination_folder_type,
LLInventoryType::EType inv_type,
U32 next_owner_perms,
U32 group_perms,
U32 everyone_perms)
{
LLSD body;
body["folder_id"] = gInventory.findCategoryUUIDForType(destination_folder_type == LLFolderType::FT_NONE ?
LLFolderType::assetTypeToFolderType(asset_type) :
destination_folder_type);
body["asset_type"] = LLAssetType::lookup(asset_type);
body["inventory_type"] = LLInventoryType::lookup(inv_type);
body["name"] = name;
body["description"] = desc;
body["next_owner_mask"] = LLSD::Integer(next_owner_perms);
body["group_mask"] = LLSD::Integer(group_perms);
body["everyone_mask"] = LLSD::Integer(everyone_perms);
return body;
}
void upload_new_resource(const LLTransactionID &tid, LLAssetType::EType asset_type,
std::string name,
std::string desc, S32 compression_info,
@@ -1140,51 +1151,20 @@ void upload_new_resource(const LLTransactionID &tid, LLAssetType::EType asset_ty
return ;
}
LLAssetID uuid = tid.makeAssetID(gAgent.getSecureSessionID());
if( LLAssetType::AT_SOUND == asset_type )
{
LLViewerStats::getInstance()->incStat(LLViewerStats::ST_UPLOAD_SOUND_COUNT );
}
else
if( LLAssetType::AT_TEXTURE == asset_type )
{
LLViewerStats::getInstance()->incStat(LLViewerStats::ST_UPLOAD_TEXTURE_COUNT );
}
else
if( LLAssetType::AT_ANIMATION == asset_type)
{
LLViewerStats::getInstance()->incStat(LLViewerStats::ST_UPLOAD_ANIM_COUNT );
}
if(LLInventoryType::IT_NONE == inv_type)
{
inv_type = LLInventoryType::defaultForAssetType(asset_type);
}
LLStringUtil::stripNonprintable(name);
LLStringUtil::stripNonprintable(desc);
if(name.empty())
{
name = "(No Name)";
}
if(desc.empty())
{
desc = "(No Description)";
}
// At this point, we're ready for the upload.
std::string upload_message = "Uploading...\n\n";
upload_message.append(display_name);
LLUploadDialog::modalUploadDialog(upload_message);
LLAssetID uuid = upload_new_resource_prep(tid, asset_type, inv_type,
name, display_name, desc);
llinfos << "*** Uploading: "
<< "\nType: " << LLAssetType::lookup(asset_type)
<< "\nUUID: " << uuid
<< "\nName: " << name
<< "\nDesc: " << desc
<< "\nFolder: "
<< gInventory.findCategoryUUIDForType(destination_folder_type == LLFolderType::FT_NONE ?
LLFolderType::assetTypeToFolderType(asset_type) :
destination_folder_type)
<< "\nExpected Upload Cost: " << expected_upload_cost << llendl;
llinfos << "*** Uploading: " << llendl;
llinfos << "Type: " << LLAssetType::lookup(asset_type) << llendl;
llinfos << "UUID: " << uuid << llendl;
llinfos << "Name: " << name << llendl;
llinfos << "Desc: " << desc << llendl;
llinfos << "Expected Upload Cost: " << expected_upload_cost << llendl;
lldebugs << "Folder: " << gInventory.findCategoryUUIDForType((destination_folder_type == LLFolderType::FT_NONE) ? LLFolderType::assetTypeToFolderType(asset_type) : destination_folder_type) << llendl;
lldebugs << "Asset Type: " << LLAssetType::lookup(asset_type) << llendl;
std::string url = gAgent.getRegion()->getCapability("NewFileAgentInventory");
// <edit>
BOOL temporary = gSavedSettings.getBOOL("TemporaryUpload");
@@ -1204,11 +1184,8 @@ void upload_new_resource(const LLTransactionID &tid, LLAssetType::EType asset_ty
body["everyone_mask"] = LLSD::Integer(everyone_perms);
body["expected_upload_cost"] = LLSD::Integer(expected_upload_cost);
//std::ostringstream llsdxml;
//LLSDSerialize::toPrettyXML(body, llsdxml);
//llinfos << "posting body to capability: " << llsdxml.str() << llendl;
LLHTTPClient::post(url, body, new LLNewAgentInventoryResponder(body, uuid, asset_type));
LLHTTPClient::post(url, body,
new LLNewAgentInventoryResponder(body, uuid, asset_type));
}
else
{
@@ -1259,6 +1236,64 @@ void upload_new_resource(const LLTransactionID &tid, LLAssetType::EType asset_ty
}
}
LLAssetID generate_asset_id_for_new_upload(const LLTransactionID& tid)
{
LLAssetID uuid;
if (gDisconnected)
{
uuid.setNull();
}
else
{
uuid = tid.makeAssetID(gAgent.getSecureSessionID());
}
return uuid;
}
void increase_new_upload_stats(LLAssetType::EType asset_type)
{
if (LLAssetType::AT_SOUND == asset_type)
{
LLViewerStats::getInstance()->incStat(LLViewerStats::ST_UPLOAD_SOUND_COUNT);
}
else if (LLAssetType::AT_TEXTURE == asset_type)
{
LLViewerStats::getInstance()->incStat(LLViewerStats::ST_UPLOAD_TEXTURE_COUNT);
}
else if (LLAssetType::AT_ANIMATION == asset_type)
{
LLViewerStats::getInstance()->incStat(LLViewerStats::ST_UPLOAD_ANIM_COUNT);
}
}
void assign_defaults_and_show_upload_message(LLAssetType::EType asset_type,
LLInventoryType::EType& inventory_type,
std::string& name,
const std::string& display_name,
std::string& description)
{
if (LLInventoryType::IT_NONE == inventory_type)
{
inventory_type = LLInventoryType::defaultForAssetType(asset_type);
}
LLStringUtil::stripNonprintable(name);
LLStringUtil::stripNonprintable(description);
if (name.empty())
{
name = "(No Name)";
}
if (description.empty())
{
description = "(No Description)";
}
// At this point, we're ready for the upload.
std::string upload_message = "Uploading...\n\n";
upload_message.append(display_name);
LLUploadDialog::modalUploadDialog(upload_message);
}
void init_menu_file()
{

View File

@@ -38,6 +38,8 @@
// <edit>
#include "llviewerinventory.h"
#include "statemachine/aifilepicker.h"
class NewResourceItemCallback : public LLInventoryCallback
{
void fire(const LLUUID& inv_item);
@@ -46,36 +48,84 @@ class NewResourceItemCallback : public LLInventoryCallback
class LLTransactionID;
extern std::deque<std::string> gUploadQueue;
void init_menu_file();
void upload_new_resource(const std::string& src_filename,
std::string name,
std::string desc,
S32 compression_info,
LLFolderType::EType destination_folder_type,
LLInventoryType::EType inv_type,
U32 next_owner_perms,
U32 group_perms,
U32 everyone_perms,
const std::string& display_name,
LLAssetStorage::LLStoreAssetCallback callback,
S32 expected_upload_cost,
void *userdata);
void upload_new_resource(const std::string& src_filename,
std::string name,
std::string desc,
S32 compression_info,
LLFolderType::EType destination_folder_type,
LLInventoryType::EType inv_type,
U32 next_owner_perms,
U32 group_perms,
U32 everyone_perms,
const std::string& display_name,
LLAssetStorage::LLStoreAssetCallback callback,
S32 expected_upload_cost,
void *userdata);
void upload_new_resource(const LLTransactionID &tid,
LLAssetType::EType type,
std::string name,
std::string desc,
S32 compression_info,
LLFolderType::EType destination_folder_type,
LLInventoryType::EType inv_type,
U32 next_owner_perms,
U32 group_perms,
U32 everyone_perms,
const std::string& display_name,
LLAssetStorage::LLStoreAssetCallback callback,
S32 expected_upload_cost,
void *userdata);
LLAssetType::EType type,
std::string name,
std::string desc,
S32 compression_info,
LLFolderType::EType destination_folder_type,
LLInventoryType::EType inv_type,
U32 next_owner_perms,
U32 group_perms,
U32 everyone_perms,
const std::string& display_name,
LLAssetStorage::LLStoreAssetCallback callback,
S32 expected_upload_cost,
void *userdata);
LLAssetID generate_asset_id_for_new_upload(const LLTransactionID& tid);
void increase_new_upload_stats(LLAssetType::EType asset_type);
void assign_defaults_and_show_upload_message(LLAssetType::EType asset_type,
LLInventoryType::EType& inventory_type,
std::string& name,
const std::string& display_name,
std::string& description);
LLSD generate_new_resource_upload_capability_body(LLAssetType::EType asset_type,
const std::string& name,
const std::string& desc,
LLFolderType::EType destination_folder_type,
LLInventoryType::EType inv_type,
U32 next_owner_perms,
U32 group_perms,
U32 everyone_perms);
class LLFilePickerThread : public LLThread
{ //multi-threaded file picker (runs system specific file picker in background and calls "notify" from main thread)
public:
static std::queue<LLFilePickerThread*> sDeadQ;
static LLMutex* sMutex;
static void initClass();
static void cleanupClass();
static void clearDead();
std::string mFile;
ELoadFilter mFilter;
LLFilePickerThread(ELoadFilter filter)
: LLThread("file picker"), mFilter(filter)
{
}
void getFile();
virtual void run();
virtual void notify(const std::string& filename) = 0;
};
#endif

View File

@@ -1732,17 +1732,29 @@ std::string LLViewerRegion::getDescription() const
return stringize(*this);
}
#if MESH_ENABLED
bool LLViewerRegion::meshUploadEnabled() const
{
return (mSimulatorFeatures.has("MeshUploadEnabled") &&
mSimulatorFeatures["MeshUploadEnabled"].asBoolean());
if (getCapability("SimulatorFeatures").empty())
{
return !getCapability("MeshUploadFlag").empty();
}
else
{
return (mSimulatorFeatures.has("MeshUploadEnabled") &&
mSimulatorFeatures["MeshUploadEnabled"].asBoolean());
}
}
bool LLViewerRegion::meshRezEnabled() const
{
return (mSimulatorFeatures.has("MeshRezEnabled") &&
if (getCapability("SimulatorFeatures").empty())
{
return !getCapability("GetMesh").empty();
}
else
{
return (mSimulatorFeatures.has("MeshRezEnabled") &&
mSimulatorFeatures["MeshRezEnabled"].asBoolean());
}
}
#endif //MESH_ENABLED

View File

@@ -1607,6 +1607,17 @@ Unable to upload [FILE] due to the following reason: [REASON]
Please try again later.
</notification>
<notification
icon="alertmodal.tga"
name="UploadCostConfirmation"
type="alertmodal">
This upload will cost L$[PRICE], do you wish to continue with the upload?
<usetemplate
name="okcancelbuttons"
notext="Cancel"
yestext="Upload"/>
</notification>
<notification
icon="alertmodal.tga"
name="CannotCreateLandmarkNotOwner"
@@ -6830,6 +6841,13 @@ The region you have entered is running a different simulator version. Click this
The URL you clicked cannot be opened from this web browser.
</notification>
<notification
name="RegionCapabilityRequestError"
icon="alert.tga"
type="alert">
Could not get region capability &apos;[CAPABILITY]&apos;.
</notification>
<global name="UnsupportedCPU">
- Your CPU speed does not meet the minimum requirements.
</global>