summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
Diffstat (limited to 'indra')
-rwxr-xr-xindra/newview/app_settings/settings.xml11
-rwxr-xr-xindra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl10
-rwxr-xr-xindra/newview/lldrawpoolavatar.cpp49
-rwxr-xr-xindra/newview/lldrawpoolavatar.h4
-rwxr-xr-xindra/newview/llfloatermodelpreview.cpp5
-rwxr-xr-xindra/newview/llviewercontrol.cpp1
-rwxr-xr-xindra/newview/llviewershadermgr.cpp8
-rwxr-xr-xindra/newview/llvovolume.cpp5
8 files changed, 77 insertions, 16 deletions
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 6533344048..dcb2764fe7 100755
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -6112,6 +6112,17 @@
<key>Value</key>
<real>1.6</real>
</map>
+ <key>MaxJointsPerMeshObject</key>
+ <map>
+ <key>Comment</key>
+ <string>Maximum joints per rigged mesh object</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>U32</string>
+ <key>Value</key>
+ <real>999</real>
+ </map>
<key>MaxPersistentNotifications</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl b/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl
index b342abb7c1..8f754fe82b 100755
--- a/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl
+++ b/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl
@@ -27,8 +27,8 @@ ATTRIBUTE vec4 weight4;
/* BENTO JOINT COUNT LIMITS
* Note that the value in these two lines also needs to be updated to value-1 several places below.
*/
-uniform mat3 matrixPalette[152];
-uniform vec3 translationPalette[152];
+uniform mat3 matrixPalette[MAX_JOINTS_PER_MESH_OBJECT];
+uniform vec3 translationPalette[MAX_JOINTS_PER_MESH_OBJECT];
mat4 getObjectSkinnedTransform()
{
@@ -37,7 +37,7 @@ mat4 getObjectSkinnedTransform()
vec4 w = fract(weight4);
vec4 index = floor(weight4);
- index = min(index, vec4(151.0));
+ index = min(index, vec4(MAX_JOINTS_PER_MESH_OBJECT-1));
index = max(index, vec4( 0.0));
w *= 1.0/(w.x+w.y+w.z+w.w);
@@ -70,8 +70,8 @@ mat4 getObjectSkinnedTransform()
// If it's AMD make sure the GLSL compiler sees the arrays referenced once by static index. Otherwise it seems to optimise the storage awawy which leads to unfun crashes and artifacts.
mat3 dummy1 = matrixPalette[0];
vec3 dummy2 = translationPalette[0];
- mat3 dummy3 = matrixPalette[151];
- vec3 dummy4 = translationPalette[151];
+ mat3 dummy3 = matrixPalette[MAX_JOINTS_PER_MESH_OBJECT-1];
+ vec3 dummy4 = translationPalette[MAX_JOINTS_PER_MESH_OBJECT-1];
#endif
}
diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp
index b3821fda85..5d78132f6d 100755
--- a/indra/newview/lldrawpoolavatar.cpp
+++ b/indra/newview/lldrawpoolavatar.cpp
@@ -1538,6 +1538,18 @@ void LLDrawPoolAvatar::getRiggedGeometry(
}
// static
+U32 LLDrawPoolAvatar::getMaxJointCount()
+{
+ return llmin(LL_MAX_JOINTS_PER_MESH_OBJECT, gSavedSettings.getU32("MaxJointsPerMeshObject"));
+}
+
+// static
+U32 LLDrawPoolAvatar::getMeshJointCount(const LLMeshSkinInfo *skin)
+{
+ return llmin(getMaxJointCount(), skin->mJointNames.size());
+}
+
+// static
void LLDrawPoolAvatar::initSkinningMatrixPalette(
LLMatrix4* mat,
S32 count,
@@ -1555,6 +1567,26 @@ void LLDrawPoolAvatar::initSkinningMatrixPalette(
}
if (joint)
{
+#if 0
+ // BENTO HACK - test of simple push-to-ancestor complexity reduction scheme.
+ const std::string& name = joint->getName();
+ S32 digit = name.back()-'0';
+ while (joint->getParent() && (digit<=9) && (digit>=5))
+ {
+ joint = joint->getParent();
+ const std::string& name = joint->getName();
+ digit = name.back()-'0';
+ }
+ U32 j_remap = 0;
+ std::vector<std::string>::const_iterator find_it =
+ std::find(skin->mJointNames.begin(), skin->mJointNames.end(), joint->getName());
+ if (find_it != skin->mJointNames.end())
+ {
+ j_remap = find_it - skin->mJointNames.begin();
+ }
+ // BENTO for hack, use invBindMatrix of up-casted joint
+ mat[j] = skin->mInvBindMatrix[j_remap];
+#endif
mat[j] = skin->mInvBindMatrix[j];
mat[j] *= joint->getWorldMatrix();
}
@@ -1570,8 +1602,14 @@ void LLDrawPoolAvatar::initSkinningMatrixPalette(
}
// static
-void LLDrawPoolAvatar::getPerVertexSkinMatrix(F32* weights, LLMatrix4a* mat, bool handle_bad_scale, LLMatrix4a& final_mat)
+void LLDrawPoolAvatar::getPerVertexSkinMatrix(
+ F32* weights,
+ LLMatrix4a* mat,
+ bool handle_bad_scale,
+ LLMatrix4a& final_mat,
+ U32 max_joints)
{
+
final_mat.clear();
S32 idx[4];
@@ -1589,7 +1627,7 @@ void LLDrawPoolAvatar::getPerVertexSkinMatrix(F32* weights, LLMatrix4a* mat, boo
// >= 0.0, we can use int instead of floorf; the latter
// allegedly has a lot of overhead due to ieeefp error
// checking which we should not need.
- idx[k] = llclamp((S32) floorf(w), (S32)0, (S32)LL_MAX_JOINTS_PER_MESH_OBJECT-1);
+ idx[k] = llclamp((S32) floorf(w), (S32)0, (S32)max_joints-1);
wght[k] = w - floorf(w);
scale += wght[k];
@@ -1685,16 +1723,17 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(
//build matrix palette
LLMatrix4a mat[LL_MAX_JOINTS_PER_MESH_OBJECT];
- U32 count = llmin((U32) skin->mJointNames.size(), (U32) LL_MAX_JOINTS_PER_MESH_OBJECT);
+ U32 count = getMeshJointCount(skin);
initSkinningMatrixPalette((LLMatrix4*)mat, count, skin, avatar);
LLMatrix4a bind_shape_matrix;
bind_shape_matrix.loadu(skin->mBindShapeMatrix);
+ const U32 max_joints = getMaxJointCount();
for (U32 j = 0; j < buffer->getNumVerts(); ++j)
{
LLMatrix4a final_mat;
- getPerVertexSkinMatrix(weight[j].getF32ptr(), mat, false, final_mat);
+ getPerVertexSkinMatrix(weight[j].getF32ptr(), mat, false, final_mat, max_joints);
LLVector4a& v = vol_face.mPositions[j];
LLVector4a t;
@@ -1777,7 +1816,7 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
{
// upload matrix palette to shader
LLMatrix4a mat[LL_MAX_JOINTS_PER_MESH_OBJECT];
- U32 count = llmin((U32) skin->mJointNames.size(), (U32) LL_MAX_JOINTS_PER_MESH_OBJECT);
+ U32 count = getMeshJointCount(skin);
initSkinningMatrixPalette((LLMatrix4*)mat, count, skin, avatar);
stop_glerror();
diff --git a/indra/newview/lldrawpoolavatar.h b/indra/newview/lldrawpoolavatar.h
index af063ee74e..79d16c26bc 100755
--- a/indra/newview/lldrawpoolavatar.h
+++ b/indra/newview/lldrawpoolavatar.h
@@ -134,8 +134,10 @@ public:
void endDeferredRiggedBump();
void getRiggedGeometry(LLFace* face, LLPointer<LLVertexBuffer>& buffer, U32 data_mask, const LLMeshSkinInfo* skin, LLVolume* volume, const LLVolumeFace& vol_face);
+ static U32 getMaxJointCount();
+ static U32 getMeshJointCount(const LLMeshSkinInfo *skin);
static void initSkinningMatrixPalette(LLMatrix4* mat, S32 count, const LLMeshSkinInfo* skin, LLVOAvatar *avatar);
- static void getPerVertexSkinMatrix(F32* weights, LLMatrix4a* mat, bool handle_bad_scale, LLMatrix4a& final_mat);
+ static void getPerVertexSkinMatrix(F32* weights, LLMatrix4a* mat, bool handle_bad_scale, LLMatrix4a& final_mat, U32 max_joints);
void updateRiggedFaceVertexBuffer(LLVOAvatar* avatar,
LLFace* facep,
const LLMeshSkinInfo* skin,
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index 18a2729398..4267d6371e 100755
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -4028,16 +4028,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);
+ U32 count = LLDrawPoolAvatar::getMeshJointCount(skin);
LLDrawPoolAvatar::initSkinningMatrixPalette((LLMatrix4*)mat, count,
skin, getPreviewAvatar());
LLMatrix4a bind_shape_matrix;
bind_shape_matrix.loadu(skin->mBindShapeMatrix);
+ U32 max_joints = LLDrawPoolAvatar::getMaxJointCount();
for (U32 j = 0; j < buffer->getNumVerts(); ++j)
{
LLMatrix4a final_mat;
F32 *wptr = weight[j].mV;
- LLDrawPoolAvatar::getPerVertexSkinMatrix(wptr, mat, true, final_mat);
+ LLDrawPoolAvatar::getPerVertexSkinMatrix(wptr, mat, true, final_mat, max_joints);
//VECTORIZE THIS
LLVector4a& v = face.mPositions[j];
diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index 5020518454..466edb19b2 100755
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -761,6 +761,7 @@ void settings_setup_listeners()
gSavedSettings.getControl("SpellCheck")->getSignal()->connect(boost::bind(&handleSpellCheckChanged));
gSavedSettings.getControl("SpellCheckDictionary")->getSignal()->connect(boost::bind(&handleSpellCheckChanged));
gSavedSettings.getControl("LoginLocation")->getSignal()->connect(boost::bind(&handleLoginLocationChanged));
+ gSavedSettings.getControl("MaxJointsPerMeshObject")->getCommitSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
}
#if TEST_CACHED_CONTROL
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index dafe2cafec..b1e521f193 100755
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -27,6 +27,8 @@
#include "llviewerprecompiledheaders.h"
+#include <boost/lexical_cast.hpp>
+
#include "llfeaturemanager.h"
#include "llviewershadermgr.h"
@@ -41,6 +43,8 @@
#include "llsky.h"
#include "llvosky.h"
#include "llrender.h"
+#include "lljoint.h"
+#include "lldrawpoolavatar.h"
#ifdef LL_RELEASE_FOR_DOWNLOAD
#define UNIFORM_ERRS LL_WARNS_ONCE("Shader")
@@ -871,7 +875,9 @@ BOOL LLViewerShaderMgr::loadBasicShaders()
shaders.push_back( make_pair( "objects/nonindexedTextureV.glsl", 1 ) );
boost::unordered_map<std::string, std::string> attribs;
-
+ attribs["MAX_JOINTS_PER_MESH_OBJECT"] =
+ boost::lexical_cast<std::string>(LLDrawPoolAvatar::getMaxJointCount());
+
// We no longer have to bind the shaders to global glhandles, they are automatically added to a map now.
for (U32 i = 0; i < shaders.size(); i++)
{
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 5e010a4712..dde0e2caa1 100755
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -4167,7 +4167,7 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons
static const size_t kMaxJoints = LL_MAX_JOINTS_PER_MESH_OBJECT;
LLMatrix4a mat[kMaxJoints];
- U32 maxJoints = llmin(skin->mJointNames.size(), kMaxJoints);
+ U32 maxJoints = LLDrawPoolAvatar::getMeshJointCount(skin);
LLDrawPoolAvatar::initSkinningMatrixPalette((LLMatrix4*)mat, maxJoints, skin, avatar);
for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i)
@@ -4189,10 +4189,11 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons
{
LL_RECORD_BLOCK_TIME(FTM_SKIN_RIGGED);
+ U32 max_joints = LLDrawPoolAvatar::getMaxJointCount();
for (U32 j = 0; j < dst_face.mNumVertices; ++j)
{
LLMatrix4a final_mat;
- LLDrawPoolAvatar::getPerVertexSkinMatrix(weight[j].getF32ptr(), mat, false, final_mat);
+ LLDrawPoolAvatar::getPerVertexSkinMatrix(weight[j].getF32ptr(), mat, false, final_mat, max_joints);
LLVector4a& v = vol_face.mPositions[j];
LLVector4a t;