summaryrefslogtreecommitdiff
path: root/indra/newview/llfloatermodelpreview.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llfloatermodelpreview.cpp')
-rw-r--r--[-rwxr-xr-x]indra/newview/llfloatermodelpreview.cpp193
1 files changed, 130 insertions, 63 deletions
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index 18a2729398..0f0fafcce6 100755..100644
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -42,7 +42,6 @@
#include "llcombobox.h"
#include "lldatapacker.h"
#include "lldrawable.h"
-#include "lldrawpoolavatar.h"
#include "llrender.h"
#include "llface.h"
#include "lleconomy.h"
@@ -54,6 +53,7 @@
#include "llmeshrepository.h"
#include "llnotificationsutil.h"
#include "llsdutil_math.h"
+#include "llskinningutil.h"
#include "lltextbox.h"
#include "lltoolmgr.h"
#include "llui.h"
@@ -338,25 +338,25 @@ BOOL LLFloaterModelPreview::postBuild()
LLTextBox* text = getChild<LLTextBox>(lod_label_name[i]);
if (text)
{
- text->setMouseDownCallback(boost::bind(&LLModelPreview::setPreviewLOD, mModelPreview, i));
+ text->setMouseDownCallback(boost::bind(&LLFloaterModelPreview::setPreviewLOD, this, i));
}
text = getChild<LLTextBox>(lod_triangles_name[i]);
if (text)
{
- text->setMouseDownCallback(boost::bind(&LLModelPreview::setPreviewLOD, mModelPreview, i));
+ text->setMouseDownCallback(boost::bind(&LLFloaterModelPreview::setPreviewLOD, this, i));
}
text = getChild<LLTextBox>(lod_vertices_name[i]);
if (text)
{
- text->setMouseDownCallback(boost::bind(&LLModelPreview::setPreviewLOD, mModelPreview, i));
+ text->setMouseDownCallback(boost::bind(&LLFloaterModelPreview::setPreviewLOD, this, i));
}
text = getChild<LLTextBox>(lod_status_name[i]);
if (text)
{
- text->setMouseDownCallback(boost::bind(&LLModelPreview::setPreviewLOD, mModelPreview, i));
+ text->setMouseDownCallback(boost::bind(&LLFloaterModelPreview::setPreviewLOD, this, i));
}
}
std::string current_grid = LLGridManager::getInstance()->getGridId();
@@ -489,10 +489,18 @@ void LLFloaterModelPreview::onClickCalculateBtn()
bool upload_skinweights = childGetValue("upload_skin").asBoolean();
bool upload_joint_positions = childGetValue("upload_joints").asBoolean();
+ if (upload_joint_positions)
+ {
+ // Diagnostic message showing list of joints for which joint offsets are defined.
+ // FIXME - given time, would be much better to put this in the UI, in updateStatusMessages().
+ mModelPreview->getPreviewAvatar()->showAttachmentPosOverrides();
+ }
+
mUploadModelUrl.clear();
gMeshRepo.uploadModel(mModelPreview->mUploadData, mModelPreview->mPreviewScale,
- childGetValue("upload_textures").asBoolean(), upload_skinweights, upload_joint_positions, mUploadModelUrl, false,
+ childGetValue("upload_textures").asBoolean(), upload_skinweights, upload_joint_positions,
+ mUploadModelUrl, false,
getWholeModelFeeObserverHandle());
toggleCalculateButton(false);
@@ -610,7 +618,7 @@ void LLFloaterModelPreview::onAutoFillCommit(LLUICtrl* ctrl, void* userdata)
{
LLFloaterModelPreview* fp = (LLFloaterModelPreview*) userdata;
- fp->mModelPreview->genLODs();
+ fp->mModelPreview->queryLODs();
}
void LLFloaterModelPreview::onLODParamCommit(S32 lod, bool enforce_tri_limit)
@@ -638,7 +646,12 @@ void LLFloaterModelPreview::onLODParamCommit(S32 lod, bool enforce_tri_limit)
//-----------------------------------------------------------------------------
void LLFloaterModelPreview::draw()
{
- LLFloater::draw();
+ LLFloater::draw();
+
+ if (!mModelPreview)
+ {
+ return;
+ }
mModelPreview->update();
@@ -668,7 +681,7 @@ void LLFloaterModelPreview::draw()
childSetTextArg("prim_cost", "[PRIM_COST]", llformat("%d", mModelPreview->mResourceCost));
childSetTextArg("description_label", "[TEXTURES]", llformat("%d", mModelPreview->mTextureSet.size()));
- if (mModelPreview)
+ if (mModelPreview->lodsReady())
{
gGL.color3f(1.f, 1.f, 1.f);
@@ -1178,13 +1191,13 @@ void LLFloaterModelPreview::onMouseCaptureLostModelPreview(LLMouseHandler* handl
LLModelPreview::LLModelPreview(S32 width, S32 height, LLFloater* fmp)
: LLViewerDynamicTexture(width, height, 3, ORDER_MIDDLE, FALSE), LLMutex(NULL)
+, mLodsQuery()
, mPelvisZOffset( 0.0f )
, mLegacyRigValid( false )
, mRigValidJointUpload( false )
, mPhysicsSearchLOD( LLModel::LOD_PHYSICS )
, mResetJoints( false )
, mModelNoErrors( true )
-, mRigParityWithScene( false )
, mLastJointUpdate( false )
{
mNeedsUpdate = TRUE;
@@ -1357,6 +1370,14 @@ void LLFloaterModelPreview::setDetails(F32 x, F32 y, F32 z, F32 streaming_cost,
childSetTextArg("import_dimensions", "[Z]", llformat("%.3f", z));
}
+void LLFloaterModelPreview::setPreviewLOD(S32 lod)
+{
+ if (mModelPreview)
+ {
+ mModelPreview->setPreviewLOD(lod);
+ }
+}
+
void LLModelPreview::rebuildUploadData()
{
@@ -1544,9 +1565,18 @@ void LLModelPreview::rebuildUploadData()
}
instance.mLOD[i] = lod_model;
}
- else if (importerDebug)
+ else
{
- LL_INFOS() << "List of models does not include " << instance.mLabel << LL_ENDL;
+ if (i < LLModel::LOD_HIGH && !lodsReady())
+ {
+ // assign a placeholder from previous LOD until lod generation is complete.
+ // Note: we might need to assign it regardless of conditions like named search does, to prevent crashes.
+ instance.mLOD[i] = instance.mLOD[i + 1];
+ }
+ if (importerDebug)
+ {
+ LL_INFOS() << "List of models does not include " << instance.mLabel << LL_ENDL;
+ }
}
}
@@ -1708,18 +1738,17 @@ void LLModelPreview::clearModel(S32 lod)
mScene[lod].clear();
}
-void LLModelPreview::getLegalJointNames(JointNameSet& legal_joint_names)
+void LLModelPreview::getJointAliases( JointMap& joint_map)
{
// 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++)
+
+ //Joint names and aliases come from avatar_skeleton.xml
+
+ joint_map = av->getJointAliases();
+ for (S32 i = 0; i < av->mNumCollisionVolumes; i++)
{
- LLAvatarJoint *joint = skel[i];
- if (joint)
- {
- legal_joint_names.push_back(joint->getName());
- }
+ joint_map[av->mCollisionVolumes[i].getName()] = av->mCollisionVolumes[i].getName();
}
}
@@ -1765,9 +1794,8 @@ void LLModelPreview::loadModel(std::string filename, S32 lod, bool force_disable
clearGLODGroup();
}
-
- JointNameSet legal_joint_names;
- getLegalJointNames(legal_joint_names);
+ std::map<std::string, std::string> joint_alias_map;
+ getJointAliases(joint_alias_map);
mModelLoader = new LLDAELoader(
filename,
@@ -1779,8 +1807,10 @@ void LLModelPreview::loadModel(std::string filename, S32 lod, bool force_disable
this,
mJointTransformMap,
mJointsFromNode,
- legal_joint_names,
- gSavedSettings.getU32("ImporterModelLimit"));
+ joint_alias_map,
+ LLSkinningUtil::getMaxJointCount(),
+ gSavedSettings.getU32("ImporterModelLimit"),
+ gSavedSettings.getBOOL("ImporterPreprocessDAE"));
if (force_disable_slm)
{
@@ -3303,14 +3333,17 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights)
LLVector3 pos(vf.mPositions[i].getF32ptr());
const LLModel::weight_list& weight_list = base_mdl->getJointInfluences(pos);
+ llassert(weight_list.size()>0 && weight_list.size() <= 4); // LLModel::loadModel() should guarantee this
LLVector4 w(0,0,0,0);
for (U32 i = 0; i < weight_list.size(); ++i)
{
- F32 wght = llmin(weight_list[i].mWeight, 0.999999f);
+ F32 wght = llclamp(weight_list[i].mWeight, 0.001f, 0.999f);
F32 joint = (F32) weight_list[i].mJointIdx;
w.mV[i] = joint + wght;
+ llassert(w.mV[i]-(S32)w.mV[i]>0.0f); // because weights are non-zero, and range of wt values
+ //should not cause floating point precision issues.
}
*(weights_strider++) = w;
@@ -3336,14 +3369,25 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights)
void LLModelPreview::update()
{
if (mGenLOD)
- {
- mGenLOD = false;
- genLODs();
- refresh();
- updateStatusMessages();
- }
+ {
+ bool subscribe_for_generation = mLodsQuery.empty();
+ mGenLOD = false;
+ mDirty = true;
+ mLodsQuery.clear();
- if (mDirty)
+ for (S32 lod = LLModel::LOD_HIGH; lod >= 0; --lod)
+ {
+ // adding all lods into query for generation
+ mLodsQuery.push_back(lod);
+ }
+
+ if (subscribe_for_generation)
+ {
+ doOnIdleRepeating(lodQueryCallback);
+ }
+ }
+
+ if (mDirty && mLodsQuery.empty())
{
mDirty = false;
mResourceCost = calcResourceCost();
@@ -3353,19 +3397,6 @@ void LLModelPreview::update()
}
//-----------------------------------------------------------------------------
-// getTranslationForJointOffset()
-//-----------------------------------------------------------------------------
-LLVector3 LLModelPreview::getTranslationForJointOffset( std::string joint )
-{
- LLMatrix4 jointTransform;
- if ( mJointTransformMap.find( joint ) != mJointTransformMap.end() )
- {
- jointTransform = mJointTransformMap[joint];
- return jointTransform.getTranslation();
- }
- return LLVector3(0.0f,0.0f,0.0f);
-}
-//-----------------------------------------------------------------------------
// createPreviewAvatar
//-----------------------------------------------------------------------------
void LLModelPreview::createPreviewAvatar( void )
@@ -3584,6 +3615,7 @@ BOOL LLModelPreview::render()
fmp->enableViewOption("show_skin_weight");
fmp->setViewOptionEnabled("show_joint_positions", skin_weight);
mFMP->childEnable("upload_skin");
+ mFMP->childSetValue("show_skin_weight", skin_weight);
}
}
else
@@ -3987,20 +4019,6 @@ BOOL LLModelPreview::render()
LLVector3::z_axis, // up
target_pos); // point of interest
- if (joint_positions)
- {
- LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
- if (shader)
- {
- gDebugProgram.bind();
- }
- getPreviewAvatar()->renderCollisionVolumes();
- if (shader)
- {
- shader->bind();
- }
- }
-
for (LLModelLoader::scene::iterator iter = mScene[mPreviewLOD].begin(); iter != mScene[mPreviewLOD].end(); ++iter)
{
for (LLModelLoader::model_instance_list::iterator model_iter = iter->second.begin(); model_iter != iter->second.end(); ++model_iter)
@@ -4028,16 +4046,17 @@ BOOL LLModelPreview::render()
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,
+ U32 count = LLSkinningUtil::getMeshJointCount(skin);
+ LLSkinningUtil::initSkinningMatrixPalette((LLMatrix4*)mat, count,
skin, getPreviewAvatar());
LLMatrix4a bind_shape_matrix;
bind_shape_matrix.loadu(skin->mBindShapeMatrix);
+ U32 max_joints = LLSkinningUtil::getMaxJointCount();
for (U32 j = 0; j < buffer->getNumVerts(); ++j)
{
LLMatrix4a final_mat;
F32 *wptr = weight[j].mV;
- LLDrawPoolAvatar::getPerVertexSkinMatrix(wptr, mat, true, final_mat);
+ LLSkinningUtil::getPerVertexSkinMatrix(wptr, mat, true, final_mat, max_joints);
//VECTORIZE THIS
LLVector4a& v = face.mPositions[j];
@@ -4083,6 +4102,22 @@ BOOL LLModelPreview::render()
}
}
}
+
+ if (joint_positions)
+ {
+ LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
+ if (shader)
+ {
+ gDebugProgram.bind();
+ }
+ getPreviewAvatar()->renderCollisionVolumes();
+ getPreviewAvatar()->renderBones();
+ if (shader)
+ {
+ shader->bind();
+ }
+ }
+
}
}
@@ -4240,6 +4275,29 @@ void LLModelPreview::textureLoadedCallback(
}
}
+// static
+bool LLModelPreview::lodQueryCallback()
+{
+ // not the best solution, but model preview belongs to floater
+ // so it is an easy way to check that preview still exists.
+ LLFloaterModelPreview* fmp = LLFloaterModelPreview::sInstance;
+ if (fmp && fmp->mModelPreview)
+ {
+ LLModelPreview* preview = fmp->mModelPreview;
+ if (preview->mLodsQuery.size() > 0)
+ {
+ S32 lod = preview->mLodsQuery.back();
+ preview->mLodsQuery.pop_back();
+ preview->genLODs(lod);
+
+ // return false to continue cycle
+ return false;
+ }
+ }
+ // nothing to process
+ return true;
+}
+
void LLModelPreview::onLODParamCommit(S32 lod, bool enforce_tri_limit)
{
if (!mLODFrozen)
@@ -4437,6 +4495,15 @@ void LLFloaterModelPreview::onPermissionsReceived(const LLSD& result)
// BAP HACK: handle "" for case that MeshUploadFlag cap is broken.
mHasUploadPerm = (("" == upload_status) || ("valid" == upload_status));
+ if (!mHasUploadPerm)
+ {
+ LL_WARNS() << "Upload permission set to false because upload_status=\"" << upload_status << "\"" << LL_ENDL;
+ }
+ else if (mHasUploadPerm && mUploadModelUrl.empty())
+ {
+ LL_WARNS() << "Upload permission set to true but uploadModelUrl is empty!" << LL_ENDL;
+ }
+
// isModelUploadAllowed() includes mHasUploadPerm
mUploadBtn->setEnabled(isModelUploadAllowed());
getChild<LLTextBox>("warning_title")->setVisible(!mHasUploadPerm);