summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/llfloatermodelpreview.cpp157
-rw-r--r--indra/newview/llfloatermodelpreview.h24
-rw-r--r--indra/newview/llmeshrepository.cpp226
-rw-r--r--indra/newview/llmeshrepository.h46
-rw-r--r--indra/newview/llvoavatar.cpp35
-rw-r--r--indra/newview/llvoavatar.h1
-rw-r--r--indra/newview/llvoavatarself.cpp22
-rw-r--r--indra/newview/llvoavatarself.h4
8 files changed, 338 insertions, 177 deletions
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index 1336043b7f..82d3a07345 100644
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -636,7 +636,15 @@ void LLFloaterModelPreview::draw()
if (mDecompFloater)
{
- mDecompFloater->childSetText("status", gMeshRepo.mDecompThread->mStatus);
+ if (mCurRequest.notNull())
+ {
+ mDecompFloater->childSetText("status", mCurRequest->mStatusMessage);
+ }
+ else
+ {
+ const std::string idle("Idle.");
+ mDecompFloater->childSetText("status", idle);
+ }
}
U32 resource_cost = mModelPreview->mResourceCost*10;
@@ -773,33 +781,16 @@ BOOL LLFloaterModelPreview::handleScrollWheel(S32 x, S32 y, S32 clicks)
//static
void LLFloaterModelPreview::onPhysicsParamCommit(LLUICtrl* ctrl, void* data)
{
- LLCDParam* param = (LLCDParam*) data;
-
- LLCDResult ret = LLCD_OK;
-
if (LLConvexDecomposition::getInstance() == NULL)
{
llinfos << "convex decomposition tool is a stub on this platform. cannot get decomp." << llendl;
return;
}
- if (param->mType == LLCDParam::LLCD_FLOAT)
- {
- ret = LLConvexDecomposition::getInstance()->setParam(param->mName, (F32) ctrl->getValue().asReal());
- }
- else if (param->mType == LLCDParam::LLCD_INTEGER ||
- param->mType == LLCDParam::LLCD_ENUM)
- {
- ret = LLConvexDecomposition::getInstance()->setParam(param->mName, ctrl->getValue().asInteger());
- }
- else if (param->mType == LLCDParam::LLCD_BOOLEAN)
- {
- ret = LLConvexDecomposition::getInstance()->setParam(param->mName, ctrl->getValue().asBoolean());
- }
-
- if (ret)
+ if (sInstance)
{
- llerrs << "WTF?" << llendl;
+ LLCDParam* param = (LLCDParam*) data;
+ sInstance->mDecompParams[param->mName] = ctrl->getValue();
}
}
@@ -812,6 +803,12 @@ void LLFloaterModelPreview::onPhysicsStageExecute(LLUICtrl* ctrl, void* data)
if (sInstance)
{
+ if (sInstance->mCurRequest.notNull())
+ {
+ llinfos << "Decomposition request still pending." << llendl;
+ return;
+ }
+
if (sInstance->mModelPreview)
{
if (sInstance->mDecompFloater)
@@ -827,14 +824,18 @@ void LLFloaterModelPreview::onPhysicsStageExecute(LLUICtrl* ctrl, void* data)
if (mdl)
{
- gMeshRepo.mDecompThread->execute(stage->mName, mdl);
+ sInstance->mCurRequest = new DecompRequest(stage->mName, mdl);
+ gMeshRepo.mDecompThread->submitRequest(sInstance->mCurRequest);
}
}
//static
void LLFloaterModelPreview::onPhysicsStageCancel(LLUICtrl* ctrl, void*data)
{
- gMeshRepo.mDecompThread->cancel();
+ if (sInstance && sInstance->mCurRequest.notNull())
+ {
+ sInstance->mCurRequest->mContinue = 0;
+ }
}
void LLFloaterModelPreview::showDecompFloater()
@@ -899,6 +900,8 @@ void LLFloaterModelPreview::showDecompFloater()
// protected against stub by stage_count being 0 for stub above
LLConvexDecomposition::getInstance()->registerCallback(j, LLPhysicsDecomp::llcdCallback);
+ llinfos << "Physics decomp stage " << j << " parameters:" << llendl;
+
for (S32 i = 0; i < param_count; ++i)
{
if (param[i].mStage != j)
@@ -909,8 +912,11 @@ void LLFloaterModelPreview::showDecompFloater()
std::string name(param[i].mName ? param[i].mName : "");
std::string description(param[i].mDescription ? param[i].mDescription : "");
+ llinfos << name << " - " << description << llendl;
+
if (param[i].mType == LLCDParam::LLCD_FLOAT)
{
+ mDecompParams[param[i].mName] = LLSD(param[i].mDefault.mFloat);
LLSliderCtrl::Params p;
p.name(name);
p.label(name);
@@ -928,6 +934,7 @@ void LLFloaterModelPreview::showDecompFloater()
}
else if (param[i].mType == LLCDParam::LLCD_INTEGER)
{
+ mDecompParams[param[i].mName] = LLSD(param[i].mDefault.mIntOrEnumValue);
LLSliderCtrl::Params p;
p.name(name);
p.label(name);
@@ -944,6 +951,7 @@ void LLFloaterModelPreview::showDecompFloater()
}
else if (param[i].mType == LLCDParam::LLCD_BOOLEAN)
{
+ mDecompParams[param[i].mName] = LLSD(param[i].mDefault.mBool);
LLCheckBoxCtrl::Params p;
p.rect(LLRect(left, cur_y, right, cur_y-20));
p.name(name);
@@ -958,7 +966,7 @@ void LLFloaterModelPreview::showDecompFloater()
else if (param[i].mType == LLCDParam::LLCD_ENUM)
{
S32 cur_x = left;
-
+ mDecompParams[param[i].mName] = LLSD(param[i].mDefault.mIntOrEnumValue);
{ //add label
LLTextBox::Params p;
const LLFontGL* font = (LLFontGL*) p.font();
@@ -2211,9 +2219,16 @@ void LLModelPreview::loadModel(std::string filename, S32 lod)
mModelLoader = NULL;
}
- if (filename.empty() && mBaseModel.empty())
+ if (filename.empty())
{
- mFMP->closeFloater(false);
+ if (mBaseModel.empty())
+ {
+ // this is the initial file picking. Close the whole floater
+ // if we don't have a base model to show for high LOD.
+ mFMP->closeFloater(false);
+ }
+
+ mFMP->mLoading = false;
return;
}
@@ -2892,9 +2907,20 @@ void LLModelPreview::genLODs(S32 which_lod)
}
}
}
-
- mResourceCost = calcResourceCost();
}
+
+ mResourceCost = calcResourceCost();
+
+ /*if (which_lod == -1 && mScene[LLModel::LOD_PHYSICS].empty())
+ { //build physics scene
+ mScene[LLModel::LOD_PHYSICS] = mScene[LLModel::LOD_LOW];
+ mModel[LLModel::LOD_PHYSICS] = mModel[LLModel::LOD_LOW];
+
+ for (U32 i = 1; i < mModel[LLModel::LOD_PHYSICS].size(); ++i)
+ {
+ mPhysicsQ.push(mModel[LLModel::LOD_PHYSICS][i]);
+ }
+ }*/
}
void LLModelPreview::updateStatusMessages()
@@ -3665,18 +3691,6 @@ void LLFloaterModelPreview::onDecompose(void* user_data)
mp->showDecompFloater();
}
-//static
-void LLFloaterModelPreview::onModelDecompositionComplete(LLModel* model, std::vector<LLPointer<LLVertexBuffer> >& physics_mesh)
-{
- if (sInstance && sInstance->mModelPreview)
- {
- sInstance->mModelPreview->mPhysicsMesh[model] = physics_mesh;
-
- sInstance->mModelPreview->mDirty = true;
- }
-}
-
-
//static
void LLFloaterModelPreview::refresh(LLUICtrl* ctrl, void* user_data)
{
@@ -3697,3 +3711,66 @@ void LLModelPreview::textureLoadedCallback( BOOL success, LLViewerFetchedTexture
preview->refresh();
}
+LLFloaterModelPreview::DecompRequest::DecompRequest(const std::string& stage, LLModel* mdl)
+{
+ mStage = stage;
+ mContinue = 1;
+ mModel = mdl;
+ mParams = sInstance->mDecompParams;
+
+ //copy out positions and indices
+ if (mdl)
+ {
+ U16 index_offset = 0;
+
+ mPositions.clear();
+ mIndices.clear();
+
+ //queue up vertex positions and indices
+ for (S32 i = 0; i < mdl->getNumVolumeFaces(); ++i)
+ {
+ const LLVolumeFace& face = mdl->getVolumeFace(i);
+ if (mPositions.size() + face.mNumVertices > 65535)
+ {
+ continue;
+ }
+
+ for (U32 j = 0; j < face.mNumVertices; ++j)
+ {
+ mPositions.push_back(LLVector3(face.mPositions[j].getF32ptr()));
+ }
+
+ for (U32 j = 0; j < face.mNumIndices; ++j)
+ {
+ mIndices.push_back(face.mIndices[j]+index_offset);
+ }
+
+ index_offset += face.mNumVertices;
+ }
+ }
+}
+
+S32 LLFloaterModelPreview::DecompRequest::statusCallback(const char* status, S32 p1, S32 p2)
+{
+ setStatusMessage(llformat("%s: %d/%d", status, p1, p2));
+ return mContinue;
+}
+
+void LLFloaterModelPreview::DecompRequest::completed()
+{
+ mModel->setPhysicsShape(mHull);
+
+ if (sInstance)
+ {
+ if (sInstance->mModelPreview)
+ {
+ sInstance->mModelPreview->mPhysicsMesh[mModel] = mHullMesh;
+ sInstance->mModelPreview->mDirty = true;
+ LLFloaterModelPreview::sInstance->mModelPreview->refresh();
+ }
+
+ sInstance->mCurRequest = NULL;
+ }
+}
+
+
diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h
index 8409249182..7be32663f4 100644
--- a/indra/newview/llfloatermodelpreview.h
+++ b/indra/newview/llfloatermodelpreview.h
@@ -92,6 +92,11 @@ public:
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);
virtual void run();
@@ -189,6 +194,18 @@ class LLModelPreview : public LLViewerDynamicTexture, public LLMutex
class LLFloaterModelPreview : public LLFloater
{
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 LLSD& key);
@@ -270,13 +287,18 @@ protected:
LLModelPreview* mModelPreview;
LLFloater* mDecompFloater;
-
+ LLPhysicsDecomp::decomp_params mDecompParams;
+
S32 mLastMouseX;
S32 mLastMouseY;
LLRect mPreviewRect;
U32 mGLName;
BOOL mLoading;
static S32 sUploadAmount;
+
+ LLPointer<DecompRequest> mCurRequest;
+
+
};
#endif // LL_LLFLOATERMODELPREVIEW_H
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index 9aba84acb4..eae5cf59f0 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -2132,7 +2132,18 @@ const LLMeshDecomposition* LLMeshRepository::getDecomposition(const LLUUID& mesh
void LLMeshRepository::buildHull(const LLVolumeParams& params, S32 detail)
{
+ LLVolume* volume = LLPrimitive::sVolumeManager->refVolume(params, detail);
+ if (!volume->mHullPoints)
+ {
+ //all default params
+ //execute first stage
+ //set simplify mode to retain
+ //set retain percentage to zero
+ //run second stage
+ }
+
+ LLPrimitive::sVolumeManager->unrefVolume(volume);
}
const LLSD& LLMeshRepository::getMeshHeader(const LLUUID& mesh_id)
@@ -2580,13 +2591,9 @@ LLPhysicsDecomp::LLPhysicsDecomp()
mInited = false;
mQuitting = false;
mDone = false;
- mStage = -1;
- mContinue = 1;
mSignal = new LLCondition(NULL);
mMutex = new LLMutex(NULL);
-
- setStatusMessage("Idle");
}
LLPhysicsDecomp::~LLPhysicsDecomp()
@@ -2599,7 +2606,6 @@ void LLPhysicsDecomp::shutdown()
if (mSignal)
{
mQuitting = true;
- mContinue = 0;
mSignal->signal();
while (!mDone)
@@ -2609,74 +2615,24 @@ void LLPhysicsDecomp::shutdown()
}
}
-void LLPhysicsDecomp::setStatusMessage(std::string msg)
+void LLPhysicsDecomp::submitRequest(LLPhysicsDecomp::Request* request)
{
LLMutexLock lock(mMutex);
- mStatus = msg;
-}
-
-void LLPhysicsDecomp::execute(const char* stage, LLModel* mdl)
-{
- LLMutexLock lock(mMutex);
-
- if (mModel.notNull())
- {
- llwarns << "Not done processing previous model." << llendl;
- return;
- }
-
- mModel = mdl;
- //load model into LLCD
- if (mdl)
- {
- mStage = mStageID[stage];
-
- U16 index_offset = 0;
-
- if (mStage == 0)
- {
- mPositions.clear();
- mIndices.clear();
-
- //queue up vertex positions and indices
- for (S32 i = 0; i < mdl->getNumVolumeFaces(); ++i)
- {
- const LLVolumeFace& face = mdl->getVolumeFace(i);
- if (mPositions.size() + face.mNumVertices > 65535)
- {
- continue;
- }
-
- for (U32 j = 0; j < face.mNumVertices; ++j)
- {
- mPositions.push_back(LLVector3(face.mPositions[j].getF32ptr()));
- }
+ mRequestQ.push(request);
+ mSignal->signal();
- for (U32 j = 0; j < face.mNumIndices; ++j)
- {
- mIndices.push_back(face.mIndices[j]+index_offset);
- }
-
- index_offset += face.mNumVertices;
- }
- }
-
- //signal decomposition thread
- mSignal->signal();
- }
+
}
//static
S32 LLPhysicsDecomp::llcdCallback(const char* status, S32 p1, S32 p2)
{
- LLPhysicsDecomp* comp = gMeshRepo.mDecompThread;
- comp->setStatusMessage(llformat("%s: %d/%d", status, p1, p2));
- return comp->mContinue;
-}
+ if (gMeshRepo.mDecompThread && gMeshRepo.mDecompThread->mCurRequest.notNull())
+ {
+ return gMeshRepo.mDecompThread->mCurRequest->statusCallback(status, p1, p2);
+ }
-void LLPhysicsDecomp::cancel()
-{
- mContinue = 0;
+ return 1;
}
void LLPhysicsDecomp::run()
@@ -2687,25 +2643,31 @@ void LLPhysicsDecomp::run()
while (!mQuitting)
{
mSignal->wait();
- if (!mQuitting)
+ while (!mQuitting && !mRequestQ.empty())
{
+ mCurRequest = mRequestQ.front();
+ mRequestQ.pop();
+
+ LLCDMeshData mesh;
+ S32 stage = mStageID[mCurRequest->mStage];
+
//load data intoLLCD
- if (mStage == 0)
+ if (stage == 0)
{
- mMesh.mVertexBase = mPositions[0].mV;
- mMesh.mVertexStrideBytes = 12;
- mMesh.mNumVertices = mPositions.size();
+ mesh.mVertexBase = mCurRequest->mPositions[0].mV;
+ mesh.mVertexStrideBytes = 12;
+ mesh.mNumVertices = mCurRequest->mPositions.size();
- mMesh.mIndexType = LLCDMeshData::INT_16;
- mMesh.mIndexBase = &(mIndices[0]);
- mMesh.mIndexStrideBytes = 6;
+ mesh.mIndexType = LLCDMeshData::INT_16;
+ mesh.mIndexBase = &(mCurRequest->mIndices[0]);
+ mesh.mIndexStrideBytes = 6;
- mMesh.mNumTriangles = mIndices.size()/3;
+ mesh.mNumTriangles = mCurRequest->mIndices.size()/3;
LLCDResult ret = LLCD_OK;
if (LLConvexDecomposition::getInstance() != NULL)
{
- ret = LLConvexDecomposition::getInstance()->setMeshData(&mMesh);
+ ret = LLConvexDecomposition::getInstance()->setMeshData(&mesh);
}
if (ret)
@@ -2714,44 +2676,81 @@ void LLPhysicsDecomp::run()
}
}
- setStatusMessage("Executing.");
- mContinue = 1;
+ //build parameter map
+ std::map<std::string, const LLCDParam*> param_map;
+
+ const LLCDParam* params;
+ S32 param_count = LLConvexDecomposition::getInstance()->getParameters(&params);
+
+ for (S32 i = 0; i < param_count; ++i)
+ {
+ param_map[params[i].mName] = params+i;
+ }
+
+ //set parameter values
+ for (decomp_params::iterator iter = mCurRequest->mParams.begin(); iter != mCurRequest->mParams.end(); ++iter)
+ {
+ const std::string& name = iter->first;
+ const LLSD& value = iter->second;
+
+ const LLCDParam* param = param_map[name];
+
+ if (param == NULL)
+ { //couldn't find valid parameter
+ continue;
+ }
+
+ U32 ret = LLCD_OK;
+
+ if (param->mType == LLCDParam::LLCD_FLOAT)
+ {
+ ret = LLConvexDecomposition::getInstance()->setParam(param->mName, (F32) value.asReal());
+ }
+ else if (param->mType == LLCDParam::LLCD_INTEGER ||
+ param->mType == LLCDParam::LLCD_ENUM)
+ {
+ ret = LLConvexDecomposition::getInstance()->setParam(param->mName, value.asInteger());
+ }
+ else if (param->mType == LLCDParam::LLCD_BOOLEAN)
+ {
+ ret = LLConvexDecomposition::getInstance()->setParam(param->mName, value.asBoolean());
+ }
+
+ if (ret)
+ {
+ llerrs << "WTF?" << llendl;
+ }
+ }
+
+ mCurRequest->setStatusMessage("Executing.");
+
LLCDResult ret = LLCD_OK;
+
if (LLConvexDecomposition::getInstance() != NULL)
{
- ret = LLConvexDecomposition::getInstance()->executeStage(mStage);
+ ret = LLConvexDecomposition::getInstance()->executeStage(stage);
}
- mContinue = 0;
if (ret)
{
- llerrs << "Convex Decomposition thread valid but could not execute stage " << mStage << llendl;
+ llerrs << "Convex Decomposition thread valid but could not execute stage " << stage << llendl;
}
-
- setStatusMessage("Reading results");
+ mCurRequest->setStatusMessage("Reading results");
S32 num_hulls =0;
if (LLConvexDecomposition::getInstance() != NULL)
{
- num_hulls = LLConvexDecomposition::getInstance()->getNumHullsFromStage(mStage);
+ num_hulls = LLConvexDecomposition::getInstance()->getNumHullsFromStage(stage);
}
- if (mModel.isNull())
- {
- llerrs << "mModel should never be null here!" << llendl;
- }
-
mMutex->lock();
- mModel->mPhysicsShape.clear();
- mModel->mPhysicsShape.resize(num_hulls);
- mModel->mHullCenter.clear();
- mModel->mHullCenter.resize(num_hulls);
- std::vector<LLPointer<LLVertexBuffer> > mesh_buffer;
- mesh_buffer.resize(num_hulls);
- mModel->mPhysicsCenter.clearVec();
- mModel->mPhysicsPoints = 0;
+ mCurRequest->mHull.clear();
+ mCurRequest->mHull.resize(num_hulls);
+
+ mCurRequest->mHullMesh.clear();
+ mCurRequest->mHullMesh.resize(num_hulls);
mMutex->unlock();
for (S32 i = 0; i < num_hulls; ++i)
@@ -2759,49 +2758,36 @@ void LLPhysicsDecomp::run()
std::vector<LLVector3> p;
LLCDHull hull;
// if LLConvexDecomposition is a stub, num_hulls should have been set to 0 above, and we should not reach this code
- LLConvexDecomposition::getInstance()->getHullFromStage(mStage, i, &hull);
+ LLConvexDecomposition::getInstance()->getHullFromStage(stage, i, &hull);
const F32* v = hull.mVertexBase;
- LLVector3 hull_center;
-
for (S32 j = 0; j < hull.mNumVertices; ++j)
{
LLVector3 vert(v[0], v[1], v[2]);
p.push_back(vert);
- hull_center += vert;
v = (F32*) (((U8*) v) + hull.mVertexStrideBytes);
}
-
- hull_center *= 1.f/hull.mNumVertices;
-
LLCDMeshData mesh;
// if LLConvexDecomposition is a stub, num_hulls should have been set to 0 above, and we should not reach this code
- LLConvexDecomposition::getInstance()->getMeshFromStage(mStage, i, &mesh);
-
- mesh_buffer[i] = get_vertex_buffer_from_mesh(mesh);
+ LLConvexDecomposition::getInstance()->getMeshFromStage(stage, i, &mesh);
+ mCurRequest->mHullMesh[i] = get_vertex_buffer_from_mesh(mesh);
+
mMutex->lock();
- mModel->mPhysicsShape[i] = p;
- mModel->mHullCenter[i] = hull_center;
- mModel->mPhysicsPoints += hull.mNumVertices;
- mModel->mPhysicsCenter += hull_center;
-
+ mCurRequest->mHull[i] = p;
mMutex->unlock();
}
{
LLMutexLock lock(mMutex);
- mModel->mPhysicsCenter *= 1.f/mModel->mPhysicsPoints;
-
- LLFloaterModelPreview::onModelDecompositionComplete(mModel, mesh_buffer);
- //done updating model
- mModel = NULL;
+
+ mCurRequest->setStatusMessage("Done.");
+ mCurRequest->completed();
+
+ mCurRequest = NULL;
}
-
- setStatusMessage("Done.");
- LLFloaterModelPreview::sInstance->mModelPreview->refresh();
}
}
@@ -2814,4 +2800,8 @@ void LLPhysicsDecomp::run()
mDone = true;
}
+void LLPhysicsDecomp::Request::setStatusMessage(const std::string& msg)
+{
+ mStatusMessage = msg;
+}
diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h
index 0bc63a8469..e7270cc47d 100644
--- a/indra/newview/llmeshrepository.h
+++ b/indra/newview/llmeshrepository.h
@@ -151,37 +151,53 @@ public:
class LLPhysicsDecomp : public LLThread
{
public:
+
+ typedef std::map<std::string, LLSD> decomp_params;
+
+ class Request : public LLRefCount
+ {
+ public:
+ //input params
+ std::string mStage;
+ std::vector<LLVector3> mPositions;
+ std::vector<U16> mIndices;
+ decomp_params mParams;
+
+ //output state
+ std::string mStatusMessage;
+ std::vector<LLPointer<LLVertexBuffer> > mHullMesh;
+ LLModel::physics_shape mHull;
+
+ virtual S32 statusCallback(const char* status, S32 p1, S32 p2) = 0;
+ virtual void completed() = 0;
+ virtual void setStatusMessage(const std::string& msg);
+ };
+
LLCondition* mSignal;
LLMutex* mMutex;
- LLCDMeshData mMesh;
-
bool mInited;
bool mQuitting;
bool mDone;
-
- S32 mContinue;
- std::string mStatus;
-
- std::vector<LLVector3> mPositions;
- std::vector<U16> mIndices;
-
- S32 mStage;
-
+
LLPhysicsDecomp();
~LLPhysicsDecomp();
void shutdown();
- void setStatusMessage(std::string msg);
-
- void execute(const char* stage, LLModel* mdl);
+
+ void submitRequest(Request* request);
static S32 llcdCallback(const char*, S32, S32);
void cancel();
virtual void run();
std::map<std::string, S32> mStageID;
- LLPointer<LLModel> mModel;
+
+ typedef std::queue<LLPointer<Request> > request_queue;
+ request_queue mRequestQ;
+
+ LLPointer<Request> mCurRequest;
+
};
class LLMeshRepoThread : public LLThread
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 63c3e61598..8fd2d7a016 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -1631,7 +1631,8 @@ BOOL LLVOAvatar::setupBone(const LLVOAvatarBoneInfo* info, LLViewerJoint* parent
info->mRot.mV[VZ], LLQuaternion::XYZ));
joint->setScale(info->mScale);
-
+ joint->setDefaultFromCurrentXform();
+
if (info->mIsJoint)
{
joint->setSkinOffset( info->mPivot );
@@ -4785,6 +4786,38 @@ void LLVOAvatar::resetJointPositions( void )
}
}
//-----------------------------------------------------------------------------
+// resetJointPositionsToDefault
+//-----------------------------------------------------------------------------
+void LLVOAvatar::resetJointPositionsToDefault( void )
+{
+ const LLVector3& avPos = getCharacterPosition();
+
+ //Reposition the pelvis
+ LLJoint* pPelvis = mRoot.findJoint("mPelvis");
+ if ( pPelvis )
+ {
+ pPelvis->setPosition( avPos + pPelvis->getPosition() );
+ }
+ else
+ {
+ llwarns<<"Can't get pelvis joint."<<llendl;
+ return;
+ }
+
+ //Subsequent joints are relative to pelvis
+ for( S32 i = 0; i < (S32)mNumJoints; ++i )
+ {
+ LLJoint* pJoint = (LLJoint*)&mSkeleton[i];
+ //restore joints to default positions, however skip over the pelvis
+ if ( pJoint && pPelvis != pJoint )
+ {
+ pJoint->restoreToDefaultXform();
+ }
+ }
+}
+
+
+//-----------------------------------------------------------------------------
// getCharacterPosition()
//-----------------------------------------------------------------------------
LLVector3 LLVOAvatar::getCharacterPosition()
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index 4a8f3bf9ef..f4e27c675b 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -171,6 +171,7 @@ public:
virtual LLJoint* getRootJoint() { return &mRoot; }
void resetJointPositions( void );
+ void resetJointPositionsToDefault( void );
virtual const char* getAnimationPrefix() { return "avatar"; }
virtual const LLUUID& getID();
diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp
index fd519cb3a9..0298bcc80b 100644
--- a/indra/newview/llvoavatarself.cpp
+++ b/indra/newview/llvoavatarself.cpp
@@ -62,6 +62,8 @@
#include "llviewerstats.h"
#include "llviewerregion.h"
#include "llappearancemgr.h"
+#include "llmeshrepository.h"
+#include "llvovolume.h"
#if LL_MSVC
// disable boost::lexical_cast warning
@@ -655,6 +657,10 @@ LLJoint *LLVOAvatarSelf::getJoint(const std::string &name)
return LLVOAvatar::getJoint(name);
}
+void LLVOAvatarSelf::resetJointPositions( void )
+{
+ return LLVOAvatar::resetJointPositionsToDefault();
+}
// virtual
BOOL LLVOAvatarSelf::setVisualParamWeight(LLVisualParam *which_param, F32 weight, BOOL upload_bake )
{
@@ -1119,8 +1125,22 @@ const LLViewerJointAttachment *LLVOAvatarSelf::attachObject(LLViewerObject *view
BOOL LLVOAvatarSelf::detachObject(LLViewerObject *viewer_object)
{
const LLUUID attachment_id = viewer_object->getAttachmentItemID();
- if (LLVOAvatar::detachObject(viewer_object))
+ if ( LLVOAvatar::detachObject(viewer_object) )
{
+ //If a VO has a skin that we'll reset the joint positions to their default
+ if ( viewer_object->mDrawable )
+ {
+ LLVOVolume* pVObj = viewer_object->mDrawable->getVOVolume();
+ if ( pVObj )
+ {
+ const LLMeshSkinInfo* pSkinData = gMeshRepo.getSkinInfo( pVObj->getVolume()->getParams().getSculptID() );
+ if ( pSkinData )
+ {
+ resetJointPositions();
+ }
+ }
+ }
+
// the simulator should automatically handle permission revocation
stopMotionFromSource(attachment_id);
diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h
index 23a799ea3a..141a419fc8 100644
--- a/indra/newview/llvoavatarself.h
+++ b/indra/newview/llvoavatarself.h
@@ -83,7 +83,9 @@ public:
/*virtual*/ void stopMotionFromSource(const LLUUID& source_id);
/*virtual*/ void requestStopMotion(LLMotion* motion);
/*virtual*/ LLJoint* getJoint(const std::string &name);
-
+
+ void resetJointPositions( void );
+
/*virtual*/ BOOL setVisualParamWeight(LLVisualParam *which_param, F32 weight, BOOL upload_bake = FALSE );
/*virtual*/ BOOL setVisualParamWeight(const char* param_name, F32 weight, BOOL upload_bake = FALSE );
/*virtual*/ BOOL setVisualParamWeight(S32 index, F32 weight, BOOL upload_bake = FALSE );