diff options
Diffstat (limited to 'indra/newview')
-rw-r--r-- | indra/newview/llfloatermodelpreview.cpp | 157 | ||||
-rw-r--r-- | indra/newview/llfloatermodelpreview.h | 24 | ||||
-rw-r--r-- | indra/newview/llmeshrepository.cpp | 226 | ||||
-rw-r--r-- | indra/newview/llmeshrepository.h | 46 | ||||
-rw-r--r-- | indra/newview/llvoavatar.cpp | 35 | ||||
-rw-r--r-- | indra/newview/llvoavatar.h | 1 | ||||
-rw-r--r-- | indra/newview/llvoavatarself.cpp | 22 | ||||
-rw-r--r-- | indra/newview/llvoavatarself.h | 4 |
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(¶ms); + + 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 ); |