summaryrefslogtreecommitdiff
path: root/indra/newview/llfloatermodelpreview.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llfloatermodelpreview.cpp')
-rwxr-xr-xindra/newview/llfloatermodelpreview.cpp179
1 files changed, 133 insertions, 46 deletions
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index a2a1dfbdb8..18a2729398 100755
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -202,6 +202,15 @@ LLViewerFetchedTexture* bindMaterialDiffuseTexture(const LLImportMaterial& mater
return NULL;
}
+std::string stripSuffix(std::string name)
+{
+ if ((name.find("_LOD") != -1) || (name.find("_PHYS") != -1))
+ {
+ return name.substr(0, name.rfind('_'));
+ }
+ return name;
+}
+
LLMeshFilePicker::LLMeshFilePicker(LLModelPreview* mp, S32 lod)
: LLFilePickerThread(LLFilePicker::FFLOAD_COLLADA)
{
@@ -1699,6 +1708,21 @@ void LLModelPreview::clearModel(S32 lod)
mScene[lod].clear();
}
+void LLModelPreview::getLegalJointNames(JointNameSet& legal_joint_names)
+{
+ // Get all standard skeleton joints from the preview avatar.
+ LLVOAvatar *av = getPreviewAvatar();
+ const LLVOAvatar::avatar_joint_list_t &skel = av->getSkeleton();
+ for (S32 i=0; i<skel.size(); i++)
+ {
+ LLAvatarJoint *joint = skel[i];
+ if (joint)
+ {
+ legal_joint_names.push_back(joint->getName());
+ }
+ }
+}
+
void LLModelPreview::loadModel(std::string filename, S32 lod, bool force_disable_slm)
{
assert_main_thread();
@@ -1741,6 +1765,10 @@ void LLModelPreview::loadModel(std::string filename, S32 lod, bool force_disable
clearGLODGroup();
}
+
+ JointNameSet legal_joint_names;
+ getLegalJointNames(legal_joint_names);
+
mModelLoader = new LLDAELoader(
filename,
lod,
@@ -1751,6 +1779,7 @@ void LLModelPreview::loadModel(std::string filename, S32 lod, bool force_disable
this,
mJointTransformMap,
mJointsFromNode,
+ legal_joint_names,
gSavedSettings.getU32("ImporterModelLimit"));
if (force_disable_slm)
@@ -1986,6 +2015,83 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod)
mBaseScene = mScene[loaded_lod];
mVertexBuffer[5].clear();
}
+ else
+ {
+ BOOL importerDebug = gSavedSettings.getBOOL("ImporterDebug");
+ BOOL legacyMatching = gSavedSettings.getBOOL("ImporterLegacyMatching");
+ if (!legacyMatching)
+ {
+ if (!mBaseModel.empty())
+ {
+ BOOL name_based = FALSE;
+ BOOL has_submodels = FALSE;
+ for (U32 idx = 0; idx < mBaseModel.size(); ++idx)
+ {
+ if (mBaseModel[idx]->mSubmodelID)
+ { // don't do index-based renaming when the base model has submodels
+ has_submodels = TRUE;
+ if (importerDebug)
+ {
+ LL_INFOS() << "High LOD has submodels" << LL_ENDL;
+ }
+ break;
+ }
+ }
+
+ for (U32 idx = 0; idx < mModel[loaded_lod].size(); ++idx)
+ {
+ std::string loaded_name = stripSuffix(mModel[loaded_lod][idx]->mLabel);
+
+ LLModel* found_model = NULL;
+ LLMatrix4 transform;
+ FindModel(mBaseScene, loaded_name, found_model, transform);
+ if (found_model)
+ { // don't rename correctly named models (even if they are placed in a wrong order)
+ name_based = TRUE;
+ }
+
+ if (mModel[loaded_lod][idx]->mSubmodelID)
+ { // don't rename the models when loaded LOD model has submodels
+ has_submodels = TRUE;
+ }
+ }
+
+ if (importerDebug)
+ {
+ LL_INFOS() << "Loaded LOD " << loaded_lod << ": correct names" << (name_based ? "" : "NOT ") << "found; submodels " << (has_submodels ? "" : "NOT ") << "found" << LL_ENDL;
+ }
+
+ if (!name_based && !has_submodels)
+ { // replace the name of the model loaded for any non-HIGH LOD to match the others (MAINT-5601)
+ // this actually works like "ImporterLegacyMatching" for this particular LOD
+ for (U32 idx = 0; idx < mModel[loaded_lod].size() && idx < mBaseModel.size(); ++idx)
+ {
+ std::string name = mBaseModel[idx]->mLabel;
+ std::string loaded_name = stripSuffix(mModel[loaded_lod][idx]->mLabel);
+
+ if (loaded_name != name)
+ {
+ switch (loaded_lod)
+ {
+ case LLModel::LOD_IMPOSTOR: name += "_LOD0"; break;
+ case LLModel::LOD_LOW: name += "_LOD1"; break;
+ case LLModel::LOD_MEDIUM: name += "_LOD2"; break;
+ case LLModel::LOD_PHYSICS: name += "_PHYS"; break;
+ case LLModel::LOD_HIGH: break;
+ }
+
+ if (importerDebug)
+ {
+ LL_WARNS() << "Loded model name " << mModel[loaded_lod][idx]->mLabel << " for LOD " << loaded_lod << " doesn't match the base model. Renaming to " << name << LL_ENDL;
+ }
+
+ mModel[loaded_lod][idx]->mLabel = name;
+ }
+ }
+ }
+ }
+ }
+ }
clearIncompatible(loaded_lod);
@@ -3388,6 +3494,7 @@ void LLModelPreview::addEmptyFace( LLModel* pTarget )
pTarget->setVolumeFaceData( faceCnt+1, pos, norm, tc, index, buff->getNumVerts(), buff->getNumIndices() );
}
+
//-----------------------------------------------------------------------------
// render()
//-----------------------------------------------------------------------------
@@ -3918,58 +4025,31 @@ BOOL LLModelPreview::render()
//quick 'n dirty software vertex skinning
//build matrix palette
-
- LLMatrix4 mat[64];
- for (U32 j = 0; j < model->mSkinInfo.mJointNames.size(); ++j)
- {
- LLJoint* joint = getPreviewAvatar()->getJoint(model->mSkinInfo.mJointNames[j]);
- if (joint)
- {
- mat[j] = model->mSkinInfo.mInvBindMatrix[j];
- mat[j] *= joint->getWorldMatrix();
- }
- }
+ LLMatrix4a mat[LL_MAX_JOINTS_PER_MESH_OBJECT];
+ const LLMeshSkinInfo *skin = &model->mSkinInfo;
+ U32 count = llmin((U32) skin->mJointNames.size(), (U32) LL_MAX_JOINTS_PER_MESH_OBJECT);
+ LLDrawPoolAvatar::initSkinningMatrixPalette((LLMatrix4*)mat, count,
+ skin, getPreviewAvatar());
+ LLMatrix4a bind_shape_matrix;
+ bind_shape_matrix.loadu(skin->mBindShapeMatrix);
for (U32 j = 0; j < buffer->getNumVerts(); ++j)
{
- LLMatrix4 final_mat;
- final_mat.mMatrix[0][0] = final_mat.mMatrix[1][1] = final_mat.mMatrix[2][2] = final_mat.mMatrix[3][3] = 0.f;
-
- LLVector4 wght;
- S32 idx[4];
-
- F32 scale = 0.f;
- for (U32 k = 0; k < 4; k++)
- {
- F32 w = weight[j].mV[k];
-
- idx[k] = (S32) floorf(w);
- wght.mV[k] = w - floorf(w);
- scale += wght.mV[k];
- }
-
- wght *= 1.f/scale;
-
- for (U32 k = 0; k < 4; k++)
- {
- F32* src = (F32*) mat[idx[k]].mMatrix;
- F32* dst = (F32*) final_mat.mMatrix;
-
- F32 w = wght.mV[k];
-
- for (U32 l = 0; l < 16; l++)
- {
- dst[l] += src[l]*w;
- }
- }
+ LLMatrix4a final_mat;
+ F32 *wptr = weight[j].mV;
+ LLDrawPoolAvatar::getPerVertexSkinMatrix(wptr, mat, true, final_mat);
//VECTORIZE THIS
- LLVector3 v(face.mPositions[j].getF32ptr());
+ LLVector4a& v = face.mPositions[j];
- v = v * model->mSkinInfo.mBindShapeMatrix;
- v = v * final_mat;
+ LLVector4a t;
+ LLVector4a dst;
+ bind_shape_matrix.affineTransform(v, t);
+ final_mat.affineTransform(t, dst);
- position[j] = v;
+ position[j][0] = dst[0];
+ position[j][1] = dst[1];
+ position[j][2] = dst[2];
}
llassert(model->mMaterialList.size() > i);
@@ -4139,7 +4219,14 @@ void LLFloaterModelPreview::refresh()
}
//static
-void LLModelPreview::textureLoadedCallback( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* userdata )
+void LLModelPreview::textureLoadedCallback(
+ BOOL success,
+ LLViewerFetchedTexture *src_vi,
+ LLImageRaw* src,
+ LLImageRaw* src_aux,
+ S32 discard_level,
+ BOOL final,
+ void* userdata )
{
LLModelPreview* preview = (LLModelPreview*) userdata;
preview->refresh();