summaryrefslogtreecommitdiff
path: root/indra/llappearance
diff options
context:
space:
mode:
authorDon Kjer <don@lindenlab.com>2012-09-09 12:12:19 +0000
committerDon Kjer <don@lindenlab.com>2012-09-09 12:12:19 +0000
commite1580128ab2a42ecd4019ef35069f9e939dc4ff2 (patch)
tree9ca329417e96ae7fa09261c843623349be759d5f /indra/llappearance
parentb77e2eff481512667c35bc99946fb62eca1be169 (diff)
Fixed crashes on login. Moved most of the remaining character/skeleton generation code into llappearance. Moved non-rendering related LLViewerJoint functionality into LLAvatarJoint.
Diffstat (limited to 'indra/llappearance')
-rw-r--r--indra/llappearance/llavatarappearance.cpp245
-rw-r--r--indra/llappearance/llavatarappearance.h27
-rw-r--r--indra/llappearance/llavatarappearancedefines.cpp4
-rw-r--r--indra/llappearance/llavatarappearancedefines.h10
-rw-r--r--indra/llappearance/llavatarjoint.cpp120
-rw-r--r--indra/llappearance/llavatarjoint.h24
-rwxr-xr-xindra/llappearance/llavatarjointmesh.cpp10
-rwxr-xr-xindra/llappearance/llavatarjointmesh.h12
-rw-r--r--indra/llappearance/lljointpickname.h3
9 files changed, 378 insertions, 77 deletions
diff --git a/indra/llappearance/llavatarappearance.cpp b/indra/llappearance/llavatarappearance.cpp
index 406e6153e0..e2dfa2fb74 100644
--- a/indra/llappearance/llavatarappearance.cpp
+++ b/indra/llappearance/llavatarappearance.cpp
@@ -24,8 +24,13 @@
* $/LicenseInfo$
*/
-#include "linden_common.h"
+#if LL_MSVC
+// disable warning about boost::lexical_cast returning uninitialized data
+// when it fails to parse the string
+#pragma warning (disable:4701)
+#endif
+#include "linden_common.h"
#include "llavatarappearance.h"
#include "llavatarappearancedefines.h"
@@ -36,9 +41,20 @@
#include "llpolymorph.h"
#include "llpolymesh.h"
#include "llpolyskeletaldistortion.h"
+#include "llstl.h"
#include "lltexglobalcolor.h"
#include "llwearabledata.h"
+
+#if LL_MSVC
+// disable boost::lexical_cast warning
+#pragma warning (disable:4702)
+#endif
+
+#include <boost/lexical_cast.hpp>
+
+using namespace LLAvatarAppearanceDefines;
+
//-----------------------------------------------------------------------------
// Constants
//-----------------------------------------------------------------------------
@@ -153,7 +169,9 @@ LLAvatarAppearance::LLAvatarAppearance(LLWearableData* wearable_data) :
mWearableData(wearable_data)
{
- llassert(mWearableData);
+ LLMemType mt(LLMemType::MTYPE_AVATAR);
+
+ llassert_always(mWearableData);
mBakedTextureDatas.resize(LLAvatarAppearanceDefines::BAKED_NUM_INDICES);
for (U32 i = 0; i < mBakedTextureDatas.size(); i++ )
{
@@ -167,13 +185,85 @@ LLAvatarAppearance::LLAvatarAppearance(LLWearableData* wearable_data) :
mIsBuilt = FALSE;
- mNumJoints = 0;
- mSkeleton = NULL;
-
mNumCollisionVolumes = 0;
mCollisionVolumes = NULL;
+}
+
+// virtual
+void LLAvatarAppearance::initInstance()
+{
+ //-------------------------------------------------------------------------
+ // initialize joint, mesh and shape members
+ //-------------------------------------------------------------------------
+ mRoot = createAvatarJoint();
+ mRoot->setName( "mRoot" );
+
+ for (LLAvatarAppearanceDictionary::MeshEntries::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getMeshEntries().begin();
+ iter != LLAvatarAppearanceDictionary::getInstance()->getMeshEntries().end();
+ ++iter)
+ {
+ const EMeshIndex mesh_index = iter->first;
+ const LLAvatarAppearanceDictionary::MeshEntry *mesh_dict = iter->second;
+ LLAvatarJoint* joint = createAvatarJoint();
+ joint->setName(mesh_dict->mName);
+ joint->setMeshID(mesh_index);
+ mMeshLOD.push_back(joint);
+
+ /* mHairLOD.setName("mHairLOD");
+ mHairMesh0.setName("mHairMesh0");
+ mHairMesh0.setMeshID(MESH_ID_HAIR);
+ mHairMesh1.setName("mHairMesh1"); */
+ for (U32 lod = 0; lod < mesh_dict->mLOD; lod++)
+ {
+ LLAvatarJointMesh* mesh = createAvatarJointMesh();
+ std::string mesh_name = "m" + mesh_dict->mName + boost::lexical_cast<std::string>(lod);
+ // We pre-pended an m - need to capitalize first character for camelCase
+ mesh_name[1] = toupper(mesh_name[1]);
+ mesh->setName(mesh_name);
+ mesh->setMeshID(mesh_index);
+ mesh->setPickName(mesh_dict->mPickName);
+ mesh->setIsTransparent(FALSE);
+ switch((int)mesh_index)
+ {
+ case MESH_ID_HAIR:
+ mesh->setIsTransparent(TRUE);
+ break;
+ case MESH_ID_SKIRT:
+ mesh->setIsTransparent(TRUE);
+ break;
+ case MESH_ID_EYEBALL_LEFT:
+ case MESH_ID_EYEBALL_RIGHT:
+ mesh->setSpecular( LLColor4( 1.0f, 1.0f, 1.0f, 1.0f ), 1.f );
+ break;
+ }
+
+ joint->mMeshParts.push_back(mesh);
+ }
+ }
- mRoot = new LLAvatarJoint();
+ //-------------------------------------------------------------------------
+ // associate baked textures with meshes
+ //-------------------------------------------------------------------------
+ for (LLAvatarAppearanceDictionary::MeshEntries::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getMeshEntries().begin();
+ iter != LLAvatarAppearanceDictionary::getInstance()->getMeshEntries().end();
+ ++iter)
+ {
+ const EMeshIndex mesh_index = iter->first;
+ const LLAvatarAppearanceDictionary::MeshEntry *mesh_dict = iter->second;
+ const EBakedTextureIndex baked_texture_index = mesh_dict->mBakedID;
+ // Skip it if there's no associated baked texture.
+ if (baked_texture_index == BAKED_NUM_INDICES) continue;
+
+ for (avatar_joint_mesh_list_t::iterator iter = mMeshLOD[mesh_index]->mMeshParts.begin();
+ iter != mMeshLOD[mesh_index]->mMeshParts.end();
+ ++iter)
+ {
+ LLAvatarJointMesh* mesh = (*iter);
+ mBakedTextureDatas[(int)baked_texture_index].mJointMeshes.push_back(mesh);
+ }
+ }
+
+ buildCharacter();
}
@@ -187,7 +277,7 @@ LLAvatarAppearance::~LLAvatarAppearance()
for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
{
deleteAndClear(mBakedTextureDatas[i].mTexLayerSet);
- mBakedTextureDatas[i].mMeshes.clear();
+ mBakedTextureDatas[i].mJointMeshes.clear();
for (morph_list_t::iterator iter2 = mBakedTextureDatas[i].mMaskedMorphs.begin();
iter2 != mBakedTextureDatas[i].mMaskedMorphs.end(); iter2++)
@@ -200,23 +290,21 @@ LLAvatarAppearance::~LLAvatarAppearance()
mRoot->removeAllChildren();
mJointMap.clear();
- deleteAndClearArray(mSkeleton);
+ clearSkeleton();
deleteAndClearArray(mCollisionVolumes);
- mNumJoints = 0;
-
deleteAndClear(mTexSkinColor);
deleteAndClear(mTexHairColor);
deleteAndClear(mTexEyeColor);
- std::for_each(mMeshes.begin(), mMeshes.end(), DeletePairedPointer());
- mMeshes.clear();
+ std::for_each(mPolyMeshes.begin(), mPolyMeshes.end(), DeletePairedPointer());
+ mPolyMeshes.clear();
- for (std::vector<LLAvatarJoint*>::iterator jointIter = mMeshLOD.begin();
+ for (avatar_joint_list_t::iterator jointIter = mMeshLOD.begin();
jointIter != mMeshLOD.end();
++jointIter)
{
- LLAvatarJoint* joint = (LLAvatarJoint *) *jointIter;
+ LLAvatarJoint* joint = *jointIter;
std::for_each(joint->mMeshParts.begin(), joint->mMeshParts.end(), DeletePointer());
joint->mMeshParts.clear();
}
@@ -505,6 +593,22 @@ BOOL LLAvatarAppearance::setupBone(const LLAvatarBoneInfo* info, LLJoint* parent
}
//-----------------------------------------------------------------------------
+// allocateCharacterJoints()
+//-----------------------------------------------------------------------------
+BOOL LLAvatarAppearance::allocateCharacterJoints( U32 num )
+{
+ clearSkeleton();
+
+ for(S32 joint_num = 0; joint_num < (S32)num; joint_num++)
+ {
+ mSkeleton.push_back(createAvatarJoint(joint_num));
+ }
+
+ return TRUE;
+}
+
+
+//-----------------------------------------------------------------------------
// buildSkeleton()
//-----------------------------------------------------------------------------
BOOL LLAvatarAppearance::buildSkeleton(const LLAvatarSkeletonInfo *info)
@@ -549,6 +653,15 @@ BOOL LLAvatarAppearance::buildSkeleton(const LLAvatarSkeletonInfo *info)
}
//-----------------------------------------------------------------------------
+// clearSkeleton()
+//-----------------------------------------------------------------------------
+void LLAvatarAppearance::clearSkeleton()
+{
+ std::for_each(mSkeleton.begin(), mSkeleton.end(), DeletePointer());
+ mSkeleton.clear();
+}
+
+//-----------------------------------------------------------------------------
// LLAvatarAppearance::buildCharacter()
// Deferred initialization and rebuild of the avatar.
//-----------------------------------------------------------------------------
@@ -570,6 +683,21 @@ void LLAvatarAppearance::buildCharacter()
mIsBuilt = FALSE;
//-------------------------------------------------------------------------
+ // clear mesh data
+ //-------------------------------------------------------------------------
+ for (avatar_joint_list_t::iterator jointIter = mMeshLOD.begin();
+ jointIter != mMeshLOD.end(); ++jointIter)
+ {
+ LLAvatarJoint* joint = *jointIter;
+ for (avatar_joint_mesh_list_t::iterator meshIter = joint->mMeshParts.begin();
+ meshIter != joint->mMeshParts.end(); ++meshIter)
+ {
+ LLAvatarJointMesh * mesh = *meshIter;
+ mesh->setMesh(NULL);
+ }
+ }
+
+ //-------------------------------------------------------------------------
// (re)load our skeleton and meshes
//-------------------------------------------------------------------------
LLTimer timer;
@@ -755,7 +883,7 @@ BOOL LLAvatarAppearance::loadAvatar()
}
- loadLayersets();
+ loadLayersets();
// avatar_lad.xml : <driver_parameters>
for (LLAvatarXmlInfo::driver_info_list_t::iterator iter = sAvatarXmlInfo->mDriverInfoList.begin();
@@ -791,7 +919,17 @@ BOOL LLAvatarAppearance::loadAvatar()
//-----------------------------------------------------------------------------
BOOL LLAvatarAppearance::loadSkeletonNode ()
{
- mRoot->addChild( &mSkeleton[0] );
+ mRoot->addChild( mSkeleton[0] );
+
+ // make meshes children before calling parent version of the function
+ for (avatar_joint_list_t::iterator iter = mMeshLOD.begin();
+ iter != mMeshLOD.end();
+ ++iter)
+ {
+ LLAvatarJoint *joint = *iter;
+ joint->mUpdateXform = FALSE;
+ joint->setMeshesToChildren();
+ }
mRoot->addChild(mMeshLOD[MESH_ID_HEAD]);
mRoot->addChild(mMeshLOD[MESH_ID_EYELASH]);
@@ -864,8 +1002,8 @@ BOOL LLAvatarAppearance::loadMeshNodes()
switch(lod)
case 0:
mesh = &mHairMesh0; */
- for (LLAvatarAppearanceDictionary::Meshes::const_iterator mesh_iter = LLAvatarAppearanceDictionary::getInstance()->getMeshes().begin();
- mesh_iter != LLAvatarAppearanceDictionary::getInstance()->getMeshes().end();
+ for (LLAvatarAppearanceDictionary::MeshEntries::const_iterator mesh_iter = LLAvatarAppearanceDictionary::getInstance()->getMeshEntries().begin();
+ mesh_iter != LLAvatarAppearanceDictionary::getInstance()->getMeshEntries().end();
++mesh_iter)
{
const EMeshIndex mesh_index = mesh_iter->first;
@@ -906,8 +1044,8 @@ BOOL LLAvatarAppearance::loadMeshNodes()
if (!info->mReferenceMeshName.empty())
{
- polymesh_map_t::const_iterator polymesh_iter = mMeshes.find(info->mReferenceMeshName);
- if (polymesh_iter != mMeshes.end())
+ polymesh_map_t::const_iterator polymesh_iter = mPolyMeshes.find(info->mReferenceMeshName);
+ if (polymesh_iter != mPolyMeshes.end())
{
poly_mesh = LLPolyMesh::getMesh(info->mMeshFileName, polymesh_iter->second);
poly_mesh->setAvatar(this);
@@ -931,7 +1069,7 @@ BOOL LLAvatarAppearance::loadMeshNodes()
}
// Multimap insert
- mMeshes.insert(std::make_pair(info->mMeshFileName, poly_mesh));
+ mPolyMeshes.insert(std::make_pair(info->mMeshFileName, poly_mesh));
mesh->setMesh( poly_mesh );
mesh->setLOD( info->mMinPixelArea );
@@ -974,15 +1112,72 @@ BOOL LLAvatarAppearance::loadLayersets()
layerset_iter != sAvatarXmlInfo->mLayerInfoList.end();
++layerset_iter)
{
- // Construct a layerset for each one specified in avatar_lad.xml and initialize it as such.
LLTexLayerSetInfo *layerset_info = *layerset_iter;
- layerset_info->createVisualParams(this);
+ if (isSelf())
+ {
+ // Construct a layerset for each one specified in avatar_lad.xml and initialize it as such.
+ LLTexLayerSet* layer_set = createTexLayerSet();
+
+ if (!layer_set->setInfo(layerset_info))
+ {
+ stop_glerror();
+ delete layer_set;
+ llwarns << "avatar file: layer_set->setInfo() failed" << llendl;
+ return FALSE;
+ }
+
+ // scan baked textures and associate the layerset with the appropriate one
+ EBakedTextureIndex baked_index = BAKED_NUM_INDICES;
+ for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().begin();
+ baked_iter != LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().end();
+ ++baked_iter)
+ {
+ const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = baked_iter->second;
+ if (layer_set->isBodyRegion(baked_dict->mName))
+ {
+ baked_index = baked_iter->first;
+ // ensure both structures are aware of each other
+ mBakedTextureDatas[baked_index].mTexLayerSet = layer_set;
+ layer_set->setBakedTexIndex(baked_index);
+ break;
+ }
+ }
+ // if no baked texture was found, warn and cleanup
+ if (baked_index == BAKED_NUM_INDICES)
+ {
+ llwarns << "<layer_set> has invalid body_region attribute" << llendl;
+ delete layer_set;
+ return FALSE;
+ }
+
+ // scan morph masks and let any affected layers know they have an associated morph
+ for (LLAvatarAppearance::morph_list_t::const_iterator morph_iter = mBakedTextureDatas[baked_index].mMaskedMorphs.begin();
+ morph_iter != mBakedTextureDatas[baked_index].mMaskedMorphs.end();
+ ++morph_iter)
+ {
+ LLMaskedMorph *morph = *morph_iter;
+ LLTexLayerInterface* layer = layer_set->findLayerByName(morph->mLayer);
+ if (layer)
+ {
+ layer->setHasMorph(TRUE);
+ }
+ else
+ {
+ llwarns << "Could not find layer named " << morph->mLayer << " to set morph flag" << llendl;
+ success = FALSE;
+ }
+ }
+ }
+ else // !isSelf()
+ {
+ // Construct a layerset for each one specified in avatar_lad.xml and initialize it as such.
+ LLTexLayerSetInfo *layerset_info = *layerset_iter;
+ layerset_info->createVisualParams(this);
+ }
}
return success;
}
-
-
// virtual
BOOL LLAvatarAppearance::isValid() const
{
diff --git a/indra/llappearance/llavatarappearance.h b/indra/llappearance/llavatarappearance.h
index 38a54d904d..96dd81be77 100644
--- a/indra/llappearance/llavatarappearance.h
+++ b/indra/llappearance/llavatarappearance.h
@@ -28,9 +28,8 @@
#define LL_AVATAR_APPEARANCE_H
#include "llcharacter.h"
-//#include "llframetimer.h"
#include "llavatarappearancedefines.h"
-#include "llavatarjoint.h"
+#include "llavatarjointmesh.h"
#include "lldriverparam.h"
#include "lltexlayer.h"
#include "llviewervisualparam.h"
@@ -67,9 +66,10 @@ public:
virtual ~LLAvatarAppearance();
static void initClass(); // initializes static members
+ virtual void initInstance(); // Called after construction to initialize the instance.
virtual BOOL loadSkeletonNode();
- virtual BOOL loadMeshNodes();
- virtual BOOL loadLayersets();
+ BOOL loadMeshNodes();
+ BOOL loadLayersets();
/** Initialization
@@ -97,8 +97,13 @@ public:
** SKELETON
**/
+protected:
+ virtual LLAvatarJoint* createAvatarJoint() = 0;
+ virtual LLAvatarJoint* createAvatarJoint(S32 joint_num) = 0;
+ virtual LLAvatarJointMesh* createAvatarJointMesh() = 0;
public:
F32 getPelvisToFoot() const { return mPelvisToFoot; }
+ /*virtual*/ LLJoint* getRootJoint() { return mRoot; }
LLVector3 mHeadOffset; // current head position
LLAvatarJoint *mRoot;
@@ -114,11 +119,13 @@ protected:
void computeBodySize();
BOOL setupBone(const LLAvatarBoneInfo* info, LLJoint* parent, S32 &current_volume_num, S32 &current_joint_num);
+ BOOL allocateCharacterJoints(U32 num);
BOOL buildSkeleton(const LLAvatarSkeletonInfo *info);
protected:
+ void clearSkeleton();
BOOL mIsBuilt; // state of deferred character building
- S32 mNumJoints;
- LLJoint* mSkeleton;
+ typedef std::vector<LLAvatarJoint*> avatar_joint_list_t;
+ avatar_joint_list_t mSkeleton;
//--------------------------------------------------------------------
// Pelvis height adjustment members.
@@ -204,8 +211,8 @@ protected:
protected:
typedef std::multimap<std::string, LLPolyMesh*> polymesh_map_t;
- polymesh_map_t mMeshes;
- std::vector<LLAvatarJoint *> mMeshLOD;
+ polymesh_map_t mPolyMeshes;
+ avatar_joint_list_t mMeshLOD;
/** Meshes
** **
@@ -263,6 +270,8 @@ private:
** BAKED TEXTURES
**/
protected:
+ virtual LLTexLayerSet* createTexLayerSet() = 0;
+protected:
struct LLMaskedMorph;
typedef std::deque<LLMaskedMorph *> morph_list_t;
struct BakedTextureData
@@ -274,7 +283,7 @@ protected:
LLAvatarAppearanceDefines::ETextureIndex mTextureIndex;
U32 mMaskTexName;
// Stores pointers to the joint meshes that this baked texture deals with
- std::vector< LLJoint* > mMeshes; // std::vector<LLViewerJointMesh> mJoints[i]->mMeshParts
+ avatar_joint_mesh_list_t mJointMeshes;
morph_list_t mMaskedMorphs;
};
typedef std::vector<BakedTextureData> bakedtexturedata_vec_t;
diff --git a/indra/llappearance/llavatarappearancedefines.cpp b/indra/llappearance/llavatarappearancedefines.cpp
index 2c3cf781c1..0416309fc7 100644
--- a/indra/llappearance/llavatarappearancedefines.cpp
+++ b/indra/llappearance/llavatarappearancedefines.cpp
@@ -109,9 +109,9 @@ LLAvatarAppearanceDictionary::BakedTextures::BakedTextures()
2, LLWearableType::WT_HAIR, LLWearableType::WT_ALPHA));
}
-LLAvatarAppearanceDictionary::Meshes::Meshes()
+LLAvatarAppearanceDictionary::MeshEntries::MeshEntries()
{
- // Meshes
+ // MeshEntries
addEntry(MESH_ID_HAIR, new MeshEntry(BAKED_HAIR, "hairMesh", 6, PN_4));
addEntry(MESH_ID_HEAD, new MeshEntry(BAKED_HEAD, "headMesh", 5, PN_5));
addEntry(MESH_ID_EYELASH, new MeshEntry(BAKED_HEAD, "eyelashMesh", 1, PN_0)); // no baked mesh associated currently
diff --git a/indra/llappearance/llavatarappearancedefines.h b/indra/llappearance/llavatarappearancedefines.h
index c5285ddc02..e7c94104cc 100644
--- a/indra/llappearance/llavatarappearancedefines.h
+++ b/indra/llappearance/llavatarappearancedefines.h
@@ -174,12 +174,12 @@ public:
const LLJointPickName mPickName;
};
- struct Meshes : public LLDictionary<EMeshIndex, MeshEntry>
+ struct MeshEntries : public LLDictionary<EMeshIndex, MeshEntry>
{
- Meshes();
- } mMeshes;
- const MeshEntry* getMesh(EMeshIndex index) const { return mMeshes.lookup(index); }
- const Meshes& getMeshes() const { return mMeshes; }
+ MeshEntries();
+ } mMeshEntries;
+ const MeshEntry* getMeshEntry(EMeshIndex index) const { return mMeshEntries.lookup(index); }
+ const MeshEntries& getMeshEntries() const { return mMeshEntries; }
//--------------------------------------------------------------------
// Baked Textures
diff --git a/indra/llappearance/llavatarjoint.cpp b/indra/llappearance/llavatarjoint.cpp
index 809a261633..eb450485c7 100644
--- a/indra/llappearance/llavatarjoint.cpp
+++ b/indra/llappearance/llavatarjoint.cpp
@@ -33,13 +33,9 @@
#include "llrender.h"
#include "llmath.h"
#include "llglheaders.h"
-#include "llrendersphere.h"
#include "llavatarappearance.h"
-//#include "pipeline.h"
-#define DEFAULT_LOD 0.0f
-
-const S32 MIN_PIXEL_AREA_3PASS_HAIR = 64*64;
+const F32 DEFAULT_AVATAR_JOINT_LOD = 0.0f;
//-----------------------------------------------------------------------------
// Static Data
@@ -48,21 +44,22 @@ BOOL LLAvatarJoint::sDisableLOD = FALSE;
//-----------------------------------------------------------------------------
// LLAvatarJoint()
-// Class Constructor
+// Class Constructors
//-----------------------------------------------------------------------------
-LLAvatarJoint::LLAvatarJoint()
- : LLJoint()
+LLAvatarJoint::LLAvatarJoint() :
+ LLJoint()
{
init();
}
+LLAvatarJoint::LLAvatarJoint(const std::string &name, LLJoint *parent) :
+ LLJoint(name, parent)
+{
+ init();
+}
-//-----------------------------------------------------------------------------
-// LLAvatarJoint()
-// Class Constructor
-//-----------------------------------------------------------------------------
-LLAvatarJoint::LLAvatarJoint(const std::string &name, LLJoint *parent)
- : LLJoint(name, parent)
+LLAvatarJoint::LLAvatarJoint(S32 joint_num) :
+ LLJoint(joint_num)
{
init();
}
@@ -72,7 +69,7 @@ void LLAvatarJoint::init()
{
mValid = FALSE;
mComponents = SC_JOINT | SC_BONE | SC_AXES;
- mMinPixelArea = DEFAULT_LOD;
+ mMinPixelArea = DEFAULT_AVATAR_JOINT_LOD;
mPickName = PN_DEFAULT;
mVisible = TRUE;
mMeshID = 0;
@@ -114,14 +111,6 @@ void LLAvatarJoint::setValid( BOOL valid, BOOL recursive )
}
//--------------------------------------------------------------------
-// isTransparent()
-//--------------------------------------------------------------------
-BOOL LLAvatarJoint::isTransparent()
-{
- return FALSE;
-}
-
-//--------------------------------------------------------------------
// setSkeletonComponents()
//--------------------------------------------------------------------
void LLAvatarJoint::setSkeletonComponents( U32 comp, BOOL recursive )
@@ -132,7 +121,7 @@ void LLAvatarJoint::setSkeletonComponents( U32 comp, BOOL recursive )
for (child_list_t::iterator iter = mChildren.begin();
iter != mChildren.end(); ++iter)
{
- LLAvatarJoint* joint = (LLAvatarJoint*)(*iter);
+ LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter);
joint->setSkeletonComponents(comp, recursive);
}
}
@@ -153,14 +142,87 @@ void LLAvatarJoint::setVisible(BOOL visible, BOOL recursive)
}
}
+void LLAvatarJoint::updateFaceSizes(U32 &num_vertices, U32& num_indices, F32 pixel_area)
+{
+ for (child_list_t::iterator iter = mChildren.begin();
+ iter != mChildren.end(); ++iter)
+ {
+ LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter);
+ joint->updateFaceSizes(num_vertices, num_indices, pixel_area);
+ }
+}
+
+void LLAvatarJoint::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind, bool terse_update)
+{
+ for (child_list_t::iterator iter = mChildren.begin();
+ iter != mChildren.end(); ++iter)
+ {
+ LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter);
+ joint->updateFaceData(face, pixel_area, damp_wind, terse_update);
+ }
+}
+
+void LLAvatarJoint::updateJointGeometry()
+{
+ for (child_list_t::iterator iter = mChildren.begin();
+ iter != mChildren.end(); ++iter)
+ {
+ LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter);
+ joint->updateJointGeometry();
+ }
+}
+
+
+BOOL LLAvatarJoint::updateLOD(F32 pixel_area, BOOL activate)
+{
+ BOOL lod_changed = FALSE;
+ BOOL found_lod = FALSE;
+
+ for (child_list_t::iterator iter = mChildren.begin();
+ iter != mChildren.end(); ++iter)
+ {
+ LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter);
+ F32 jointLOD = joint->getLOD();
+
+ if (found_lod || jointLOD == DEFAULT_AVATAR_JOINT_LOD)
+ {
+ // we've already found a joint to enable, so enable the rest as alternatives
+ lod_changed |= joint->updateLOD(pixel_area, TRUE);
+ }
+ else
+ {
+ if (pixel_area >= jointLOD || sDisableLOD)
+ {
+ lod_changed |= joint->updateLOD(pixel_area, TRUE);
+ found_lod = TRUE;
+ }
+ else
+ {
+ lod_changed |= joint->updateLOD(pixel_area, FALSE);
+ }
+ }
+ }
+ return lod_changed;
+}
+
+void LLAvatarJoint::dump()
+{
+ for (child_list_t::iterator iter = mChildren.begin();
+ iter != mChildren.end(); ++iter)
+ {
+ LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter);
+ joint->dump();
+ }
+}
+
void LLAvatarJoint::setMeshesToChildren()
{
removeAllChildren();
- for (std::vector<LLAvatarJointMesh*>::iterator iter = mMeshParts.begin();
+ for (avatar_joint_mesh_list_t::iterator iter = mMeshParts.begin();
iter != mMeshParts.end(); iter++)
{
- addChild((LLAvatarJoint*) *iter);
+ addChild((*iter));
}
}
//-----------------------------------------------------------------------------
@@ -172,9 +234,11 @@ LLAvatarJointCollisionVolume::LLAvatarJointCollisionVolume()
mUpdateXform = FALSE;
}
-LLAvatarJointCollisionVolume::LLAvatarJointCollisionVolume(const std::string &name, LLJoint *parent) : LLAvatarJoint(name, parent)
+/*virtual*/
+U32 LLAvatarJointCollisionVolume::render( F32 pixelArea, BOOL first_pass, BOOL is_dummy )
{
-
+ llerrs << "Cannot call render() on LLAvatarJointCollisionVolume" << llendl;
+ return 0;
}
LLVector3 LLAvatarJointCollisionVolume::getVolumePos(LLVector3 &offset)
diff --git a/indra/llappearance/llavatarjoint.h b/indra/llappearance/llavatarjoint.h
index cbfc1b73ea..1dfbd37456 100644
--- a/indra/llappearance/llavatarjoint.h
+++ b/indra/llappearance/llavatarjoint.h
@@ -36,6 +36,8 @@
class LLFace;
class LLAvatarJointMesh;
+extern const F32 DEFAULT_AVATAR_JOINT_LOD;
+
//-----------------------------------------------------------------------------
// class LLViewerJoint
//-----------------------------------------------------------------------------
@@ -44,6 +46,8 @@ class LLAvatarJoint :
{
public:
LLAvatarJoint();
+ LLAvatarJoint(S32 joint_num);
+ // *TODO: Only used for LLVOAvatarSelf::mScreenp. *DOES NOT INITIALIZE mResetAfterRestoreOldXform*
LLAvatarJoint(const std::string &name, LLJoint *parent = NULL);
virtual ~LLAvatarJoint();
@@ -55,12 +59,11 @@ public:
// Returns true if this object is transparent.
// This is used to determine in which order to draw objects.
- virtual BOOL isTransparent();
+ virtual BOOL isTransparent() { return FALSE; }
// Returns true if this object should inherit scale modifiers from its immediate parent
virtual BOOL inheritScale() { return FALSE; }
-
enum Components
{
SC_BONE = 1,
@@ -83,7 +86,7 @@ public:
// of this node under the same parent will be.
F32 getLOD() { return mMinPixelArea; }
void setLOD( F32 pixelArea ) { mMinPixelArea = pixelArea; }
-
+
void setPickName(LLJointPickName name) { mPickName = name; }
LLJointPickName getPickName() { return mPickName; }
@@ -92,9 +95,18 @@ public:
// Takes meshes in mMeshParts and sets each one as a child joint
void setMeshesToChildren();
+ // LLViewerJoint interface
+ virtual U32 render( F32 pixelArea, BOOL first_pass = TRUE, BOOL is_dummy = FALSE ) = 0;
+ virtual void updateFaceSizes(U32 &num_vertices, U32& num_indices, F32 pixel_area);
+ virtual void updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind = FALSE, bool terse_update = false);
+ virtual BOOL updateLOD(F32 pixel_area, BOOL activate);
+ virtual void updateJointGeometry();
+ virtual void dump();
+
+
public:
static BOOL sDisableLOD;
- std::vector<LLAvatarJointMesh*> mMeshParts; //LLViewerJointMesh*
+ avatar_joint_mesh_list_t mMeshParts; //LLViewerJointMesh*
void setMeshID( S32 id ) {mMeshID = id;}
protected:
@@ -112,10 +124,10 @@ class LLAvatarJointCollisionVolume : public LLAvatarJoint
{
public:
LLAvatarJointCollisionVolume();
- LLAvatarJointCollisionVolume(const std::string &name, LLJoint *parent = NULL);
virtual ~LLAvatarJointCollisionVolume() {};
- virtual BOOL inheritScale() { return TRUE; }
+ /*virtual*/ BOOL inheritScale() { return TRUE; }
+ /*virtual*/ U32 render( F32 pixelArea, BOOL first_pass = TRUE, BOOL is_dummy = FALSE );
void renderCollision();
diff --git a/indra/llappearance/llavatarjointmesh.cpp b/indra/llappearance/llavatarjointmesh.cpp
index 92c213126a..d39587defe 100755
--- a/indra/llappearance/llavatarjointmesh.cpp
+++ b/indra/llappearance/llavatarjointmesh.cpp
@@ -233,6 +233,12 @@ void LLAvatarJointMesh::setTexture( LLGLTexture *texture )
}
}
+
+BOOL LLAvatarJointMesh::hasGLTexture() const
+{
+ return mTexture.notNull() && mTexture->hasGLTexture();
+}
+
//--------------------------------------------------------------------
// LLAvatarJointMesh::setLayerSet()
// Sets the shape texture (takes precedence over normal texture)
@@ -248,6 +254,10 @@ void LLAvatarJointMesh::setLayerSet( LLTexLayerSet* layer_set )
}
}
+BOOL LLAvatarJointMesh::hasComposite() const
+{
+ return (mLayerSet && mLayerSet->hasComposite());
+}
//--------------------------------------------------------------------
diff --git a/indra/llappearance/llavatarjointmesh.h b/indra/llappearance/llavatarjointmesh.h
index dcd202bdaf..4b56a168ac 100755
--- a/indra/llappearance/llavatarjointmesh.h
+++ b/indra/llappearance/llavatarjointmesh.h
@@ -59,9 +59,8 @@ public:
//-----------------------------------------------------------------------------
// class LLViewerJointMesh
//-----------------------------------------------------------------------------
-class LLAvatarJointMesh : public LLAvatarJoint
+class LLAvatarJointMesh : public virtual LLAvatarJoint
{
- friend class LLAvatarAppearance;
protected:
LLColor4 mColor; // color value
// LLColor4 mSpecular; // specular color (always white for now)
@@ -94,6 +93,9 @@ public:
// Destructor
virtual ~LLAvatarJointMesh();
+ // overloaded from base class
+ /*virtual*/ BOOL isTransparent() { return mIsTransparent; }
+
// Gets the shape color
void getColor( F32 *red, F32 *green, F32 *blue, F32 *alpha );
@@ -106,11 +108,15 @@ public:
// Sets the shape texture
void setTexture( LLGLTexture *texture );
+ BOOL hasGLTexture() const;
+
void setTestTexture( U32 name ) { mTestImageName = name; }
// Sets layer set responsible for a dynamic shape texture (takes precedence over normal texture)
void setLayerSet( LLTexLayerSet* layer_set );
+ BOOL hasComposite() const;
+
// Gets the poly mesh
LLPolyMesh *getMesh();
@@ -129,6 +135,8 @@ public:
// Gets ID for picking
S32 getMeshID() { return mMeshID; }
+ void setIsTransparent(BOOL is_transparent) { mIsTransparent = is_transparent; }
+
private:
// Allocate skin data
BOOL allocateSkinData( U32 numSkinJoints );
diff --git a/indra/llappearance/lljointpickname.h b/indra/llappearance/lljointpickname.h
index 17181520e3..1d41a761fc 100644
--- a/indra/llappearance/lljointpickname.h
+++ b/indra/llappearance/lljointpickname.h
@@ -28,6 +28,7 @@
#ifndef LL_LLJOINTPICKNAME_H
#define LL_LLJOINTPICKNAME_H
+class LLAvatarJointMesh;
// Sets the OpenGL selection stack name that is pushed and popped
// with this joint state. The default value indicates that no name
@@ -43,4 +44,6 @@ enum LLJointPickName
PN_5 = 5
};
+typedef std::vector<LLAvatarJointMesh*> avatar_joint_mesh_list_t;
+
#endif // LL_LLJOINTPICKNAME_H