diff options
| author | Nyx (Neal Orman) <nyx@lindenlab.com> | 2012-09-07 23:17:34 -0400 | 
|---|---|---|
| committer | Nyx (Neal Orman) <nyx@lindenlab.com> | 2012-09-07 23:17:34 -0400 | 
| commit | 77b33d9623c08152932282048fe847d79fcf43cd (patch) | |
| tree | a7876f588a95861047de6d9981876395dcd7cf2e | |
| parent | 2e933100bb6bf27c0307dc6831142dcc0860fb7b (diff) | |
SH-3264 Porting over the XML loading of the avatar structure to llappearance
Moved over the necessary classes to llappearance to support the loading of the
avatar's structure & params from file.
30 files changed, 4045 insertions, 2413 deletions
diff --git a/indra/llappearance/CMakeLists.txt b/indra/llappearance/CMakeLists.txt index 41da898457..c5a855a505 100644 --- a/indra/llappearance/CMakeLists.txt +++ b/indra/llappearance/CMakeLists.txt @@ -42,9 +42,14 @@ include_directories(  set(llappearance_SOURCE_FILES      llavatarappearance.cpp +    llavatarjoint.cpp +    llavatarjointmesh.cpp      lldriverparam.cpp      llinventoryicon.cpp      lllocaltextureobject.cpp +    llpolyskeletaldistortion.cpp +    llpolymesh.cpp +    llpolymorph.cpp      lltexglobalcolor.cpp      lltexlayer.cpp      lltexlayerparams.cpp @@ -60,10 +65,15 @@ set(llappearance_HEADER_FILES      CMakeLists.txt      llavatarappearance.h +    llavatarjoint.h +    llavatarjointmesh.h      lldriverparam.h      llinventoryicon.h      lljointpickname.h      lllocaltextureobject.h +    llpolyskeletaldistortion.h +    llpolymesh.h +    llpolymorph.h      lltexglobalcolor.h      lltexlayer.h      lltexlayerparams.h diff --git a/indra/llappearance/llavatarappearance.cpp b/indra/llappearance/llavatarappearance.cpp index 2c03f8ba02..406e6153e0 100644 --- a/indra/llappearance/llavatarappearance.cpp +++ b/indra/llappearance/llavatarappearance.cpp @@ -29,19 +29,128 @@  #include "llavatarappearance.h"  #include "llavatarappearancedefines.h" +#include "llavatarjointmesh.h"  #include "imageids.h" +#include "lldir.h"  #include "lldeleteutils.h" +#include "llpolymorph.h" +#include "llpolymesh.h" +#include "llpolyskeletaldistortion.h"  #include "lltexglobalcolor.h"  #include "llwearabledata.h" +//----------------------------------------------------------------------------- +// Constants +//----------------------------------------------------------------------------- + +const std::string AVATAR_DEFAULT_CHAR = "avatar";  const LLColor4 DUMMY_COLOR = LLColor4(0.5,0.5,0.5,1.0); +/********************************************************************************* + **                                                                             ** + ** Begin private LLAvatarAppearance Support classes + ** + **/ + +//------------------------------------------------------------------------ +// LLAvatarBoneInfo +// Trans/Scale/Rot etc. info about each avatar bone.  Used by LLVOAvatarSkeleton. +//------------------------------------------------------------------------ +class LLAvatarBoneInfo +{ +	friend class LLAvatarAppearance; +	friend class LLAvatarSkeletonInfo; +public: +	LLAvatarBoneInfo() : mIsJoint(FALSE) {} +	~LLAvatarBoneInfo() +	{ +		std::for_each(mChildList.begin(), mChildList.end(), DeletePointer()); +	} +	BOOL parseXml(LLXmlTreeNode* node); +	 +private: +	std::string mName; +	BOOL mIsJoint; +	LLVector3 mPos; +	LLVector3 mRot; +	LLVector3 mScale; +	LLVector3 mPivot; +	typedef std::vector<LLAvatarBoneInfo*> child_list_t; +	child_list_t mChildList; +}; + +//------------------------------------------------------------------------ +// LLAvatarSkeletonInfo +// Overall avatar skeleton +//------------------------------------------------------------------------ +class LLAvatarSkeletonInfo +{ +	friend class LLAvatarAppearance; +public: +	LLAvatarSkeletonInfo() : +		mNumBones(0), mNumCollisionVolumes(0) {} +	~LLAvatarSkeletonInfo() +	{ +		std::for_each(mBoneInfoList.begin(), mBoneInfoList.end(), DeletePointer()); +	} +	BOOL parseXml(LLXmlTreeNode* node); +	S32 getNumBones() const { return mNumBones; } +	S32 getNumCollisionVolumes() const { return mNumCollisionVolumes; } +	 +private: +	S32 mNumBones; +	S32 mNumCollisionVolumes; +	typedef std::vector<LLAvatarBoneInfo*> bone_info_list_t; +	bone_info_list_t mBoneInfoList; +}; + +//----------------------------------------------------------------------------- +// LLAvatarXmlInfo +//----------------------------------------------------------------------------- + +LLAvatarAppearance::LLAvatarXmlInfo::LLAvatarXmlInfo() +	: mTexSkinColorInfo(0), mTexHairColorInfo(0), mTexEyeColorInfo(0) +{ +} + +LLAvatarAppearance::LLAvatarXmlInfo::~LLAvatarXmlInfo() +{ +	std::for_each(mMeshInfoList.begin(), mMeshInfoList.end(), DeletePointer()); +	std::for_each(mSkeletalDistortionInfoList.begin(), mSkeletalDistortionInfoList.end(), DeletePointer());		 +	std::for_each(mAttachmentInfoList.begin(), mAttachmentInfoList.end(), DeletePointer()); +	deleteAndClear(mTexSkinColorInfo); +	deleteAndClear(mTexHairColorInfo); +	deleteAndClear(mTexEyeColorInfo); +	std::for_each(mLayerInfoList.begin(), mLayerInfoList.end(), DeletePointer());		 +	std::for_each(mDriverInfoList.begin(), mDriverInfoList.end(), DeletePointer()); +	std::for_each(mMorphMaskInfoList.begin(), mMorphMaskInfoList.end(), DeletePointer()); +} + + +/** + ** + ** End LLAvatarAppearance Support classes + **                                                                             ** + *********************************************************************************/ + +//----------------------------------------------------------------------------- +// Static Data +//----------------------------------------------------------------------------- +LLXmlTree LLAvatarAppearance::sXMLTree; +LLXmlTree LLAvatarAppearance::sSkeletonXMLTree; +LLAvatarSkeletonInfo* LLAvatarAppearance::sAvatarSkeletonInfo = NULL; +LLAvatarAppearance::LLAvatarXmlInfo* LLAvatarAppearance::sAvatarXmlInfo = NULL; + +  LLAvatarAppearance::LLAvatarAppearance(LLWearableData* wearable_data) :  	LLCharacter(),  	mIsDummy(FALSE),  	mTexSkinColor( NULL ),  	mTexHairColor( NULL ),  	mTexEyeColor( NULL ), +	mPelvisToFoot(0.f), +	mHeadOffset(), +  	mWearableData(wearable_data)  {  	llassert(mWearableData); @@ -55,6 +164,17 @@ LLAvatarAppearance::LLAvatarAppearance(LLWearableData* wearable_data) :  		mBakedTextureDatas[i].mMaskTexName = 0;  		mBakedTextureDatas[i].mTextureIndex = LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::bakedToLocalTextureIndex((LLAvatarAppearanceDefines::EBakedTextureIndex)i);  	} + +	mIsBuilt = FALSE; + +	mNumJoints = 0; +	mSkeleton = NULL; + +	mNumCollisionVolumes = 0; +	mCollisionVolumes = NULL; + +	mRoot = new LLAvatarJoint(); +  }  // virtual @@ -76,10 +196,793 @@ LLAvatarAppearance::~LLAvatarAppearance()  			delete masked_morph;  		}  	} + +	mRoot->removeAllChildren(); +	mJointMap.clear(); + +	deleteAndClearArray(mSkeleton); +	deleteAndClearArray(mCollisionVolumes); + +	mNumJoints = 0; + +	deleteAndClear(mTexSkinColor); +	deleteAndClear(mTexHairColor); +	deleteAndClear(mTexEyeColor); + +	std::for_each(mMeshes.begin(), mMeshes.end(), DeletePairedPointer()); +	mMeshes.clear(); + +	for (std::vector<LLAvatarJoint*>::iterator jointIter = mMeshLOD.begin(); +		 jointIter != mMeshLOD.end();  +		 ++jointIter) +	{ +		LLAvatarJoint* joint = (LLAvatarJoint *) *jointIter; +		std::for_each(joint->mMeshParts.begin(), joint->mMeshParts.end(), DeletePointer()); +		joint->mMeshParts.clear(); +	} +	std::for_each(mMeshLOD.begin(), mMeshLOD.end(), DeletePointer()); +	mMeshLOD.clear(); +} + +//static +void LLAvatarAppearance::initClass() +{ +	std::string xmlFile; + +	xmlFile = gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,AVATAR_DEFAULT_CHAR) + "_lad.xml"; +	BOOL success = sXMLTree.parseFile( xmlFile, FALSE ); +	if (!success) +	{ +		llerrs << "Problem reading avatar configuration file:" << xmlFile << llendl; +	} + +	// now sanity check xml file +	LLXmlTreeNode* root = sXMLTree.getRoot(); +	if (!root)  +	{ +		llerrs << "No root node found in avatar configuration file: " << xmlFile << llendl; +		return; +	} + +	//------------------------------------------------------------------------- +	// <linden_avatar version="1.0"> (root) +	//------------------------------------------------------------------------- +	if( !root->hasName( "linden_avatar" ) ) +	{ +		llerrs << "Invalid avatar file header: " << xmlFile << llendl; +	} +	 +	std::string version; +	static LLStdStringHandle version_string = LLXmlTree::addAttributeString("version"); +	if( !root->getFastAttributeString( version_string, version ) || (version != "1.0") ) +	{ +		llerrs << "Invalid avatar file version: " << version << " in file: " << xmlFile << llendl; +	} + +	S32 wearable_def_version = 1; +	static LLStdStringHandle wearable_definition_version_string = LLXmlTree::addAttributeString("wearable_definition_version"); +	root->getFastAttributeS32( wearable_definition_version_string, wearable_def_version ); +	LLWearable::setCurrentDefinitionVersion( wearable_def_version ); + +	std::string mesh_file_name; + +	LLXmlTreeNode* skeleton_node = root->getChildByName( "skeleton" ); +	if (!skeleton_node) +	{ +		llerrs << "No skeleton in avatar configuration file: " << xmlFile << llendl; +		return; +	} +	 +	std::string skeleton_file_name; +	static LLStdStringHandle file_name_string = LLXmlTree::addAttributeString("file_name"); +	if (!skeleton_node->getFastAttributeString(file_name_string, skeleton_file_name)) +	{ +		llerrs << "No file name in skeleton node in avatar config file: " << xmlFile << llendl; +	} +	 +	std::string skeleton_path; +	skeleton_path = gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,skeleton_file_name); +	if (!parseSkeletonFile(skeleton_path)) +	{ +		llerrs << "Error parsing skeleton file: " << skeleton_path << llendl; +	} + +	// Process XML data + +	// avatar_skeleton.xml +	if (sAvatarSkeletonInfo) +	{ //this can happen if a login attempt failed +		delete sAvatarSkeletonInfo; +	} +	sAvatarSkeletonInfo = new LLAvatarSkeletonInfo; +	if (!sAvatarSkeletonInfo->parseXml(sSkeletonXMLTree.getRoot())) +	{ +		llerrs << "Error parsing skeleton XML file: " << skeleton_path << llendl; +	} +	// parse avatar_lad.xml +	if (sAvatarXmlInfo) +	{ //this can happen if a login attempt failed +		deleteAndClear(sAvatarXmlInfo); +	} +	sAvatarXmlInfo = new LLAvatarXmlInfo; +	if (!sAvatarXmlInfo->parseXmlSkeletonNode(root)) +	{ +		llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl; +	} +	if (!sAvatarXmlInfo->parseXmlMeshNodes(root)) +	{ +		llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl; +	} +	if (!sAvatarXmlInfo->parseXmlColorNodes(root)) +	{ +		llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl; +	} +	if (!sAvatarXmlInfo->parseXmlLayerNodes(root)) +	{ +		llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl; +	} +	if (!sAvatarXmlInfo->parseXmlDriverNodes(root)) +	{ +		llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl; +	} +	if (!sAvatarXmlInfo->parseXmlMorphNodes(root)) +	{ +		llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl; +	}  }  using namespace LLAvatarAppearanceDefines; +//------------------------------------------------------------------------ +// The viewer can only suggest a good size for the agent, +// the simulator will keep it inside a reasonable range. +void LLAvatarAppearance::computeBodySize()  +{ +	LLVector3 pelvis_scale = mPelvisp->getScale(); + +	// some of the joints have not been cached +	LLVector3 skull = mSkullp->getPosition(); +	LLVector3 skull_scale = mSkullp->getScale(); + +	LLVector3 neck = mNeckp->getPosition(); +	LLVector3 neck_scale = mNeckp->getScale(); + +	LLVector3 chest = mChestp->getPosition(); +	LLVector3 chest_scale = mChestp->getScale(); + +	// the rest of the joints have been cached +	LLVector3 head = mHeadp->getPosition(); +	LLVector3 head_scale = mHeadp->getScale(); + +	LLVector3 torso = mTorsop->getPosition(); +	LLVector3 torso_scale = mTorsop->getScale(); + +	LLVector3 hip = mHipLeftp->getPosition(); +	LLVector3 hip_scale = mHipLeftp->getScale(); + +	LLVector3 knee = mKneeLeftp->getPosition(); +	LLVector3 knee_scale = mKneeLeftp->getScale(); + +	LLVector3 ankle = mAnkleLeftp->getPosition(); +	LLVector3 ankle_scale = mAnkleLeftp->getScale(); + +	LLVector3 foot  = mFootLeftp->getPosition(); + +	mPelvisToFoot = hip.mV[VZ] * pelvis_scale.mV[VZ] - +				 	knee.mV[VZ] * hip_scale.mV[VZ] - +				 	ankle.mV[VZ] * knee_scale.mV[VZ] - +				 	foot.mV[VZ] * ankle_scale.mV[VZ]; + +	LLVector3 new_body_size; +	new_body_size.mV[VZ] = mPelvisToFoot + +					   // the sqrt(2) correction below is an approximate +					   // correction to get to the top of the head +					   F_SQRT2 * (skull.mV[VZ] * head_scale.mV[VZ]) +  +					   head.mV[VZ] * neck_scale.mV[VZ] +  +					   neck.mV[VZ] * chest_scale.mV[VZ] +  +					   chest.mV[VZ] * torso_scale.mV[VZ] +  +					   torso.mV[VZ] * pelvis_scale.mV[VZ];  + +	// TODO -- measure the real depth and width +	new_body_size.mV[VX] = DEFAULT_AGENT_DEPTH; +	new_body_size.mV[VY] = DEFAULT_AGENT_WIDTH; + +	if (new_body_size != mBodySize) +	{ +		mBodySize = new_body_size; +		bodySizeChanged(); +	} +} + +//----------------------------------------------------------------------------- +// parseSkeletonFile() +//----------------------------------------------------------------------------- +BOOL LLAvatarAppearance::parseSkeletonFile(const std::string& filename) +{ +	LLMemType mt(LLMemType::MTYPE_AVATAR); +	 +	//------------------------------------------------------------------------- +	// parse the file +	//------------------------------------------------------------------------- +	BOOL parsesuccess = sSkeletonXMLTree.parseFile( filename, FALSE ); + +	if (!parsesuccess) +	{ +		llerrs << "Can't parse skeleton file: " << filename << llendl; +		return FALSE; +	} + +	// now sanity check xml file +	LLXmlTreeNode* root = sSkeletonXMLTree.getRoot(); +	if (!root)  +	{ +		llerrs << "No root node found in avatar skeleton file: " << filename << llendl; +		return FALSE; +	} + +	if( !root->hasName( "linden_skeleton" ) ) +	{ +		llerrs << "Invalid avatar skeleton file header: " << filename << llendl; +		return FALSE; +	} + +	std::string version; +	static LLStdStringHandle version_string = LLXmlTree::addAttributeString("version"); +	if( !root->getFastAttributeString( version_string, version ) || (version != "1.0") ) +	{ +		llerrs << "Invalid avatar skeleton file version: " << version << " in file: " << filename << llendl; +		return FALSE; +	} + +	return TRUE; +} + +//----------------------------------------------------------------------------- +// setupBone() +//----------------------------------------------------------------------------- +BOOL LLAvatarAppearance::setupBone(const LLAvatarBoneInfo* info, LLJoint* parent, S32 &volume_num, S32 &joint_num) +{ +	LLMemType mt(LLMemType::MTYPE_AVATAR); +	 +	LLJoint* joint = NULL; + +	if (info->mIsJoint) +	{ +		joint = getCharacterJoint(joint_num); +		if (!joint) +		{ +			llwarns << "Too many bones" << llendl; +			return FALSE; +		} +		joint->setName( info->mName ); +	} +	else // collision volume +	{ +		if (volume_num >= (S32)mNumCollisionVolumes) +		{ +			llwarns << "Too many bones" << llendl; +			return FALSE; +		} +		joint = (&mCollisionVolumes[volume_num]); +		joint->setName( info->mName ); +	} + +	// add to parent +	if (parent) +	{ +		parent->addChild( joint ); +	} + +	joint->setPosition(info->mPos); +	joint->setRotation(mayaQ(info->mRot.mV[VX], info->mRot.mV[VY], +							 info->mRot.mV[VZ], LLQuaternion::XYZ)); +	joint->setScale(info->mScale); + +	joint->setDefaultFromCurrentXform(); +	 +	if (info->mIsJoint) +	{ +		joint->setSkinOffset( info->mPivot ); +		joint_num++; +	} +	else // collision volume +	{ +		volume_num++; +	} + +	// setup children +	LLAvatarBoneInfo::child_list_t::const_iterator iter; +	for (iter = info->mChildList.begin(); iter != info->mChildList.end(); ++iter) +	{ +		LLAvatarBoneInfo *child_info = *iter; +		if (!setupBone(child_info, joint, volume_num, joint_num)) +		{ +			return FALSE; +		} +	} + +	return TRUE; +} + +//----------------------------------------------------------------------------- +// buildSkeleton() +//----------------------------------------------------------------------------- +BOOL LLAvatarAppearance::buildSkeleton(const LLAvatarSkeletonInfo *info) +{ +	LLMemType mt(LLMemType::MTYPE_AVATAR); +	 +	//------------------------------------------------------------------------- +	// allocate joints +	//------------------------------------------------------------------------- +	if (!allocateCharacterJoints(info->mNumBones)) +	{ +		llerrs << "Can't allocate " << info->mNumBones << " joints" << llendl; +		return FALSE; +	} +	 +	//------------------------------------------------------------------------- +	// allocate volumes +	//------------------------------------------------------------------------- +	if (info->mNumCollisionVolumes) +	{ +		if (!allocateCollisionVolumes(info->mNumCollisionVolumes)) +		{ +			llerrs << "Can't allocate " << info->mNumCollisionVolumes << " collision volumes" << llendl; +			return FALSE; +		} +	} + +	S32 current_joint_num = 0; +	S32 current_volume_num = 0; +	LLAvatarSkeletonInfo::bone_info_list_t::const_iterator iter; +	for (iter = info->mBoneInfoList.begin(); iter != info->mBoneInfoList.end(); ++iter) +	{ +		LLAvatarBoneInfo *info = *iter; +		if (!setupBone(info, NULL, current_volume_num, current_joint_num)) +		{ +			llerrs << "Error parsing bone in skeleton file" << llendl; +			return FALSE; +		} +	} + +	return TRUE; +} + +//----------------------------------------------------------------------------- +// LLAvatarAppearance::buildCharacter() +// Deferred initialization and rebuild of the avatar. +//----------------------------------------------------------------------------- +void LLAvatarAppearance::buildCharacter() +{ +	LLMemType mt(LLMemType::MTYPE_AVATAR); +	 +	//------------------------------------------------------------------------- +	// remove all references to our existing skeleton +	// so we can rebuild it +	//------------------------------------------------------------------------- +	flushAllMotions(); + +	//------------------------------------------------------------------------- +	// remove all of mRoot's children +	//------------------------------------------------------------------------- +	mRoot->removeAllChildren(); +	mJointMap.clear(); +	mIsBuilt = FALSE; + +	//------------------------------------------------------------------------- +	// (re)load our skeleton and meshes +	//------------------------------------------------------------------------- +	LLTimer timer; + +	BOOL status = loadAvatar(); +	stop_glerror(); + +// 	gPrintMessagesThisFrame = TRUE; +	lldebugs << "Avatar load took " << timer.getElapsedTimeF32() << " seconds." << llendl; + +	if (!status) +	{ +		if (isSelf()) +		{ +			llerrs << "Unable to load user's avatar" << llendl; +		} +		else +		{ +			llwarns << "Unable to load other's avatar" << llendl; +		} +		return; +	} + +	//------------------------------------------------------------------------- +	// initialize "well known" joint pointers +	//------------------------------------------------------------------------- +	mPelvisp		= mRoot->findJoint("mPelvis"); +	mTorsop			= mRoot->findJoint("mTorso"); +	mChestp			= mRoot->findJoint("mChest"); +	mNeckp			= mRoot->findJoint("mNeck"); +	mHeadp			= mRoot->findJoint("mHead"); +	mSkullp			= mRoot->findJoint("mSkull"); +	mHipLeftp		= mRoot->findJoint("mHipLeft"); +	mHipRightp		= mRoot->findJoint("mHipRight"); +	mKneeLeftp		= mRoot->findJoint("mKneeLeft"); +	mKneeRightp		= mRoot->findJoint("mKneeRight"); +	mAnkleLeftp		= mRoot->findJoint("mAnkleLeft"); +	mAnkleRightp	= mRoot->findJoint("mAnkleRight"); +	mFootLeftp		= mRoot->findJoint("mFootLeft"); +	mFootRightp		= mRoot->findJoint("mFootRight"); +	mWristLeftp		= mRoot->findJoint("mWristLeft"); +	mWristRightp	= mRoot->findJoint("mWristRight"); +	mEyeLeftp		= mRoot->findJoint("mEyeLeft"); +	mEyeRightp		= mRoot->findJoint("mEyeRight"); + +	//------------------------------------------------------------------------- +	// Make sure "well known" pointers exist +	//------------------------------------------------------------------------- +	if (!(mPelvisp &&  +		  mTorsop && +		  mChestp && +		  mNeckp && +		  mHeadp && +		  mSkullp && +		  mHipLeftp && +		  mHipRightp && +		  mKneeLeftp && +		  mKneeRightp && +		  mAnkleLeftp && +		  mAnkleRightp && +		  mFootLeftp && +		  mFootRightp && +		  mWristLeftp && +		  mWristRightp && +		  mEyeLeftp && +		  mEyeRightp)) +	{ +		llerrs << "Failed to create avatar." << llendl; +		return; +	} + +	//------------------------------------------------------------------------- +	// initialize the pelvis +	//------------------------------------------------------------------------- +	mPelvisp->setPosition( LLVector3(0.0f, 0.0f, 0.0f) ); + +	mIsBuilt = TRUE; +	stop_glerror(); + +} + +BOOL LLAvatarAppearance::loadAvatar() +{ +// 	LLFastTimer t(FTM_LOAD_AVATAR); +	 +	// avatar_skeleton.xml +	if( !buildSkeleton(sAvatarSkeletonInfo) ) +	{ +		llwarns << "avatar file: buildSkeleton() failed" << llendl; +		return FALSE; +	} + +	// avatar_lad.xml : <skeleton> +	if( !loadSkeletonNode() ) +	{ +		llwarns << "avatar file: loadNodeSkeleton() failed" << llendl; +		return FALSE; +	} +	 +	// avatar_lad.xml : <mesh> +	if( !loadMeshNodes() ) +	{ +		llwarns << "avatar file: loadNodeMesh() failed" << llendl; +		return FALSE; +	} +	 +	// avatar_lad.xml : <global_color> +	if( sAvatarXmlInfo->mTexSkinColorInfo ) +	{ +		mTexSkinColor = new LLTexGlobalColor( this ); +		if( !mTexSkinColor->setInfo( sAvatarXmlInfo->mTexSkinColorInfo ) ) +		{ +			llwarns << "avatar file: mTexSkinColor->setInfo() failed" << llendl; +			return FALSE; +		} +	} +	else +	{ +		llwarns << "<global_color> name=\"skin_color\" not found" << llendl; +		return FALSE; +	} +	if( sAvatarXmlInfo->mTexHairColorInfo ) +	{ +		mTexHairColor = new LLTexGlobalColor( this ); +		if( !mTexHairColor->setInfo( sAvatarXmlInfo->mTexHairColorInfo ) ) +		{ +			llwarns << "avatar file: mTexHairColor->setInfo() failed" << llendl; +			return FALSE; +		} +	} +	else +	{ +		llwarns << "<global_color> name=\"hair_color\" not found" << llendl; +		return FALSE; +	} +	if( sAvatarXmlInfo->mTexEyeColorInfo ) +	{ +		mTexEyeColor = new LLTexGlobalColor( this ); +		if( !mTexEyeColor->setInfo( sAvatarXmlInfo->mTexEyeColorInfo ) ) +		{ +			llwarns << "avatar file: mTexEyeColor->setInfo() failed" << llendl; +			return FALSE; +		} +	} +	else +	{ +		llwarns << "<global_color> name=\"eye_color\" not found" << llendl; +		return FALSE; +	} +	 +	// avatar_lad.xml : <layer_set> +	if (sAvatarXmlInfo->mLayerInfoList.empty()) +	{ +		llwarns << "avatar file: missing <layer_set> node" << llendl; +		return FALSE; +	} + +	if (sAvatarXmlInfo->mMorphMaskInfoList.empty()) +	{ +		llwarns << "avatar file: missing <morph_masks> node" << llendl; +		return FALSE; +	} + +	// avatar_lad.xml : <morph_masks> +	for (LLAvatarXmlInfo::morph_info_list_t::iterator iter = sAvatarXmlInfo->mMorphMaskInfoList.begin(); +		 iter != sAvatarXmlInfo->mMorphMaskInfoList.end(); +		 ++iter) +	{ +		LLAvatarXmlInfo::LLAvatarMorphInfo *info = *iter; + +		EBakedTextureIndex baked = LLAvatarAppearanceDictionary::findBakedByRegionName(info->mRegion);  +		if (baked != BAKED_NUM_INDICES) +		{ +			LLVisualParam* morph_param; +			const std::string *name = &info->mName; +			morph_param = getVisualParam(name->c_str()); +			if (morph_param) +			{ +				BOOL invert = info->mInvert; +				addMaskedMorph(baked, morph_param, invert, info->mLayer); +			} +		} + +	} + +	loadLayersets();	 +	 +	// avatar_lad.xml : <driver_parameters> +	for (LLAvatarXmlInfo::driver_info_list_t::iterator iter = sAvatarXmlInfo->mDriverInfoList.begin(); +		 iter != sAvatarXmlInfo->mDriverInfoList.end();  +		 ++iter) +	{ +		LLDriverParamInfo *info = *iter; +		LLDriverParam* driver_param = new LLDriverParam( this ); +		if (driver_param->setInfo(info)) +		{ +			addVisualParam( driver_param ); +			LLVisualParam*(LLAvatarAppearance::*avatar_function)(S32)const = &LLAvatarAppearance::getVisualParam;  +			if( !driver_param->linkDrivenParams(boost::bind(avatar_function,(LLAvatarAppearance*)this,_1 ), false)) +			{ +				llwarns << "could not link driven params for avatar " << getID().asString() << " param id: " << driver_param->getID() << llendl; +				continue; +			} +		} +		else +		{ +			delete driver_param; +			llwarns << "avatar file: driver_param->parseData() failed" << llendl; +			return FALSE; +		} +	} + +	 +	return TRUE; +} + +//----------------------------------------------------------------------------- +// loadSkeletonNode(): loads <skeleton> node from XML tree +//----------------------------------------------------------------------------- +BOOL LLAvatarAppearance::loadSkeletonNode () +{ +	mRoot->addChild( &mSkeleton[0] ); + +	mRoot->addChild(mMeshLOD[MESH_ID_HEAD]); +	mRoot->addChild(mMeshLOD[MESH_ID_EYELASH]); +	mRoot->addChild(mMeshLOD[MESH_ID_UPPER_BODY]); +	mRoot->addChild(mMeshLOD[MESH_ID_LOWER_BODY]); +	mRoot->addChild(mMeshLOD[MESH_ID_SKIRT]); +	mRoot->addChild(mMeshLOD[MESH_ID_HEAD]); + +	LLAvatarJoint *skull = (LLAvatarJoint*)mRoot->findJoint("mSkull"); +	if (skull) +	{ +		skull->addChild(mMeshLOD[MESH_ID_HAIR] ); +	} + +	LLAvatarJoint *eyeL = (LLAvatarJoint*)mRoot->findJoint("mEyeLeft"); +	if (eyeL) +	{ +		eyeL->addChild( mMeshLOD[MESH_ID_EYEBALL_LEFT] ); +	} + +	LLAvatarJoint *eyeR = (LLAvatarJoint*)mRoot->findJoint("mEyeRight"); +	if (eyeR) +	{ +		eyeR->addChild( mMeshLOD[MESH_ID_EYEBALL_RIGHT] ); +	} + +	// SKELETAL DISTORTIONS +	{ +		LLAvatarXmlInfo::skeletal_distortion_info_list_t::iterator iter; +		for (iter = sAvatarXmlInfo->mSkeletalDistortionInfoList.begin(); +			 iter != sAvatarXmlInfo->mSkeletalDistortionInfoList.end();  +			 ++iter) +		{ +			LLPolySkeletalDistortionInfo *info = (LLPolySkeletalDistortionInfo*)*iter; +			LLPolySkeletalDistortion *param = new LLPolySkeletalDistortion(this); +			if (!param->setInfo(info)) +			{ +				delete param; +				return FALSE; +			} +			else +			{ +				addVisualParam(param); +			}				 +		} +	} + + +	return TRUE; +} + +//----------------------------------------------------------------------------- +// loadMeshNodes(): loads <mesh> nodes from XML tree +//----------------------------------------------------------------------------- +BOOL LLAvatarAppearance::loadMeshNodes() +{ +	for (LLAvatarXmlInfo::mesh_info_list_t::const_iterator meshinfo_iter = sAvatarXmlInfo->mMeshInfoList.begin(); +		 meshinfo_iter != sAvatarXmlInfo->mMeshInfoList.end();  +		 ++meshinfo_iter) +	{ +		const LLAvatarXmlInfo::LLAvatarMeshInfo *info = *meshinfo_iter; +		const std::string &type = info->mType; +		S32 lod = info->mLOD; + +		LLAvatarJointMesh* mesh = NULL; +		U8 mesh_id = 0; +		BOOL found_mesh_id = FALSE; + +		/* if (type == "hairMesh") +			switch(lod) +			  case 0: +				mesh = &mHairMesh0; */ +		for (LLAvatarAppearanceDictionary::Meshes::const_iterator mesh_iter = LLAvatarAppearanceDictionary::getInstance()->getMeshes().begin(); +			 mesh_iter != LLAvatarAppearanceDictionary::getInstance()->getMeshes().end(); +			 ++mesh_iter) +		{ +			const EMeshIndex mesh_index = mesh_iter->first; +			const LLAvatarAppearanceDictionary::MeshEntry *mesh_dict = mesh_iter->second; +			if (type.compare(mesh_dict->mName) == 0) +			{ +				mesh_id = mesh_index; +				found_mesh_id = TRUE; +				break; +			} +		} + +		if (found_mesh_id) +		{ +			if (lod < (S32)mMeshLOD[mesh_id]->mMeshParts.size()) +			{ +				mesh = mMeshLOD[mesh_id]->mMeshParts[lod]; +			} +			else +			{ +				llwarns << "Avatar file: <mesh> has invalid lod setting " << lod << llendl; +				return FALSE; +			} +		} +		else  +		{ +			llwarns << "Ignoring unrecognized mesh type: " << type << llendl; +			return FALSE; +		} + +		//	llinfos << "Parsing mesh data for " << type << "..." << llendl; + +		// If this isn't set to white (1.0), avatars will *ALWAYS* be darker than their surroundings. +		// Do not touch!!! +		mesh->setColor( 1.0f, 1.0f, 1.0f, 1.0f ); + +		LLPolyMesh *poly_mesh = NULL; + +		if (!info->mReferenceMeshName.empty()) +		{ +			polymesh_map_t::const_iterator polymesh_iter = mMeshes.find(info->mReferenceMeshName); +			if (polymesh_iter != mMeshes.end()) +			{ +				poly_mesh = LLPolyMesh::getMesh(info->mMeshFileName, polymesh_iter->second); +				poly_mesh->setAvatar(this); +			} +			else +			{ +				// This should never happen +				LL_WARNS("Avatar") << "Could not find avatar mesh: " << info->mReferenceMeshName << LL_ENDL; +			} +		} +		else +		{ +			poly_mesh = LLPolyMesh::getMesh(info->mMeshFileName); +			poly_mesh->setAvatar(this); +		} + +		if( !poly_mesh ) +		{ +			llwarns << "Failed to load mesh of type " << type << llendl; +			return FALSE; +		} + +		// Multimap insert +		mMeshes.insert(std::make_pair(info->mMeshFileName, poly_mesh)); +	 +		mesh->setMesh( poly_mesh ); +		mesh->setLOD( info->mMinPixelArea ); + +		for (LLAvatarXmlInfo::LLAvatarMeshInfo::morph_info_list_t::const_iterator xmlinfo_iter = info->mPolyMorphTargetInfoList.begin(); +			 xmlinfo_iter != info->mPolyMorphTargetInfoList.end();  +			 ++xmlinfo_iter) +		{ +			const LLAvatarXmlInfo::LLAvatarMeshInfo::morph_info_pair_t *info_pair = &(*xmlinfo_iter); +			LLPolyMorphTarget *param = new LLPolyMorphTarget(mesh->getMesh()); +			if (!param->setInfo((LLPolyMorphTargetInfo*)info_pair->first)) +			{ +				delete param; +				return FALSE; +			} +			else +			{ +				if (info_pair->second) +				{ +					addSharedVisualParam(param); +				} +				else +				{ +					addVisualParam(param); +				} +			}				 +		} +	} + +	return TRUE; +} + +//----------------------------------------------------------------------------- +// loadLayerSets() +//----------------------------------------------------------------------------- +BOOL LLAvatarAppearance::loadLayersets() +{ +	BOOL success = TRUE; +	for (LLAvatarXmlInfo::layer_info_list_t::const_iterator layerset_iter = sAvatarXmlInfo->mLayerInfoList.begin(); +		 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); +	} +	return success; +} + + +  // virtual  BOOL LLAvatarAppearance::isValid() const  { @@ -273,4 +1176,494 @@ BOOL LLAvatarAppearance::isWearingWearableType(LLWearableType::EType type) const  	return FALSE;  } +//----------------------------------------------------------------------------- +// allocateCollisionVolumes() +//----------------------------------------------------------------------------- +BOOL LLAvatarAppearance::allocateCollisionVolumes( U32 num ) +{ +	deleteAndClearArray(mCollisionVolumes); +	mNumCollisionVolumes = 0; + +	mCollisionVolumes = new LLAvatarJointCollisionVolume[num]; +	if (!mCollisionVolumes) +	{ +		return FALSE; +	} + +	mNumCollisionVolumes = num; +	return TRUE; +} + +//----------------------------------------------------------------------------- +// LLAvatarBoneInfo::parseXml() +//----------------------------------------------------------------------------- +BOOL LLAvatarBoneInfo::parseXml(LLXmlTreeNode* node) +{ +	if (node->hasName("bone")) +	{ +		mIsJoint = TRUE; +		static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name"); +		if (!node->getFastAttributeString(name_string, mName)) +		{ +			llwarns << "Bone without name" << llendl; +			return FALSE; +		} +	} +	else if (node->hasName("collision_volume")) +	{ +		mIsJoint = FALSE; +		static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name"); +		if (!node->getFastAttributeString(name_string, mName)) +		{ +			mName = "Collision Volume"; +		} +	} +	else +	{ +		llwarns << "Invalid node " << node->getName() << llendl; +		return FALSE; +	} + +	static LLStdStringHandle pos_string = LLXmlTree::addAttributeString("pos"); +	if (!node->getFastAttributeVector3(pos_string, mPos)) +	{ +		llwarns << "Bone without position" << llendl; +		return FALSE; +	} + +	static LLStdStringHandle rot_string = LLXmlTree::addAttributeString("rot"); +	if (!node->getFastAttributeVector3(rot_string, mRot)) +	{ +		llwarns << "Bone without rotation" << llendl; +		return FALSE; +	} +	 +	static LLStdStringHandle scale_string = LLXmlTree::addAttributeString("scale"); +	if (!node->getFastAttributeVector3(scale_string, mScale)) +	{ +		llwarns << "Bone without scale" << llendl; +		return FALSE; +	} + +	if (mIsJoint) +	{ +		static LLStdStringHandle pivot_string = LLXmlTree::addAttributeString("pivot"); +		if (!node->getFastAttributeVector3(pivot_string, mPivot)) +		{ +			llwarns << "Bone without pivot" << llendl; +			return FALSE; +		} +	} + +	// parse children +	LLXmlTreeNode* child; +	for( child = node->getFirstChild(); child; child = node->getNextChild() ) +	{ +		LLAvatarBoneInfo *child_info = new LLAvatarBoneInfo; +		if (!child_info->parseXml(child)) +		{ +			delete child_info; +			return FALSE; +		} +		mChildList.push_back(child_info); +	} +	return TRUE; +} + +//----------------------------------------------------------------------------- +// LLAvatarSkeletonInfo::parseXml() +//----------------------------------------------------------------------------- +BOOL LLAvatarSkeletonInfo::parseXml(LLXmlTreeNode* node) +{ +	static LLStdStringHandle num_bones_string = LLXmlTree::addAttributeString("num_bones"); +	if (!node->getFastAttributeS32(num_bones_string, mNumBones)) +	{ +		llwarns << "Couldn't find number of bones." << llendl; +		return FALSE; +	} + +	static LLStdStringHandle num_collision_volumes_string = LLXmlTree::addAttributeString("num_collision_volumes"); +	node->getFastAttributeS32(num_collision_volumes_string, mNumCollisionVolumes); + +	LLXmlTreeNode* child; +	for( child = node->getFirstChild(); child; child = node->getNextChild() ) +	{ +		LLAvatarBoneInfo *info = new LLAvatarBoneInfo; +		if (!info->parseXml(child)) +		{ +			delete info; +			llwarns << "Error parsing bone in skeleton file" << llendl; +			return FALSE; +		} +		mBoneInfoList.push_back(info); +	} +	return TRUE; +} + + +//----------------------------------------------------------------------------- +// parseXmlSkeletonNode(): parses <skeleton> nodes from XML tree +//----------------------------------------------------------------------------- +BOOL LLAvatarAppearance::LLAvatarXmlInfo::parseXmlSkeletonNode(LLXmlTreeNode* root) +{ +	LLXmlTreeNode* node = root->getChildByName( "skeleton" ); +	if( !node ) +	{ +		llwarns << "avatar file: missing <skeleton>" << llendl; +		return FALSE; +	} + +	LLXmlTreeNode* child; + +	// SKELETON DISTORTIONS +	for (child = node->getChildByName( "param" ); +		 child; +		 child = node->getNextNamedChild()) +	{ +		if (!child->getChildByName("param_skeleton")) +		{ +			if (child->getChildByName("param_morph")) +			{ +				llwarns << "Can't specify morph param in skeleton definition." << llendl; +			} +			else +			{ +				llwarns << "Unknown param type." << llendl; +			} +			continue; +		} +		 +		LLPolySkeletalDistortionInfo *info = new LLPolySkeletalDistortionInfo; +		if (!info->parseXml(child)) +		{ +			delete info; +			return FALSE; +		} + +		mSkeletalDistortionInfoList.push_back(info); +	} + +	// ATTACHMENT POINTS +	for (child = node->getChildByName( "attachment_point" ); +		 child; +		 child = node->getNextNamedChild()) +	{ +		LLAvatarAttachmentInfo* info = new LLAvatarAttachmentInfo(); + +		static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name"); +		if (!child->getFastAttributeString(name_string, info->mName)) +		{ +			llwarns << "No name supplied for attachment point." << llendl; +			delete info; +			continue; +		} + +		static LLStdStringHandle joint_string = LLXmlTree::addAttributeString("joint"); +		if (!child->getFastAttributeString(joint_string, info->mJointName)) +		{ +			llwarns << "No bone declared in attachment point " << info->mName << llendl; +			delete info; +			continue; +		} + +		static LLStdStringHandle position_string = LLXmlTree::addAttributeString("position"); +		if (child->getFastAttributeVector3(position_string, info->mPosition)) +		{ +			info->mHasPosition = TRUE; +		} + +		static LLStdStringHandle rotation_string = LLXmlTree::addAttributeString("rotation"); +		if (child->getFastAttributeVector3(rotation_string, info->mRotationEuler)) +		{ +			info->mHasRotation = TRUE; +		} +		 static LLStdStringHandle group_string = LLXmlTree::addAttributeString("group"); +		if (child->getFastAttributeS32(group_string, info->mGroup)) +		{ +			if (info->mGroup == -1) +				info->mGroup = -1111; // -1 = none parsed, < -1 = bad value +		} + +		static LLStdStringHandle id_string = LLXmlTree::addAttributeString("id"); +		if (!child->getFastAttributeS32(id_string, info->mAttachmentID)) +		{ +			llwarns << "No id supplied for attachment point " << info->mName << llendl; +			delete info; +			continue; +		} + +		static LLStdStringHandle slot_string = LLXmlTree::addAttributeString("pie_slice"); +		child->getFastAttributeS32(slot_string, info->mPieMenuSlice); +			 +		static LLStdStringHandle visible_in_first_person_string = LLXmlTree::addAttributeString("visible_in_first_person"); +		child->getFastAttributeBOOL(visible_in_first_person_string, info->mVisibleFirstPerson); + +		static LLStdStringHandle hud_attachment_string = LLXmlTree::addAttributeString("hud"); +		child->getFastAttributeBOOL(hud_attachment_string, info->mIsHUDAttachment); + +		mAttachmentInfoList.push_back(info); +	} + +	return TRUE; +} + +//----------------------------------------------------------------------------- +// parseXmlMeshNodes(): parses <mesh> nodes from XML tree +//----------------------------------------------------------------------------- +BOOL LLAvatarAppearance::LLAvatarXmlInfo::parseXmlMeshNodes(LLXmlTreeNode* root) +{ +	for (LLXmlTreeNode* node = root->getChildByName( "mesh" ); +		 node; +		 node = root->getNextNamedChild()) +	{ +		LLAvatarMeshInfo *info = new LLAvatarMeshInfo; + +		// attribute: type +		static LLStdStringHandle type_string = LLXmlTree::addAttributeString("type"); +		if( !node->getFastAttributeString( type_string, info->mType ) ) +		{ +			llwarns << "Avatar file: <mesh> is missing type attribute.  Ignoring element. " << llendl; +			delete info; +			return FALSE;  // Ignore this element +		} +		 +		static LLStdStringHandle lod_string = LLXmlTree::addAttributeString("lod"); +		if (!node->getFastAttributeS32( lod_string, info->mLOD )) +		{ +			llwarns << "Avatar file: <mesh> is missing lod attribute.  Ignoring element. " << llendl; +			delete info; +			return FALSE;  // Ignore this element +		} + +		static LLStdStringHandle file_name_string = LLXmlTree::addAttributeString("file_name"); +		if( !node->getFastAttributeString( file_name_string, info->mMeshFileName ) ) +		{ +			llwarns << "Avatar file: <mesh> is missing file_name attribute.  Ignoring: " << info->mType << llendl; +			delete info; +			return FALSE;  // Ignore this element +		} + +		static LLStdStringHandle reference_string = LLXmlTree::addAttributeString("reference"); +		node->getFastAttributeString( reference_string, info->mReferenceMeshName ); +		 +		// attribute: min_pixel_area +		static LLStdStringHandle min_pixel_area_string = LLXmlTree::addAttributeString("min_pixel_area"); +		static LLStdStringHandle min_pixel_width_string = LLXmlTree::addAttributeString("min_pixel_width"); +		if (!node->getFastAttributeF32( min_pixel_area_string, info->mMinPixelArea )) +		{ +			F32 min_pixel_area = 0.1f; +			if (node->getFastAttributeF32( min_pixel_width_string, min_pixel_area )) +			{ +				// this is square root of pixel area (sensible to use linear space in defining lods) +				min_pixel_area = min_pixel_area * min_pixel_area; +			} +			info->mMinPixelArea = min_pixel_area; +		} +		 +		// Parse visual params for this node only if we haven't already +		for (LLXmlTreeNode* child = node->getChildByName( "param" ); +			 child; +			 child = node->getNextNamedChild()) +		{ +			if (!child->getChildByName("param_morph")) +			{ +				if (child->getChildByName("param_skeleton")) +				{ +					llwarns << "Can't specify skeleton param in a mesh definition." << llendl; +				} +				else +				{ +					llwarns << "Unknown param type." << llendl; +				} +				continue; +			} + +			LLPolyMorphTargetInfo *morphinfo = new LLPolyMorphTargetInfo(); +			if (!morphinfo->parseXml(child)) +			{ +				delete morphinfo; +				delete info; +				return -1; +			} +			BOOL shared = FALSE; +			static LLStdStringHandle shared_string = LLXmlTree::addAttributeString("shared"); +			child->getFastAttributeBOOL(shared_string, shared); + +			info->mPolyMorphTargetInfoList.push_back(LLAvatarMeshInfo::morph_info_pair_t(morphinfo, shared)); +		} + +		mMeshInfoList.push_back(info); +	} +	return TRUE; +} + +//----------------------------------------------------------------------------- +// parseXmlColorNodes(): parses <global_color> nodes from XML tree +//----------------------------------------------------------------------------- +BOOL LLAvatarAppearance::LLAvatarXmlInfo::parseXmlColorNodes(LLXmlTreeNode* root) +{ +	for (LLXmlTreeNode* color_node = root->getChildByName( "global_color" ); +		 color_node; +		 color_node = root->getNextNamedChild()) +	{ +		std::string global_color_name; +		static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name"); +		if (color_node->getFastAttributeString( name_string, global_color_name ) ) +		{ +			if( global_color_name == "skin_color" ) +			{ +				if (mTexSkinColorInfo) +				{ +					llwarns << "avatar file: multiple instances of skin_color" << llendl; +					return FALSE; +				} +				mTexSkinColorInfo = new LLTexGlobalColorInfo; +				if( !mTexSkinColorInfo->parseXml( color_node ) ) +				{ +					deleteAndClear(mTexSkinColorInfo); +					llwarns << "avatar file: mTexSkinColor->parseXml() failed" << llendl; +					return FALSE; +				} +			} +			else if( global_color_name == "hair_color" ) +			{ +				if (mTexHairColorInfo) +				{ +					llwarns << "avatar file: multiple instances of hair_color" << llendl; +					return FALSE; +				} +				mTexHairColorInfo = new LLTexGlobalColorInfo; +				if( !mTexHairColorInfo->parseXml( color_node ) ) +				{ +					deleteAndClear(mTexHairColorInfo); +					llwarns << "avatar file: mTexHairColor->parseXml() failed" << llendl; +					return FALSE; +				} +			} +			else if( global_color_name == "eye_color" ) +			{ +				if (mTexEyeColorInfo) +				{ +					llwarns << "avatar file: multiple instances of eye_color" << llendl; +					return FALSE; +				} +				mTexEyeColorInfo = new LLTexGlobalColorInfo; +				if( !mTexEyeColorInfo->parseXml( color_node ) ) +				{ +					llwarns << "avatar file: mTexEyeColor->parseXml() failed" << llendl; +					return FALSE; +				} +			} +		} +	} +	return TRUE; +} + +//----------------------------------------------------------------------------- +// parseXmlLayerNodes(): parses <layer_set> nodes from XML tree +//----------------------------------------------------------------------------- +BOOL LLAvatarAppearance::LLAvatarXmlInfo::parseXmlLayerNodes(LLXmlTreeNode* root) +{ +	for (LLXmlTreeNode* layer_node = root->getChildByName( "layer_set" ); +		 layer_node; +		 layer_node = root->getNextNamedChild()) +	{ +		LLTexLayerSetInfo* layer_info = new LLTexLayerSetInfo(); +		if( layer_info->parseXml( layer_node ) ) +		{ +			mLayerInfoList.push_back(layer_info); +		} +		else +		{ +			delete layer_info; +			llwarns << "avatar file: layer_set->parseXml() failed" << llendl; +			return FALSE; +		} +	} +	return TRUE; +} + +//----------------------------------------------------------------------------- +// parseXmlDriverNodes(): parses <driver_parameters> nodes from XML tree +//----------------------------------------------------------------------------- +BOOL LLAvatarAppearance::LLAvatarXmlInfo::parseXmlDriverNodes(LLXmlTreeNode* root) +{ +	LLXmlTreeNode* driver = root->getChildByName( "driver_parameters" ); +	if( driver ) +	{ +		for (LLXmlTreeNode* grand_child = driver->getChildByName( "param" ); +			 grand_child; +			 grand_child = driver->getNextNamedChild()) +		{ +			if( grand_child->getChildByName( "param_driver" ) ) +			{ +				LLDriverParamInfo* driver_info = new LLDriverParamInfo(); +				if( driver_info->parseXml( grand_child ) ) +				{ +					mDriverInfoList.push_back(driver_info); +				} +				else +				{ +					delete driver_info; +					llwarns << "avatar file: driver_param->parseXml() failed" << llendl; +					return FALSE; +				} +			} +		} +	} +	return TRUE; +} + +//----------------------------------------------------------------------------- +// parseXmlDriverNodes(): parses <driver_parameters> nodes from XML tree +//----------------------------------------------------------------------------- +BOOL LLAvatarAppearance::LLAvatarXmlInfo::parseXmlMorphNodes(LLXmlTreeNode* root) +{ +	LLXmlTreeNode* masks = root->getChildByName( "morph_masks" ); +	if( !masks ) +	{ +		return FALSE; +	} + +	for (LLXmlTreeNode* grand_child = masks->getChildByName( "mask" ); +		 grand_child; +		 grand_child = masks->getNextNamedChild()) +	{ +		LLAvatarMorphInfo* info = new LLAvatarMorphInfo(); + +		static LLStdStringHandle name_string = LLXmlTree::addAttributeString("morph_name"); +		if (!grand_child->getFastAttributeString(name_string, info->mName)) +		{ +			llwarns << "No name supplied for morph mask." << llendl; +			delete info; +			continue; +		} + +		static LLStdStringHandle region_string = LLXmlTree::addAttributeString("body_region"); +		if (!grand_child->getFastAttributeString(region_string, info->mRegion)) +		{ +			llwarns << "No region supplied for morph mask." << llendl; +			delete info; +			continue; +		} + +		static LLStdStringHandle layer_string = LLXmlTree::addAttributeString("layer"); +		if (!grand_child->getFastAttributeString(layer_string, info->mLayer)) +		{ +			llwarns << "No layer supplied for morph mask." << llendl; +			delete info; +			continue; +		} + +		// optional parameter. don't throw a warning if not present. +		static LLStdStringHandle invert_string = LLXmlTree::addAttributeString("invert"); +		grand_child->getFastAttributeBOOL(invert_string, info->mInvert); + +		mMorphMaskInfoList.push_back(info); +	} + +	return TRUE; +} + + diff --git a/indra/llappearance/llavatarappearance.h b/indra/llappearance/llavatarappearance.h index b2ab6b069f..38a54d904d 100644 --- a/indra/llappearance/llavatarappearance.h +++ b/indra/llappearance/llavatarappearance.h @@ -30,11 +30,17 @@  #include "llcharacter.h"  //#include "llframetimer.h"  #include "llavatarappearancedefines.h" -#include "lljoint.h" +#include "llavatarjoint.h" +#include "lldriverparam.h" +#include "lltexlayer.h" +#include "llviewervisualparam.h" +#include "llxmltree.h"  class LLTexLayerSet;  class LLTexGlobalColor;  class LLWearableData; +class LLAvatarBoneInfo; +class LLAvatarSkeletonInfo;  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  // LLAvatarAppearance @@ -45,6 +51,9 @@ class LLAvatarAppearance : public LLCharacter  {  	LOG_CLASS(LLAvatarAppearance); +protected: +	struct LLAvatarXmlInfo; +  /********************************************************************************   **                                                                            **   **                    INITIALIZATION @@ -57,6 +66,12 @@ public:  	LLAvatarAppearance(LLWearableData* wearable_data);  	virtual ~LLAvatarAppearance(); +	static void initClass(); // initializes static members +	virtual BOOL		loadSkeletonNode(); +	virtual BOOL		loadMeshNodes(); +	virtual BOOL		loadLayersets(); + +  /**                    Initialization   **                                                                            **   *******************************************************************************/ @@ -69,16 +84,94 @@ public:  	virtual bool 	isSelf() const { return false; } // True if this avatar is for this viewer's agent  	virtual BOOL	isValid() const;  	virtual BOOL	isUsingBakedTextures() const = 0; + +	bool isBuilt() const { return mIsBuilt; } +  /**                    State   **                                                                            **   *******************************************************************************/ +/******************************************************************************** + **                                                                            ** + **                    SKELETON + **/ + +public: +	F32					getPelvisToFoot() const { return mPelvisToFoot; } + +	LLVector3			mHeadOffset; // current head position +	LLAvatarJoint		*mRoot; + +	typedef std::map<std::string, LLJoint*> joint_map_t; +	joint_map_t			mJointMap; + +protected: +	static BOOL			parseSkeletonFile(const std::string& filename); +	virtual void		buildCharacter(); +	virtual BOOL		loadAvatar(); +	virtual void		bodySizeChanged() = 0; +	void 				computeBodySize(); + +	BOOL				setupBone(const LLAvatarBoneInfo* info, LLJoint* parent, S32 ¤t_volume_num, S32 ¤t_joint_num); +	BOOL				buildSkeleton(const LLAvatarSkeletonInfo *info); +protected: +	BOOL				mIsBuilt; // state of deferred character building +	S32					mNumJoints; +	LLJoint*			mSkeleton; +	 +	//-------------------------------------------------------------------- +	// Pelvis height adjustment members. +	//-------------------------------------------------------------------- +public: +	LLVector3			mBodySize; +protected: +	F32					mPelvisToFoot; + +	//-------------------------------------------------------------------- +	// Cached pointers to well known joints +	//-------------------------------------------------------------------- +public: +	LLJoint* 		mPelvisp; +	LLJoint* 		mTorsop; +	LLJoint* 		mChestp; +	LLJoint* 		mNeckp; +	LLJoint* 		mHeadp; +	LLJoint* 		mSkullp; +	LLJoint* 		mEyeLeftp; +	LLJoint* 		mEyeRightp; +	LLJoint* 		mHipLeftp; +	LLJoint* 		mHipRightp; +	LLJoint* 		mKneeLeftp; +	LLJoint* 		mKneeRightp; +	LLJoint* 		mAnkleLeftp; +	LLJoint* 		mAnkleRightp; +	LLJoint* 		mFootLeftp; +	LLJoint* 		mFootRightp; +	LLJoint* 		mWristLeftp; +	LLJoint* 		mWristRightp; + +	//-------------------------------------------------------------------- +	// XML parse tree +	//-------------------------------------------------------------------- +protected: +	static LLXmlTree 	sXMLTree; // avatar config file +	static LLXmlTree 	sSkeletonXMLTree; // avatar skeleton file + +	static LLAvatarSkeletonInfo* 					sAvatarSkeletonInfo; +	static LLAvatarXmlInfo* 						sAvatarXmlInfo; + + +/**                    Skeleton + **                                                                            ** + *******************************************************************************/ +  /********************************************************************************   **                                                                            **   **                    RENDERING   **/ +public:  	BOOL		mIsDummy; // for special views  	//-------------------------------------------------------------------- @@ -109,6 +202,11 @@ public:  protected:  	virtual void	dirtyMesh(S32 priority) = 0; // Dirty the avatar mesh, with priority +protected: +	typedef std::multimap<std::string, LLPolyMesh*> polymesh_map_t; +	polymesh_map_t 									mMeshes; +	std::vector<LLAvatarJoint *> 					mMeshLOD; +  /**                    Meshes   **                                                                            **   *******************************************************************************/ @@ -182,12 +280,115 @@ protected:  	typedef std::vector<BakedTextureData> 	bakedtexturedata_vec_t;  	bakedtexturedata_vec_t 					mBakedTextureDatas; +/******************************************************************************** + **                                                                            ** + **                    PHYSICS + **/ + +	//-------------------------------------------------------------------- +	// Collision volumes +	//-------------------------------------------------------------------- +public: +  	S32			mNumCollisionVolumes; +	LLAvatarJointCollisionVolume* mCollisionVolumes; +protected: +	BOOL		allocateCollisionVolumes(U32 num); + +/**                    Physics + **                                                                            ** + *******************************************************************************/  /********************************************************************************   **                                                                            **   **                    SUPPORT CLASSES   **/ +	struct LLAvatarXmlInfo +	{ +		LLAvatarXmlInfo(); +		~LLAvatarXmlInfo(); + +		BOOL 	parseXmlSkeletonNode(LLXmlTreeNode* root); +		BOOL 	parseXmlMeshNodes(LLXmlTreeNode* root); +		BOOL 	parseXmlColorNodes(LLXmlTreeNode* root); +		BOOL 	parseXmlLayerNodes(LLXmlTreeNode* root); +		BOOL 	parseXmlDriverNodes(LLXmlTreeNode* root); +		BOOL	parseXmlMorphNodes(LLXmlTreeNode* root); + +		struct LLAvatarMeshInfo +		{ +			typedef std::pair<LLViewerVisualParamInfo*,BOOL> morph_info_pair_t; // LLPolyMorphTargetInfo stored here +			typedef std::vector<morph_info_pair_t> morph_info_list_t; + +			LLAvatarMeshInfo() : mLOD(0), mMinPixelArea(.1f) {} +			~LLAvatarMeshInfo() +			{ +				morph_info_list_t::iterator iter; +				for (iter = mPolyMorphTargetInfoList.begin(); iter != mPolyMorphTargetInfoList.end(); iter++) +				{ +					delete iter->first; +				} +				mPolyMorphTargetInfoList.clear(); +			} + +			std::string mType; +			S32			mLOD; +			std::string	mMeshFileName; +			std::string	mReferenceMeshName; +			F32			mMinPixelArea; +			morph_info_list_t mPolyMorphTargetInfoList; +		}; +		typedef std::vector<LLAvatarMeshInfo*> mesh_info_list_t; +		mesh_info_list_t mMeshInfoList; + +		typedef std::vector<LLViewerVisualParamInfo*> skeletal_distortion_info_list_t; // LLPolySkeletalDistortionInfo stored here +		skeletal_distortion_info_list_t mSkeletalDistortionInfoList; + +		struct LLAvatarAttachmentInfo +		{ +			LLAvatarAttachmentInfo() +				: mGroup(-1), mAttachmentID(-1), mPieMenuSlice(-1), mVisibleFirstPerson(FALSE), +				  mIsHUDAttachment(FALSE), mHasPosition(FALSE), mHasRotation(FALSE) {} +			std::string mName; +			std::string mJointName; +			LLVector3 mPosition; +			LLVector3 mRotationEuler; +			S32 mGroup; +			S32 mAttachmentID; +			S32 mPieMenuSlice; +			BOOL mVisibleFirstPerson; +			BOOL mIsHUDAttachment; +			BOOL mHasPosition; +			BOOL mHasRotation; +		}; +		typedef std::vector<LLAvatarAttachmentInfo*> attachment_info_list_t; +		attachment_info_list_t mAttachmentInfoList; + +		LLTexGlobalColorInfo *mTexSkinColorInfo; +		LLTexGlobalColorInfo *mTexHairColorInfo; +		LLTexGlobalColorInfo *mTexEyeColorInfo; + +		typedef std::vector<LLTexLayerSetInfo*> layer_info_list_t; +		layer_info_list_t mLayerInfoList; + +		typedef std::vector<LLDriverParamInfo*> driver_info_list_t; +		driver_info_list_t mDriverInfoList; + +		struct LLAvatarMorphInfo +		{ +			LLAvatarMorphInfo() +				: mInvert(FALSE) {} +			std::string mName; +			std::string mRegion; +			std::string mLayer; +			BOOL mInvert; +		}; + +		typedef std::vector<LLAvatarMorphInfo*> morph_info_list_t; +		morph_info_list_t	mMorphMaskInfoList; +	}; + +  	class LLMaskedMorph  	{  	public: @@ -197,7 +398,9 @@ protected:  		BOOL				mInvert;  		std::string			mLayer;  	}; - +/**                    Support Classes + **                                                                            ** + *******************************************************************************/  };  #endif // LL_AVATAR_APPEARANCE_H diff --git a/indra/llappearance/llavatarjoint.cpp b/indra/llappearance/llavatarjoint.cpp new file mode 100644 index 0000000000..809a261633 --- /dev/null +++ b/indra/llappearance/llavatarjoint.cpp @@ -0,0 +1,261 @@ +/**  + * @file llavatarjoint.cpp + * @brief Implementation of LLAvatarJoint class + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +//----------------------------------------------------------------------------- +// Header Files +//----------------------------------------------------------------------------- +#include "llavatarjoint.h" + +#include "llgl.h" +#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; + +//----------------------------------------------------------------------------- +// Static Data +//----------------------------------------------------------------------------- +BOOL					LLAvatarJoint::sDisableLOD = FALSE; + +//----------------------------------------------------------------------------- +// LLAvatarJoint() +// Class Constructor +//----------------------------------------------------------------------------- +LLAvatarJoint::LLAvatarJoint() +	:       LLJoint() +{ +	init(); +} + + +//----------------------------------------------------------------------------- +// LLAvatarJoint() +// Class Constructor +//----------------------------------------------------------------------------- +LLAvatarJoint::LLAvatarJoint(const std::string &name, LLJoint *parent) +	:	LLJoint(name, parent) +{ +	init(); +} + + +void LLAvatarJoint::init() +{ +	mValid = FALSE; +	mComponents = SC_JOINT | SC_BONE | SC_AXES; +	mMinPixelArea = DEFAULT_LOD; +	mPickName = PN_DEFAULT; +	mVisible = TRUE; +	mMeshID = 0; +} + + +//----------------------------------------------------------------------------- +// ~LLAvatarJoint() +// Class Destructor +//----------------------------------------------------------------------------- +LLAvatarJoint::~LLAvatarJoint() +{ +} + + +//-------------------------------------------------------------------- +// setValid() +//-------------------------------------------------------------------- +void LLAvatarJoint::setValid( BOOL valid, BOOL recursive ) +{ +	//---------------------------------------------------------------- +	// set visibility for this joint +	//---------------------------------------------------------------- +	mValid = valid; +	 +	//---------------------------------------------------------------- +	// set visibility for children +	//---------------------------------------------------------------- +	if (recursive) +	{ +		for (child_list_t::iterator iter = mChildren.begin(); +			 iter != mChildren.end(); ++iter) +		{ +			LLAvatarJoint* joint = (LLAvatarJoint*)(*iter); +			joint->setValid(valid, TRUE); +		} +	} + +} + +//-------------------------------------------------------------------- +// isTransparent() +//-------------------------------------------------------------------- +BOOL LLAvatarJoint::isTransparent() +{ +	return FALSE; +} + +//-------------------------------------------------------------------- +// setSkeletonComponents() +//-------------------------------------------------------------------- +void LLAvatarJoint::setSkeletonComponents( U32 comp, BOOL recursive ) +{ +	mComponents = comp; +	if (recursive) +	{ +		for (child_list_t::iterator iter = mChildren.begin(); +			 iter != mChildren.end(); ++iter) +		{ +			LLAvatarJoint* joint = (LLAvatarJoint*)(*iter); +			joint->setSkeletonComponents(comp, recursive); +		} +	} +} + +void LLAvatarJoint::setVisible(BOOL visible, BOOL recursive) +{ +	mVisible = visible; + +	if (recursive) +	{ +		for (child_list_t::iterator iter = mChildren.begin(); +			 iter != mChildren.end(); ++iter) +		{ +			LLAvatarJoint* joint = (LLAvatarJoint*)(*iter); +			joint->setVisible(visible, recursive); +		} +	} +} + + +void LLAvatarJoint::setMeshesToChildren() +{ +	removeAllChildren(); +	for (std::vector<LLAvatarJointMesh*>::iterator iter = mMeshParts.begin(); +		iter != mMeshParts.end(); iter++) +	{ +		addChild((LLAvatarJoint*) *iter); +	} +} +//----------------------------------------------------------------------------- +// LLAvatarJointCollisionVolume() +//----------------------------------------------------------------------------- + +LLAvatarJointCollisionVolume::LLAvatarJointCollisionVolume() +{ +	mUpdateXform = FALSE; +} + +LLAvatarJointCollisionVolume::LLAvatarJointCollisionVolume(const std::string &name, LLJoint *parent) : LLAvatarJoint(name, parent) +{ +	 +} + +LLVector3 LLAvatarJointCollisionVolume::getVolumePos(LLVector3 &offset) +{ +	mUpdateXform = TRUE; +	 +	LLVector3 result = offset; +	result.scaleVec(getScale()); +	result.rotVec(getWorldRotation()); +	result += getWorldPosition(); + +	return result; +} + +void LLAvatarJointCollisionVolume::renderCollision() +{ +	updateWorldMatrix(); +	 +	gGL.pushMatrix(); +	gGL.multMatrix( &mXform.getWorldMatrix().mMatrix[0][0] ); + +	gGL.diffuseColor3f( 0.f, 0.f, 1.f ); +	 +	gGL.begin(LLRender::LINES); +	 +	LLVector3 v[] =  +	{ +		LLVector3(1,0,0), +		LLVector3(-1,0,0), +		LLVector3(0,1,0), +		LLVector3(0,-1,0), + +		LLVector3(0,0,-1), +		LLVector3(0,0,1), +	}; + +	//sides +	gGL.vertex3fv(v[0].mV);  +	gGL.vertex3fv(v[2].mV); + +	gGL.vertex3fv(v[0].mV);  +	gGL.vertex3fv(v[3].mV); + +	gGL.vertex3fv(v[1].mV);  +	gGL.vertex3fv(v[2].mV); + +	gGL.vertex3fv(v[1].mV);  +	gGL.vertex3fv(v[3].mV); + + +	//top +	gGL.vertex3fv(v[0].mV);  +	gGL.vertex3fv(v[4].mV); + +	gGL.vertex3fv(v[1].mV);  +	gGL.vertex3fv(v[4].mV); + +	gGL.vertex3fv(v[2].mV);  +	gGL.vertex3fv(v[4].mV); + +	gGL.vertex3fv(v[3].mV);  +	gGL.vertex3fv(v[4].mV); + + +	//bottom +	gGL.vertex3fv(v[0].mV);  +	gGL.vertex3fv(v[5].mV); + +	gGL.vertex3fv(v[1].mV);  +	gGL.vertex3fv(v[5].mV); + +	gGL.vertex3fv(v[2].mV);  +	gGL.vertex3fv(v[5].mV); + +	gGL.vertex3fv(v[3].mV);  +	gGL.vertex3fv(v[5].mV); + +	gGL.end(); + +	gGL.popMatrix(); +} + + +// End diff --git a/indra/llappearance/llavatarjoint.h b/indra/llappearance/llavatarjoint.h new file mode 100644 index 0000000000..cbfc1b73ea --- /dev/null +++ b/indra/llappearance/llavatarjoint.h @@ -0,0 +1,127 @@ +/**  + * @file llavatarjoint.h + * @brief Implementation of LLAvatarJoint class + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLAVATARJOINT_H +#define LL_LLAVATARJOINT_H + +//----------------------------------------------------------------------------- +// Header Files +//----------------------------------------------------------------------------- +#include "lljoint.h" +#include "lljointpickname.h" + +class LLFace; +class LLAvatarJointMesh; + +//----------------------------------------------------------------------------- +// class LLViewerJoint +//----------------------------------------------------------------------------- +class LLAvatarJoint : +	public LLJoint +{ +public: +	LLAvatarJoint(); +	LLAvatarJoint(const std::string &name, LLJoint *parent = NULL); +	virtual ~LLAvatarJoint(); + +	// Gets the validity of this joint +	BOOL getValid() { return mValid; } + +	// Sets the validity of this joint +	virtual void setValid( BOOL valid, BOOL recursive=FALSE ); + +	// Returns true if this object is transparent. +	// This is used to determine in which order to draw objects. +	virtual BOOL isTransparent(); + +	// Returns true if this object should inherit scale modifiers from its immediate parent +	virtual BOOL inheritScale() { return FALSE; } + + +	enum Components +	{ +		SC_BONE		= 1, +		SC_JOINT	= 2, +		SC_AXES		= 4 +	}; + +	// Selects which skeleton components to draw +	void setSkeletonComponents( U32 comp, BOOL recursive = TRUE ); + +	// Returns which skeleton components are enables for drawing +	U32 getSkeletonComponents() { return mComponents; } + +	// Sets the level of detail for this node as a minimum +	// pixel area threshold.  If the current pixel area for this +	// object is less than the specified threshold, the node is +	// not traversed.  In addition, if a value is specified (not +	// default of 0.0), and the pixel area is larger than the +	// specified minimum, the node is rendered, but no other siblings +	// 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; } + +	void setVisible( BOOL visible, BOOL recursive ); + +	// Takes meshes in mMeshParts and sets each one as a child joint +	void setMeshesToChildren(); + +public: +	static BOOL	sDisableLOD; +	std::vector<LLAvatarJointMesh*> mMeshParts; //LLViewerJointMesh* +	void setMeshID( S32 id ) {mMeshID = id;} + +protected: +	void init(); + +	BOOL		mValid; +	U32			mComponents; +	F32			mMinPixelArea; +	LLJointPickName	mPickName; +	BOOL		mVisible; +	S32			mMeshID; +}; + +class LLAvatarJointCollisionVolume : public LLAvatarJoint +{ +public: +	LLAvatarJointCollisionVolume(); +	LLAvatarJointCollisionVolume(const std::string &name, LLJoint *parent = NULL); +	virtual ~LLAvatarJointCollisionVolume() {}; + +	virtual BOOL inheritScale() { return TRUE; } + +	void renderCollision(); + +	LLVector3 getVolumePos(LLVector3 &offset); +}; + +#endif // LL_LLAVATARJOINT_H + + diff --git a/indra/llappearance/llavatarjointmesh.cpp b/indra/llappearance/llavatarjointmesh.cpp new file mode 100755 index 0000000000..92c213126a --- /dev/null +++ b/indra/llappearance/llavatarjointmesh.cpp @@ -0,0 +1,359 @@ +/**  + * @file LLAvatarJointMesh.cpp + * @brief Implementation of LLAvatarJointMesh class + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +//----------------------------------------------------------------------------- +// Header Files +//----------------------------------------------------------------------------- +#include "linden_common.h" +#include "imageids.h" +#include "llfasttimer.h" +#include "llrender.h" + +#include "llavatarjointmesh.h" +#include "llavatarappearance.h" +//#include "llapr.h" +//#include "llbox.h" +//#include "lldrawable.h" +//#include "lldrawpoolavatar.h" +//#include "lldrawpoolbump.h" +//#include "lldynamictexture.h" +//#include "llface.h" +//#include "llgldbg.h" +//#include "llglheaders.h" +#include "lltexlayer.h" +//#include "llviewercamera.h" +//#include "llviewercontrol.h" +//#include "llviewertexturelist.h" +//#include "llsky.h" +//#include "pipeline.h" +//#include "llviewershadermgr.h" +#include "llmath.h" +#include "v4math.h" +#include "m3math.h" +#include "m4math.h" +#include "llmatrix4a.h" + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +// LLAvatarJointMesh::LLSkinJoint +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// LLSkinJoint +//----------------------------------------------------------------------------- +LLSkinJoint::LLSkinJoint() +{ +	mJoint       = NULL; +} + +//----------------------------------------------------------------------------- +// ~LLSkinJoint +//----------------------------------------------------------------------------- +LLSkinJoint::~LLSkinJoint() +{ +	mJoint = NULL; +} + + +//----------------------------------------------------------------------------- +// LLSkinJoint::setupSkinJoint() +//----------------------------------------------------------------------------- +BOOL LLSkinJoint::setupSkinJoint( LLAvatarJoint *joint) +{ +	// find the named joint +	mJoint = joint; +	if ( !mJoint ) +	{ +		llinfos << "Can't find joint" << llendl; +	} + +	// compute the inverse root skin matrix +	mRootToJointSkinOffset.clearVec(); + +	LLVector3 rootSkinOffset; +	while (joint) +	{ +		rootSkinOffset += joint->getSkinOffset(); +		joint = (LLAvatarJoint*)joint->getParent(); +	} + +	mRootToJointSkinOffset = -rootSkinOffset; +	mRootToParentJointSkinOffset = mRootToJointSkinOffset; +	mRootToParentJointSkinOffset += mJoint->getSkinOffset(); + +	return TRUE; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +// LLAvatarJointMesh +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +BOOL LLAvatarJointMesh::sPipelineRender = FALSE; +EAvatarRenderPass LLAvatarJointMesh::sRenderPass = AVATAR_RENDER_PASS_SINGLE; +U32 LLAvatarJointMesh::sClothingMaskImageName = 0; +LLColor4 LLAvatarJointMesh::sClothingInnerColor; + +//----------------------------------------------------------------------------- +// LLAvatarJointMesh() +//----------------------------------------------------------------------------- +LLAvatarJointMesh::LLAvatarJointMesh() +	: +	mTexture( NULL ), +	mLayerSet( NULL ), +	mTestImageName( 0 ), +	mFaceIndexCount(0), +	mIsTransparent(FALSE) +{ + +	mColor[0] = 1.0f; +	mColor[1] = 1.0f; +	mColor[2] = 1.0f; +	mColor[3] = 1.0f; +	mShiny = 0.0f; +	mCullBackFaces = TRUE; + +	mMesh = NULL; + +	mNumSkinJoints = 0; +	mSkinJoints = NULL; + +	mFace = NULL; + +	mMeshID = 0; +	mUpdateXform = FALSE; + +	mValid = FALSE; +} + + +//----------------------------------------------------------------------------- +// ~LLAvatarJointMesh() +// Class Destructor +//----------------------------------------------------------------------------- +LLAvatarJointMesh::~LLAvatarJointMesh() +{ +	mMesh = NULL; +	mTexture = NULL; +	freeSkinData(); +} + + +//----------------------------------------------------------------------------- +// LLAvatarJointMesh::allocateSkinData() +//----------------------------------------------------------------------------- +BOOL LLAvatarJointMesh::allocateSkinData( U32 numSkinJoints ) +{ +	mSkinJoints = new LLSkinJoint[ numSkinJoints ]; +	mNumSkinJoints = numSkinJoints; +	return TRUE; +} + +//----------------------------------------------------------------------------- +// LLAvatarJointMesh::freeSkinData() +//----------------------------------------------------------------------------- +void LLAvatarJointMesh::freeSkinData() +{ +	mNumSkinJoints = 0; +	delete [] mSkinJoints; +	mSkinJoints = NULL; +} + +//-------------------------------------------------------------------- +// LLAvatarJointMesh::getColor() +//-------------------------------------------------------------------- +void LLAvatarJointMesh::getColor( F32 *red, F32 *green, F32 *blue, F32 *alpha ) +{ +	*red   = mColor[0]; +	*green = mColor[1]; +	*blue  = mColor[2]; +	*alpha = mColor[3]; +} + +//-------------------------------------------------------------------- +// LLAvatarJointMesh::setColor() +//-------------------------------------------------------------------- +void LLAvatarJointMesh::setColor( F32 red, F32 green, F32 blue, F32 alpha ) +{ +	mColor[0] = red; +	mColor[1] = green; +	mColor[2] = blue; +	mColor[3] = alpha; +} + + +//-------------------------------------------------------------------- +// LLAvatarJointMesh::getTexture() +//-------------------------------------------------------------------- +//LLViewerTexture *LLAvatarJointMesh::getTexture() +//{ +//	return mTexture; +//} + +//-------------------------------------------------------------------- +// LLAvatarJointMesh::setTexture() +//-------------------------------------------------------------------- +void LLAvatarJointMesh::setTexture( LLGLTexture *texture ) +{ +	mTexture = texture; + +	// texture and dynamic_texture are mutually exclusive +	if( texture ) +	{ +		mLayerSet = NULL; +		//texture->bindTexture(0); +		//texture->setClamp(TRUE, TRUE); +	} +} + +//-------------------------------------------------------------------- +// LLAvatarJointMesh::setLayerSet() +// Sets the shape texture (takes precedence over normal texture) +//-------------------------------------------------------------------- +void LLAvatarJointMesh::setLayerSet( LLTexLayerSet* layer_set ) +{ +	mLayerSet = layer_set; +	 +	// texture and dynamic_texture are mutually exclusive +	if( layer_set ) +	{ +		mTexture = NULL; +	} +} + + + +//-------------------------------------------------------------------- +// LLAvatarJointMesh::getMesh() +//-------------------------------------------------------------------- +LLPolyMesh *LLAvatarJointMesh::getMesh() +{ +	return mMesh; +} + +//----------------------------------------------------------------------------- +// LLAvatarJointMesh::setMesh() +//----------------------------------------------------------------------------- +void LLAvatarJointMesh::setMesh( LLPolyMesh *mesh ) +{ +	// set the mesh pointer +	mMesh = mesh; + +	// release any existing skin joints +	freeSkinData(); + +	if ( mMesh == NULL ) +	{ +		return; +	} + +	// acquire the transform from the mesh object +	setPosition( mMesh->getPosition() ); +	setRotation( mMesh->getRotation() ); +	setScale( mMesh->getScale() ); + +	// create skin joints if necessary +	if ( mMesh->hasWeights() && !mMesh->isLOD()) +	{ +		U32 numJointNames = mMesh->getNumJointNames(); +		 +		allocateSkinData( numJointNames ); +		std::string *jointNames = mMesh->getJointNames(); + +		U32 jn; +		for (jn = 0; jn < numJointNames; jn++) +		{ +			//llinfos << "Setting up joint " << jointNames[jn] << llendl; +			LLAvatarJoint* joint = (LLAvatarJoint*)(getRoot()->findJoint(jointNames[jn]) ); +			mSkinJoints[jn].setupSkinJoint( joint ); +		} +	} + +	// setup joint array +	if (!mMesh->isLOD()) +	{ +		setupJoint((LLAvatarJoint*)getRoot()); +	} + +//	llinfos << "joint render entries: " << mMesh->mJointRenderData.count() << llendl; +} + +//----------------------------------------------------------------------------- +// setupJoint() +//----------------------------------------------------------------------------- +void LLAvatarJointMesh::setupJoint(LLAvatarJoint* current_joint) +{ +//	llinfos << "Mesh: " << getName() << llendl; + +//	S32 joint_count = 0; +	U32 sj; +	for (sj=0; sj<mNumSkinJoints; sj++) +	{ +		LLSkinJoint &js = mSkinJoints[sj]; + +		if (js.mJoint != current_joint) +		{ +			continue; +		} + +		// we've found a skinjoint for this joint.. + +		// is the last joint in the array our parent? +		if(mMesh->mJointRenderData.count() && mMesh->mJointRenderData[mMesh->mJointRenderData.count() - 1]->mWorldMatrix == ¤t_joint->getParent()->getWorldMatrix()) +		{ +			// ...then just add ourselves +			LLAvatarJoint* jointp = js.mJoint; +			mMesh->mJointRenderData.put(new LLJointRenderData(&jointp->getWorldMatrix(), &js)); +//			llinfos << "joint " << joint_count << js.mJoint->getName() << llendl; +//			joint_count++; +		} +		// otherwise add our parent and ourselves +		else +		{ +			mMesh->mJointRenderData.put(new LLJointRenderData(¤t_joint->getParent()->getWorldMatrix(), NULL)); +//			llinfos << "joint " << joint_count << current_joint->getParent()->getName() << llendl; +//			joint_count++; +			mMesh->mJointRenderData.put(new LLJointRenderData(¤t_joint->getWorldMatrix(), &js)); +//			llinfos << "joint " << joint_count << current_joint->getName() << llendl; +//			joint_count++; +		} +	} + +	// depth-first traversal +	for (LLJoint::child_list_t::iterator iter = current_joint->mChildren.begin(); +		 iter != current_joint->mChildren.end(); ++iter) +	{ +		LLAvatarJoint* child_joint = (LLAvatarJoint*)(*iter); +		setupJoint(child_joint); +	} +} + + +// End diff --git a/indra/llappearance/llavatarjointmesh.h b/indra/llappearance/llavatarjointmesh.h new file mode 100755 index 0000000000..dcd202bdaf --- /dev/null +++ b/indra/llappearance/llavatarjointmesh.h @@ -0,0 +1,140 @@ +/**  + * @file llavatarjointmesh.h + * @brief Implementation of LLAvatarJointMesh class + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLAVATARJOINTMESH_H +#define LL_LLAVATARJOINTMESH_H + +#include "llavatarjoint.h" +#include "llgltexture.h" +#include "llpolymesh.h" +#include "v4color.h" + +class LLDrawable; +class LLFace; +class LLCharacter; +class LLTexLayerSet; + +typedef enum e_avatar_render_pass +{ +	AVATAR_RENDER_PASS_SINGLE, +	AVATAR_RENDER_PASS_CLOTHING_INNER, +	AVATAR_RENDER_PASS_CLOTHING_OUTER +} EAvatarRenderPass; + +class LLSkinJoint +{ +public: +	LLSkinJoint(); +	~LLSkinJoint(); +	BOOL setupSkinJoint( LLAvatarJoint *joint); + +	LLAvatarJoint	*mJoint; +	LLVector3		mRootToJointSkinOffset; +	LLVector3		mRootToParentJointSkinOffset; +}; + +//----------------------------------------------------------------------------- +// class LLViewerJointMesh +//----------------------------------------------------------------------------- +class LLAvatarJointMesh : public LLAvatarJoint +{ +	friend class LLAvatarAppearance; +protected: +	LLColor4					mColor;			// color value +// 	LLColor4					mSpecular;		// specular color (always white for now) +	F32							mShiny;			// shiny value +	LLPointer<LLGLTexture>		mTexture;		// ptr to a global texture +	LLTexLayerSet*				mLayerSet;		// ptr to a layer set owned by the avatar +	U32 						mTestImageName;		// handle to a temporary texture for previewing uploads +	LLPolyMesh*					mMesh;			// ptr to a global polymesh +	BOOL						mCullBackFaces;	// true by default +	LLFace*						mFace;			// ptr to a face w/ AGP copy of mesh + +	U32							mFaceIndexCount; +	BOOL						mIsTransparent; + +	U32							mNumSkinJoints; +	LLSkinJoint*				mSkinJoints; +	S32							mMeshID; + +public: +	static BOOL					sPipelineRender; +	//RN: this is here for testing purposes +	static U32					sClothingMaskImageName; +	static EAvatarRenderPass	sRenderPass; +	static LLColor4				sClothingInnerColor; + +public: +	// Constructor +	LLAvatarJointMesh(); + +	// Destructor +	virtual ~LLAvatarJointMesh(); + +	// Gets the shape color +	void getColor( F32 *red, F32 *green, F32 *blue, F32 *alpha ); + +	// Sets the shape color +	void setColor( F32 red, F32 green, F32 blue, F32 alpha ); + +	// Sets the shininess +	void setSpecular( const LLColor4& color, F32 shiny ) { /*mSpecular = color;*/ mShiny = shiny; }; + +	// Sets the shape texture +	void setTexture( LLGLTexture *texture ); + +	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 ); + +	// Gets the poly mesh +	LLPolyMesh *getMesh(); + +	// Sets the poly mesh +	void setMesh( LLPolyMesh *mesh ); + +	// Sets up joint matrix data for rendering +	void setupJoint(LLAvatarJoint* current_joint); + +	// Render time method to upload batches of joint matrices +	void uploadJointMatrices(); + +	// Sets ID for picking +	void setMeshID( S32 id ) {mMeshID = id;} + +	// Gets ID for picking +	S32 getMeshID() { return mMeshID; }	 + +private: +	// Allocate skin data +	BOOL allocateSkinData( U32 numSkinJoints ); + +	// Free skin data +	void freeSkinData(); +}; + +#endif // LL_LLAVATARJOINTMESH_H diff --git a/indra/newview/llpolymesh.cpp b/indra/llappearance/llpolymesh.cpp index 70f3b5335e..b1370ab1e3 100644 --- a/indra/newview/llpolymesh.cpp +++ b/indra/llappearance/llpolymesh.cpp @@ -27,25 +27,24 @@  //-----------------------------------------------------------------------------  // Header Files  //----------------------------------------------------------------------------- -#include "llviewerprecompiledheaders.h" - +#include "linden_common.h" +#include "llpolymesh.h"  #include "llfasttimer.h"  #include "llmemory.h" -#include "llviewercontrol.h" +//#include "llviewercontrol.h"  #include "llxmltree.h" -#include "llvoavatar.h" +#include "llavatarappearance.h"  #include "llwearable.h"  #include "lldir.h"  #include "llvolume.h"  #include "llendianswizzle.h" -#include "llpolymesh.h"  #define HEADER_ASCII "Linden Mesh 1.0"  #define HEADER_BINARY "Linden Binary Mesh 1.0" -extern LLControlGroup gSavedSettings;                           // read only +//extern LLControlGroup gSavedSettings;                           // read only  LLPolyMorphData *clone_morph_param_duplicate(const LLPolyMorphData *src_data,  					     const std::string &name); @@ -1048,250 +1047,4 @@ F32*    LLPolyMesh::getWritableWeights() const          return mSharedData->mWeights;  } -//----------------------------------------------------------------------------- -// LLPolySkeletalDistortionInfo() -//----------------------------------------------------------------------------- -LLPolySkeletalDistortionInfo::LLPolySkeletalDistortionInfo() -{ -} - -BOOL LLPolySkeletalDistortionInfo::parseXml(LLXmlTreeNode* node) -{ -        llassert( node->hasName( "param" ) && node->getChildByName( "param_skeleton" ) ); -         -        if (!LLViewerVisualParamInfo::parseXml(node)) -                return FALSE; - -        LLXmlTreeNode* skeletalParam = node->getChildByName("param_skeleton"); - -        if (NULL == skeletalParam) -        { -                llwarns << "Failed to getChildByName(\"param_skeleton\")" -                        << llendl; -                return FALSE; -        } - -        for( LLXmlTreeNode* bone = skeletalParam->getFirstChild(); bone; bone = skeletalParam->getNextChild() ) -        { -                if (bone->hasName("bone")) -                { -                        std::string name; -                        LLVector3 scale; -                        LLVector3 pos; -                        BOOL haspos = FALSE; -                         -                        static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name"); -                        if (!bone->getFastAttributeString(name_string, name)) -                        { -                                llwarns << "No bone name specified for skeletal param." << llendl; -                                continue; -                        } - -                        static LLStdStringHandle scale_string = LLXmlTree::addAttributeString("scale"); -                        if (!bone->getFastAttributeVector3(scale_string, scale)) -                        { -                                llwarns << "No scale specified for bone " << name << "." << llendl; -                                continue; -                        } - -                        // optional offset deformation (translation) -                        static LLStdStringHandle offset_string = LLXmlTree::addAttributeString("offset"); -                        if (bone->getFastAttributeVector3(offset_string, pos)) -                        { -                                haspos = TRUE; -                        } -                        mBoneInfoList.push_back(LLPolySkeletalBoneInfo(name, scale, pos, haspos)); -                } -                else -                { -                        llwarns << "Unrecognized element " << bone->getName() << " in skeletal distortion" << llendl; -                        continue; -                } -        } -        return TRUE; -} - -//----------------------------------------------------------------------------- -// LLPolySkeletalDistortion() -//----------------------------------------------------------------------------- -LLPolySkeletalDistortion::LLPolySkeletalDistortion(LLVOAvatar *avatarp) -{ -        mAvatar = avatarp; -        mDefaultVec.splat(0.001f); -} - -//----------------------------------------------------------------------------- -// ~LLPolySkeletalDistortion() -//----------------------------------------------------------------------------- -LLPolySkeletalDistortion::~LLPolySkeletalDistortion() -{ -} - -BOOL LLPolySkeletalDistortion::setInfo(LLPolySkeletalDistortionInfo *info) -{ -        llassert(mInfo == NULL); -        if (info->mID < 0) -                return FALSE; -        mInfo = info; -        mID = info->mID; -        setWeight(getDefaultWeight(), FALSE ); - -        LLPolySkeletalDistortionInfo::bone_info_list_t::iterator iter; -        for (iter = getInfo()->mBoneInfoList.begin(); iter != getInfo()->mBoneInfoList.end(); iter++) -        { -                LLPolySkeletalBoneInfo *bone_info = &(*iter); -                LLJoint* joint = mAvatar->getJoint(bone_info->mBoneName); -                if (!joint) -                { -                        llwarns << "Joint " << bone_info->mBoneName << " not found." << llendl; -                        continue; -                } - -                if (mJointScales.find(joint) != mJointScales.end()) -                { -                        llwarns << "Scale deformation already supplied for joint " << joint->getName() << "." << llendl; -                } - -                // store it -                mJointScales[joint] = bone_info->mScaleDeformation; - -                // apply to children that need to inherit it -                for (LLJoint::child_list_t::iterator iter = joint->mChildren.begin(); -                     iter != joint->mChildren.end(); ++iter) -                { -                        LLViewerJoint* child_joint = (LLViewerJoint*)(*iter); -                        if (child_joint->inheritScale()) -                        { -                                LLVector3 childDeformation = LLVector3(child_joint->getScale()); -                                childDeformation.scaleVec(bone_info->mScaleDeformation); -                                mJointScales[child_joint] = childDeformation; -                        } -                } - -                if (bone_info->mHasPositionDeformation) -                { -                        if (mJointOffsets.find(joint) != mJointOffsets.end()) -                        { -                                llwarns << "Offset deformation already supplied for joint " << joint->getName() << "." << llendl; -                        } -                        mJointOffsets[joint] = bone_info->mPositionDeformation; -                } -        } -        return TRUE; -} - -/*virtual*/ LLViewerVisualParam* LLPolySkeletalDistortion::cloneParam(LLWearable* wearable) const -{ -        LLPolySkeletalDistortion *new_param = new LLPolySkeletalDistortion(mAvatar); -        *new_param = *this; -        return new_param; -} - -//----------------------------------------------------------------------------- -// apply() -//----------------------------------------------------------------------------- -static LLFastTimer::DeclareTimer FTM_POLYSKELETAL_DISTORTION_APPLY("Skeletal Distortion"); - -void LLPolySkeletalDistortion::apply( ESex avatar_sex ) -{ -	LLFastTimer t(FTM_POLYSKELETAL_DISTORTION_APPLY); - -        F32 effective_weight = ( getSex() & avatar_sex ) ? mCurWeight : getDefaultWeight(); - -        LLJoint* joint; -        joint_vec_map_t::iterator iter; - -        for (iter = mJointScales.begin(); -             iter != mJointScales.end(); -             iter++) -        { -                joint = iter->first; -                LLVector3 newScale = joint->getScale(); -                LLVector3 scaleDelta = iter->second; -                newScale = newScale + (effective_weight * scaleDelta) - (mLastWeight * scaleDelta); -                joint->setScale(newScale); -        } - -        for (iter = mJointOffsets.begin(); -             iter != mJointOffsets.end(); -             iter++) -        { -                joint = iter->first; -                LLVector3 newPosition = joint->getPosition(); -                LLVector3 positionDelta = iter->second; -                newPosition = newPosition + (effective_weight * positionDelta) - (mLastWeight * positionDelta); -                joint->setPosition(newPosition); -        } - -        if (mLastWeight != mCurWeight && !mIsAnimating) -        { -                mAvatar->setSkeletonSerialNum(mAvatar->getSkeletonSerialNum() + 1); -        } -        mLastWeight = mCurWeight; -} - - -LLPolyMorphData *clone_morph_param_duplicate(const LLPolyMorphData *src_data, -					     const std::string &name) -{ -        LLPolyMorphData* cloned_morph_data = new LLPolyMorphData(*src_data); -        cloned_morph_data->mName = name; -        for (U32 v=0; v < cloned_morph_data->mNumIndices; v++) -        { -                cloned_morph_data->mCoords[v] = src_data->mCoords[v]; -                cloned_morph_data->mNormals[v] = src_data->mNormals[v]; -                cloned_morph_data->mBinormals[v] = src_data->mBinormals[v]; -        } -        return cloned_morph_data; -} - -LLPolyMorphData *clone_morph_param_direction(const LLPolyMorphData *src_data, -					     const LLVector3 &direction, -					     const std::string &name) -{ -        LLPolyMorphData* cloned_morph_data = new LLPolyMorphData(*src_data); -        cloned_morph_data->mName = name; -		LLVector4a dir; -		dir.load3(direction.mV); - -        for (U32 v=0; v < cloned_morph_data->mNumIndices; v++) -        { -                cloned_morph_data->mCoords[v] = dir; -                cloned_morph_data->mNormals[v].clear(); -                cloned_morph_data->mBinormals[v].clear(); -        } -        return cloned_morph_data; -} - -LLPolyMorphData *clone_morph_param_cleavage(const LLPolyMorphData *src_data, -                                            F32 scale, -                                            const std::string &name) -{ -        LLPolyMorphData* cloned_morph_data = new LLPolyMorphData(*src_data); -        cloned_morph_data->mName = name; - -		LLVector4a sc; -		sc.splat(scale); - -		LLVector4a nsc; -		nsc.set(scale, -scale, scale, scale); - -        for (U32 v=0; v < cloned_morph_data->mNumIndices; v++) -        { -            if (cloned_morph_data->mCoords[v][1] < 0) -            { -                cloned_morph_data->mCoords[v].setMul(src_data->mCoords[v],nsc); -				cloned_morph_data->mNormals[v].setMul(src_data->mNormals[v],nsc); -				cloned_morph_data->mBinormals[v].setMul(src_data->mBinormals[v],nsc); -			} -			else -			{ -				cloned_morph_data->mCoords[v].setMul(src_data->mCoords[v],sc); -				cloned_morph_data->mNormals[v].setMul(src_data->mNormals[v], sc); -				cloned_morph_data->mBinormals[v].setMul(src_data->mBinormals[v],sc); -			} -        } -        return cloned_morph_data; -} -  // End diff --git a/indra/newview/llpolymesh.h b/indra/llappearance/llpolymesh.h index ffb11a3f7e..ef1dfb1adb 100644 --- a/indra/newview/llpolymesh.h +++ b/indra/llappearance/llpolymesh.h @@ -24,8 +24,8 @@   * $/LicenseInfo$   */ -#ifndef LL_LLPOLYMESH_H -#define LL_LLPOLYMESH_H +#ifndef LL_LLPOLYMESHINTERFACE_H +#define LL_LLPOLYMESHINTERFACE_H  #include <string>  #include <map> @@ -39,7 +39,7 @@  //#include "lldarray.h"  class LLSkinJoint; -class LLVOAvatar; +class LLAvatarAppearance;  class LLWearable;  //#define USE_STRIPS	// Use tri-strips for rendering. @@ -319,8 +319,8 @@ public:  	BOOL	isLOD() { return mSharedData && mSharedData->isLOD(); } -	void setAvatar(LLVOAvatar* avatarp) { mAvatarp = avatarp; } -	LLVOAvatar* getAvatar() { return mAvatarp; } +	void setAvatar(LLAvatarAppearance* avatarp) { mAvatarp = avatarp; } +	LLAvatarAppearance* getAvatar() { return mAvatarp; }  	LLDynamicArray<LLJointRenderData*>	mJointRenderData; @@ -362,77 +362,8 @@ protected:  	static LLPolyMeshSharedDataTable sGlobalSharedMeshList;  	// Backlink only; don't make this an LLPointer. -	LLVOAvatar* mAvatarp; +	LLAvatarAppearance* mAvatarp;  }; -//----------------------------------------------------------------------------- -// LLPolySkeletalDeformationInfo -// Shared information for LLPolySkeletalDeformations -//----------------------------------------------------------------------------- -struct LLPolySkeletalBoneInfo -{ -	LLPolySkeletalBoneInfo(std::string &name, LLVector3 &scale, LLVector3 &pos, BOOL haspos) -		: mBoneName(name), -		  mScaleDeformation(scale), -		  mPositionDeformation(pos), -		  mHasPositionDeformation(haspos) {} -	std::string mBoneName; -	LLVector3 mScaleDeformation; -	LLVector3 mPositionDeformation; -	BOOL mHasPositionDeformation; -}; - -class LLPolySkeletalDistortionInfo : public LLViewerVisualParamInfo -{ -	friend class LLPolySkeletalDistortion; -public: -	LLPolySkeletalDistortionInfo(); -	/*virtual*/ ~LLPolySkeletalDistortionInfo() {}; -	 -	/*virtual*/ BOOL parseXml(LLXmlTreeNode* node); - -protected: -	typedef std::vector<LLPolySkeletalBoneInfo> bone_info_list_t; -	bone_info_list_t mBoneInfoList; -}; - -//----------------------------------------------------------------------------- -// LLPolySkeletalDeformation -// A set of joint scale data for deforming the avatar mesh -//----------------------------------------------------------------------------- -class LLPolySkeletalDistortion : public LLViewerVisualParam -{ -public: -	LLPolySkeletalDistortion(LLVOAvatar *avatarp); -	~LLPolySkeletalDistortion(); - -	// Special: These functions are overridden by child classes -	LLPolySkeletalDistortionInfo*	getInfo() const { return (LLPolySkeletalDistortionInfo*)mInfo; } -	//   This sets mInfo and calls initialization functions -	BOOL							setInfo(LLPolySkeletalDistortionInfo *info); - -	/*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable) const; - -	// LLVisualParam Virtual functions -	///*virtual*/ BOOL				parseData(LLXmlTreeNode* node); -	/*virtual*/ void				apply( ESex sex ); -	 -	// LLViewerVisualParam Virtual functions -	/*virtual*/ F32					getTotalDistortion() { return 0.1f; } -	/*virtual*/ const LLVector4a&	getAvgDistortion()	{ return mDefaultVec; } -	/*virtual*/ F32					getMaxDistortion() { return 0.1f; } -	/*virtual*/ LLVector4a			getVertexDistortion(S32 index, LLPolyMesh *poly_mesh){return LLVector4a(0.001f, 0.001f, 0.001f);} -	/*virtual*/ const LLVector4a*	getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh){index = 0; poly_mesh = NULL; return &mDefaultVec;}; -	/*virtual*/ const LLVector4a*	getNextDistortion(U32 *index, LLPolyMesh **poly_mesh){index = 0; poly_mesh = NULL; return NULL;}; - -protected: -	typedef std::map<LLJoint*, LLVector3> joint_vec_map_t; -	joint_vec_map_t mJointScales; -	joint_vec_map_t mJointOffsets; -	LLVector4a	mDefaultVec; -	// Backlink only; don't make this an LLPointer. -	LLVOAvatar *mAvatar; -}; - -#endif // LL_LLPOLYMESH_H +#endif // LL_LLPOLYMESHINTERFACE_H diff --git a/indra/llappearance/llpolymorph.cpp b/indra/llappearance/llpolymorph.cpp new file mode 100644 index 0000000000..aa680894ff --- /dev/null +++ b/indra/llappearance/llpolymorph.cpp @@ -0,0 +1,748 @@ +/**  + * @file llpolymorph.cpp + * @brief Implementation of LLPolyMesh class + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +//----------------------------------------------------------------------------- +// Header Files +//----------------------------------------------------------------------------- + +#include "llpolymorph.h" +#include "llavatarappearance.h" +#include "llavatarjoint.h" +#include "llwearable.h" +#include "llxmltree.h" +#include "llendianswizzle.h" +#include "llpolymesh.h" + +//#include "../tools/imdebug/imdebug.h" + +const F32 NORMAL_SOFTEN_FACTOR = 0.65f; + +//----------------------------------------------------------------------------- +// LLPolyMorphData() +//----------------------------------------------------------------------------- +LLPolyMorphData::LLPolyMorphData(const std::string& morph_name) +	: mName(morph_name) +{ +	mNumIndices = 0; +	mCurrentIndex = 0; +	mTotalDistortion = 0.f; +	mAvgDistortion.clear(); +	mMaxDistortion = 0.f; +	mVertexIndices = NULL; +	mCoords = NULL; +	mNormals = NULL; +	mBinormals = NULL; +	mTexCoords = NULL; + +	mMesh = NULL; +} + +LLPolyMorphData::LLPolyMorphData(const LLPolyMorphData &rhs) : +	mName(rhs.mName), +	mNumIndices(rhs.mNumIndices), +	mTotalDistortion(rhs.mTotalDistortion), +	mAvgDistortion(rhs.mAvgDistortion), +	mMaxDistortion(rhs.mMaxDistortion), +	mVertexIndices(NULL), +	mCoords(NULL), +	mNormals(NULL), +	mBinormals(NULL), +	mTexCoords(NULL) +{ +	const S32 numVertices = mNumIndices; + +	mCoords = new LLVector4a[numVertices]; +	mNormals = new LLVector4a[numVertices]; +	mBinormals = new LLVector4a[numVertices]; +	mTexCoords = new LLVector2[numVertices]; +	mVertexIndices = new U32[numVertices]; +	 +	for (S32 v=0; v < numVertices; v++) +	{ +		mCoords[v] = rhs.mCoords[v]; +		mNormals[v] = rhs.mNormals[v]; +		mBinormals[v] = rhs.mBinormals[v]; +		mTexCoords[v] = rhs.mTexCoords[v]; +		mVertexIndices[v] = rhs.mVertexIndices[v]; +	} +} + + +//----------------------------------------------------------------------------- +// ~LLPolyMorphData() +//----------------------------------------------------------------------------- +LLPolyMorphData::~LLPolyMorphData() +{ +	delete [] mVertexIndices; +	delete [] mCoords; +	delete [] mNormals; +	delete [] mBinormals; +	delete [] mTexCoords; +} + +//----------------------------------------------------------------------------- +// loadBinary() +//----------------------------------------------------------------------------- +BOOL LLPolyMorphData::loadBinary(LLFILE *fp, LLPolyMeshSharedData *mesh) +{ +	S32 numVertices; +	S32 numRead; + +	numRead = fread(&numVertices, sizeof(S32), 1, fp); +	llendianswizzle(&numVertices, sizeof(S32), 1); +	if (numRead != 1) +	{ +		llwarns << "Can't read number of morph target vertices" << llendl; +		return FALSE; +	} + +	//------------------------------------------------------------------------- +	// allocate vertices +	//------------------------------------------------------------------------- +	mCoords = new LLVector4a[numVertices]; +	mNormals = new LLVector4a[numVertices]; +	mBinormals = new LLVector4a[numVertices]; +	mTexCoords = new LLVector2[numVertices]; +	// Actually, we are allocating more space than we need for the skiplist +	mVertexIndices = new U32[numVertices]; +	mNumIndices = 0; +	mTotalDistortion = 0.f; +	mMaxDistortion = 0.f; +	mAvgDistortion.clear(); +	mMesh = mesh; + +	//------------------------------------------------------------------------- +	// read vertices +	//------------------------------------------------------------------------- +	for(S32 v = 0; v < numVertices; v++) +	{ +		numRead = fread(&mVertexIndices[v], sizeof(U32), 1, fp); +		llendianswizzle(&mVertexIndices[v], sizeof(U32), 1); +		if (numRead != 1) +		{ +			llwarns << "Can't read morph target vertex number" << llendl; +			return FALSE; +		} + +		if (mVertexIndices[v] > 10000) +		{ +			llerrs << "Bad morph index: " << mVertexIndices[v] << llendl; +		} + + +		numRead = fread(&mCoords[v], sizeof(F32), 3, fp); +		llendianswizzle(&mCoords[v], sizeof(F32), 3); +		if (numRead != 3) +		{ +			llwarns << "Can't read morph target vertex coordinates" << llendl; +			return FALSE; +		} + +		F32 magnitude = mCoords[v].getLength3().getF32(); +		 +		mTotalDistortion += magnitude; +		LLVector4a t; +		t.setAbs(mCoords[v]); +		mAvgDistortion.add(t); +		 +		if (magnitude > mMaxDistortion) +		{ +			mMaxDistortion = magnitude; +		} + +		numRead = fread(&mNormals[v], sizeof(F32), 3, fp); +		llendianswizzle(&mNormals[v], sizeof(F32), 3); +		if (numRead != 3) +		{ +			llwarns << "Can't read morph target normal" << llendl; +			return FALSE; +		} + +		numRead = fread(&mBinormals[v], sizeof(F32), 3, fp); +		llendianswizzle(&mBinormals[v], sizeof(F32), 3); +		if (numRead != 3) +		{ +			llwarns << "Can't read morph target binormal" << llendl; +			return FALSE; +		} + + +		numRead = fread(&mTexCoords[v].mV, sizeof(F32), 2, fp); +		llendianswizzle(&mTexCoords[v].mV, sizeof(F32), 2); +		if (numRead != 2) +		{ +			llwarns << "Can't read morph target uv" << llendl; +			return FALSE; +		} + +		mNumIndices++; +	} + +	mAvgDistortion.mul(1.f/(F32)mNumIndices); +	mAvgDistortion.normalize3fast(); + +	return TRUE; +} + +//----------------------------------------------------------------------------- +// LLPolyMorphTargetInfo() +//----------------------------------------------------------------------------- +LLPolyMorphTargetInfo::LLPolyMorphTargetInfo() +	: mIsClothingMorph(FALSE) +{ +} + +BOOL LLPolyMorphTargetInfo::parseXml(LLXmlTreeNode* node) +{ +	llassert( node->hasName( "param" ) && node->getChildByName( "param_morph" ) ); + +	if (!LLViewerVisualParamInfo::parseXml(node)) +		return FALSE; + +	// Get mixed-case name +	static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name"); +	if( !node->getFastAttributeString( name_string, mMorphName ) ) +	{ +		llwarns << "Avatar file: <param> is missing name attribute" << llendl; +		return FALSE;  // Continue, ignoring this tag +	} + +	static LLStdStringHandle clothing_morph_string = LLXmlTree::addAttributeString("clothing_morph"); +	node->getFastAttributeBOOL(clothing_morph_string, mIsClothingMorph); + +	LLXmlTreeNode *paramNode = node->getChildByName("param_morph"); + +        if (NULL == paramNode) +        { +                llwarns << "Failed to getChildByName(\"param_morph\")" +                        << llendl; +                return FALSE; +        } + +	for (LLXmlTreeNode* child_node = paramNode->getFirstChild(); +		 child_node; +		 child_node = paramNode->getNextChild()) +	{ +		static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name"); +		if (child_node->hasName("volume_morph")) +		{ +			std::string volume_name; +			if (child_node->getFastAttributeString(name_string, volume_name)) +			{ +				LLVector3 scale; +				static LLStdStringHandle scale_string = LLXmlTree::addAttributeString("scale"); +				child_node->getFastAttributeVector3(scale_string, scale); +				 +				LLVector3 pos; +				static LLStdStringHandle pos_string = LLXmlTree::addAttributeString("pos"); +				child_node->getFastAttributeVector3(pos_string, pos); + +				mVolumeInfoList.push_back(LLPolyVolumeMorphInfo(volume_name,scale,pos)); +			} +		} +	} +	 +	return TRUE; +} + +//----------------------------------------------------------------------------- +// LLPolyMorphTarget() +//----------------------------------------------------------------------------- +LLPolyMorphTarget::LLPolyMorphTarget(LLPolyMesh *poly_mesh) +	: mMorphData(NULL), mMesh(poly_mesh), +	  mVertMask(NULL), +	  mLastSex(SEX_FEMALE), +	  mNumMorphMasksPending(0) +{ +} + +//----------------------------------------------------------------------------- +// ~LLPolyMorphTarget() +//----------------------------------------------------------------------------- +LLPolyMorphTarget::~LLPolyMorphTarget() +{ +	if (mVertMask) +	{ +		delete mVertMask; +	} +} + +//----------------------------------------------------------------------------- +// setInfo() +//----------------------------------------------------------------------------- +BOOL LLPolyMorphTarget::setInfo(LLPolyMorphTargetInfo* info) +{ +	llassert(mInfo == NULL); +	if (info->mID < 0) +		return FALSE; +	mInfo = info; +	mID = info->mID; +	setWeight(getDefaultWeight(), FALSE ); + +	LLAvatarAppearance* avatarp = mMesh->getAvatar(); +	LLPolyMorphTargetInfo::volume_info_list_t::iterator iter; +	for (iter = getInfo()->mVolumeInfoList.begin(); iter != getInfo()->mVolumeInfoList.end(); iter++) +	{ +		LLPolyVolumeMorphInfo *volume_info = &(*iter); +		for (S32 i = 0; i < avatarp->mNumCollisionVolumes; i++) +		{ +			if (avatarp->mCollisionVolumes[i].getName() == volume_info->mName) +			{ +				mVolumeMorphs.push_back(LLPolyVolumeMorph(&avatarp->mCollisionVolumes[i], +														  volume_info->mScale, +														  volume_info->mPos)); +				break; +			} +		} +	} + +	std::string morph_param_name = getInfo()->mMorphName; +	 +	mMorphData = mMesh->getMorphData(morph_param_name); +	if (!mMorphData) +	{ +		const std::string driven_tag = "_Driven"; +		U32 pos = morph_param_name.find(driven_tag); +		if (pos > 0) +		{ +			morph_param_name = morph_param_name.substr(0,pos); +			mMorphData = mMesh->getMorphData(morph_param_name); +		} +	} +	if (!mMorphData) +	{ +		llwarns << "No morph target named " << morph_param_name << " found in mesh." << llendl; +		return FALSE;  // Continue, ignoring this tag +	} +	return TRUE; +} + +/*virtual*/ LLViewerVisualParam* LLPolyMorphTarget::cloneParam(LLWearable* wearable) const +{ +	LLPolyMorphTarget *new_param = new LLPolyMorphTarget(mMesh); +	*new_param = *this; +	return new_param; +} + +#if 0 // obsolete +//----------------------------------------------------------------------------- +// parseData() +//----------------------------------------------------------------------------- +BOOL LLPolyMorphTarget::parseData(LLXmlTreeNode* node) +{ +	LLPolyMorphTargetInfo* info = new LLPolyMorphTargetInfo; + +	info->parseXml(node); +	if (!setInfo(info)) +	{ +		delete info; +		return FALSE; +	} +	return TRUE; +} +#endif + +//----------------------------------------------------------------------------- +// getVertexDistortion() +//----------------------------------------------------------------------------- +LLVector4a LLPolyMorphTarget::getVertexDistortion(S32 requested_index, LLPolyMesh *mesh) +{ +	if (!mMorphData || mMesh != mesh) return LLVector4a::getZero(); + +	for(U32 index = 0; index < mMorphData->mNumIndices; index++) +	{ +		if (mMorphData->mVertexIndices[index] == (U32)requested_index) +		{ +			return mMorphData->mCoords[index]; +		} +	} + +	return LLVector4a::getZero(); +} + +//----------------------------------------------------------------------------- +// getFirstDistortion() +//----------------------------------------------------------------------------- +const LLVector4a *LLPolyMorphTarget::getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh) +{ +	if (!mMorphData) return &LLVector4a::getZero(); + +	LLVector4a* resultVec; +	mMorphData->mCurrentIndex = 0; +	if (mMorphData->mNumIndices) +	{ +		resultVec = &mMorphData->mCoords[mMorphData->mCurrentIndex]; +		if (index != NULL) +		{ +			*index = mMorphData->mVertexIndices[mMorphData->mCurrentIndex]; +		} +		if (poly_mesh != NULL) +		{ +			*poly_mesh = mMesh; +		} + +		return resultVec; +	} +	return NULL; +} + +//----------------------------------------------------------------------------- +// getNextDistortion() +//----------------------------------------------------------------------------- +const LLVector4a *LLPolyMorphTarget::getNextDistortion(U32 *index, LLPolyMesh **poly_mesh) +{ +	if (!mMorphData) return &LLVector4a::getZero(); + +	LLVector4a* resultVec; +	mMorphData->mCurrentIndex++; +	if (mMorphData->mCurrentIndex < mMorphData->mNumIndices) +	{ +		resultVec = &mMorphData->mCoords[mMorphData->mCurrentIndex]; +		if (index != NULL) +		{ +			*index = mMorphData->mVertexIndices[mMorphData->mCurrentIndex]; +		} +		if (poly_mesh != NULL) +		{ +			*poly_mesh = mMesh; +		} +		return resultVec; +	} +	return NULL; +} + +//----------------------------------------------------------------------------- +// getTotalDistortion() +//----------------------------------------------------------------------------- +F32	LLPolyMorphTarget::getTotalDistortion()  +{  +	if (mMorphData)  +	{ +		return mMorphData->mTotalDistortion;  +	} +	else  +	{ +		return 0.f; +	} +} + +//----------------------------------------------------------------------------- +// getAvgDistortion() +//----------------------------------------------------------------------------- +const LLVector4a& LLPolyMorphTarget::getAvgDistortion()	 +{ +	if (mMorphData)  +	{ +		return mMorphData->mAvgDistortion;  +	} +	else  +	{ +		return LLVector4a::getZero(); +	} +} + +//----------------------------------------------------------------------------- +// getMaxDistortion() +//----------------------------------------------------------------------------- +F32	LLPolyMorphTarget::getMaxDistortion()  +{ +	if (mMorphData)  +	{ +		return mMorphData->mMaxDistortion;  +	} +	else +	{ +		return 0.f; +	} +} + +//----------------------------------------------------------------------------- +// apply() +//----------------------------------------------------------------------------- +static LLFastTimer::DeclareTimer FTM_APPLY_MORPH_TARGET("Apply Morph"); + +void LLPolyMorphTarget::apply( ESex avatar_sex ) +{ +	if (!mMorphData || mNumMorphMasksPending > 0) +	{ +		return; +	} + +	LLFastTimer t(FTM_APPLY_MORPH_TARGET); + +	mLastSex = avatar_sex; + +	// Check for NaN condition (NaN is detected if a variable doesn't equal itself. +	if (mCurWeight != mCurWeight) +	{ +		mCurWeight = 0.0; +	} +	if (mLastWeight != mLastWeight) +	{ +		mLastWeight = mCurWeight+.001; +	} + +	// perform differential update of morph +	F32 delta_weight = ( getSex() & avatar_sex ) ? (mCurWeight - mLastWeight) : (getDefaultWeight() - mLastWeight); +	// store last weight +	mLastWeight += delta_weight; + +	if (delta_weight != 0.f) +	{ +		llassert(!mMesh->isLOD()); +		LLVector4a *coords = mMesh->getWritableCoords(); + +		LLVector4a *scaled_normals = mMesh->getScaledNormals(); +		LLVector4a *normals = mMesh->getWritableNormals(); + +		LLVector4a *scaled_binormals = mMesh->getScaledBinormals(); +		LLVector4a *binormals = mMesh->getWritableBinormals(); + +		LLVector4a *clothing_weights = mMesh->getWritableClothingWeights(); +		LLVector2 *tex_coords = mMesh->getWritableTexCoords(); + +		F32 *maskWeightArray = (mVertMask) ? mVertMask->getMorphMaskWeights() : NULL; + +		for(U32 vert_index_morph = 0; vert_index_morph < mMorphData->mNumIndices; vert_index_morph++) +		{ +			S32 vert_index_mesh = mMorphData->mVertexIndices[vert_index_morph]; + +			F32 maskWeight = 1.f; +			if (maskWeightArray) +			{ +				maskWeight = maskWeightArray[vert_index_morph]; +			} + + +			LLVector4a pos = mMorphData->mCoords[vert_index_morph]; +			pos.mul(delta_weight*maskWeight); +			coords[vert_index_mesh].add(pos); + +			if (getInfo()->mIsClothingMorph && clothing_weights) +			{ +				LLVector4a clothing_offset = mMorphData->mCoords[vert_index_morph]; +				clothing_offset.mul(delta_weight * maskWeight); +				LLVector4a* clothing_weight = &clothing_weights[vert_index_mesh]; +				clothing_weight->add(clothing_offset); +				clothing_weight->getF32ptr()[VW] = maskWeight; +			} + +			// calculate new normals based on half angles +			LLVector4a norm = mMorphData->mNormals[vert_index_morph]; +			norm.mul(delta_weight*maskWeight*NORMAL_SOFTEN_FACTOR); +			scaled_normals[vert_index_mesh].add(norm); +			norm = scaled_normals[vert_index_mesh]; +			norm.normalize3fast(); +			normals[vert_index_mesh] = norm; + +			// calculate new binormals +			LLVector4a binorm = mMorphData->mBinormals[vert_index_morph]; +			binorm.mul(delta_weight*maskWeight*NORMAL_SOFTEN_FACTOR); +			scaled_binormals[vert_index_mesh].add(binorm); +			LLVector4a tangent; +			tangent.setCross3(scaled_binormals[vert_index_mesh], norm); +			LLVector4a& normalized_binormal = binormals[vert_index_mesh]; +			normalized_binormal.setCross3(norm, tangent);  +			normalized_binormal.normalize3fast(); +			 +			tex_coords[vert_index_mesh] += mMorphData->mTexCoords[vert_index_morph] * delta_weight * maskWeight; +		} + +		// now apply volume changes +		for( volume_list_t::iterator iter = mVolumeMorphs.begin(); iter != mVolumeMorphs.end(); iter++ ) +		{ +			LLPolyVolumeMorph* volume_morph = &(*iter); +			LLVector3 scale_delta = volume_morph->mScale * delta_weight; +			LLVector3 pos_delta = volume_morph->mPos * delta_weight; +			 +			volume_morph->mVolume->setScale(volume_morph->mVolume->getScale() + scale_delta); +			volume_morph->mVolume->setPosition(volume_morph->mVolume->getPosition() + pos_delta); +		} +	} + +	if (mNext) +	{ +		mNext->apply(avatar_sex); +	} +} + +//----------------------------------------------------------------------------- +// applyMask() +//----------------------------------------------------------------------------- +void	LLPolyMorphTarget::applyMask(U8 *maskTextureData, S32 width, S32 height, S32 num_components, BOOL invert) +{ +	LLVector4a *clothing_weights = getInfo()->mIsClothingMorph ? mMesh->getWritableClothingWeights() : NULL; + +	if (!mVertMask) +	{ +		mVertMask = new LLPolyVertexMask(mMorphData); +		mNumMorphMasksPending--; +	} +	else +	{ +		// remove effect of previous mask +		F32 *maskWeights = (mVertMask) ? mVertMask->getMorphMaskWeights() : NULL; + +		if (maskWeights) +		{ +			LLVector4a *coords = mMesh->getWritableCoords(); +			LLVector4a *scaled_normals = mMesh->getScaledNormals(); +			LLVector4a *scaled_binormals = mMesh->getScaledBinormals(); +			LLVector2 *tex_coords = mMesh->getWritableTexCoords(); + +			LLVector4Logical clothing_mask; +			clothing_mask.clear(); +			clothing_mask.setElement<0>(); +			clothing_mask.setElement<1>(); +			clothing_mask.setElement<2>(); + + +			for(U32 vert = 0; vert < mMorphData->mNumIndices; vert++) +			{ +				F32 lastMaskWeight = mLastWeight * maskWeights[vert]; +				S32 out_vert = mMorphData->mVertexIndices[vert]; + +				// remove effect of existing masked morph +				LLVector4a t; +				t = mMorphData->mCoords[vert]; +				t.mul(lastMaskWeight); +				coords[out_vert].sub(t); + +				t = mMorphData->mNormals[vert]; +				t.mul(lastMaskWeight*NORMAL_SOFTEN_FACTOR); +				scaled_normals[out_vert].sub(t); + +				t = mMorphData->mBinormals[vert]; +				t.mul(lastMaskWeight*NORMAL_SOFTEN_FACTOR); +				scaled_binormals[out_vert].sub(t); + +				tex_coords[out_vert] -= mMorphData->mTexCoords[vert] * lastMaskWeight; + +				if (clothing_weights) +				{ +					LLVector4a clothing_offset = mMorphData->mCoords[vert]; +					clothing_offset.mul(lastMaskWeight); +					LLVector4a* clothing_weight = &clothing_weights[out_vert]; +					LLVector4a t; +					t.setSub(*clothing_weight, clothing_offset); +					clothing_weight->setSelectWithMask(clothing_mask, t, *clothing_weight); +				} +			} +		} +	} + +	// set last weight to 0, since we've removed the effect of this morph +	mLastWeight = 0.f; + +	mVertMask->generateMask(maskTextureData, width, height, num_components, invert, clothing_weights); + +	apply(mLastSex); +} + + +//----------------------------------------------------------------------------- +// LLPolyVertexMask() +//----------------------------------------------------------------------------- +LLPolyVertexMask::LLPolyVertexMask(LLPolyMorphData* morph_data) +{ +	mWeights = new F32[morph_data->mNumIndices]; +	mMorphData = morph_data; +	mWeightsGenerated = FALSE; +} + +//----------------------------------------------------------------------------- +// ~LLPolyVertexMask() +//----------------------------------------------------------------------------- +LLPolyVertexMask::~LLPolyVertexMask() +{ +	delete[] mWeights; +} + +//----------------------------------------------------------------------------- +// generateMask() +//----------------------------------------------------------------------------- +void LLPolyVertexMask::generateMask(U8 *maskTextureData, S32 width, S32 height, S32 num_components, BOOL invert, LLVector4a *clothing_weights) +{ +// RN debug output that uses Image Debugger (http://www.cs.unc.edu/~baxter/projects/imdebug/) +//	BOOL debugImg = FALSE;  +//	if (debugImg) +//	{ +//		if (invert) +//		{ +//			imdebug("lum rbga=rgba b=8 w=%d h=%d *-1 %p", width, height, maskTextureData); +//		} +//		else +//		{ +//			imdebug("lum rbga=rgba b=8 w=%d h=%d %p", width, height, maskTextureData); +//		} +//	} +	for (U32 index = 0; index < mMorphData->mNumIndices; index++) +	{ +		S32 vertIndex = mMorphData->mVertexIndices[index]; +		const S32 *sharedVertIndex = mMorphData->mMesh->getSharedVert(vertIndex); +		LLVector2 uvCoords; + +		if (sharedVertIndex) +		{ +			uvCoords = mMorphData->mMesh->getUVs(*sharedVertIndex); +		} +		else +		{ +			uvCoords = mMorphData->mMesh->getUVs(vertIndex); +		} +		U32 s = llclamp((U32)(uvCoords.mV[VX] * (F32)(width - 1)), (U32)0, (U32)width - 1); +		U32 t = llclamp((U32)(uvCoords.mV[VY] * (F32)(height - 1)), (U32)0, (U32)height - 1); +		 +		mWeights[index] = ((F32) maskTextureData[((t * width + s) * num_components) + (num_components - 1)]) / 255.f; +		 +		if (invert)  +		{ +			mWeights[index] = 1.f - mWeights[index]; +		} + +		// now apply step function +		// mWeights[index] = mWeights[index] > 0.95f ? 1.f : 0.f; + +		if (clothing_weights) +		{ +			clothing_weights[vertIndex].getF32ptr()[VW] = mWeights[index]; +		} +	} +	mWeightsGenerated = TRUE; +} + +//----------------------------------------------------------------------------- +// getMaskForMorphIndex() +//----------------------------------------------------------------------------- +F32* LLPolyVertexMask::getMorphMaskWeights() +{ +	if (!mWeightsGenerated) +	{ +		return NULL; +	} +	 +	return mWeights; +} diff --git a/indra/llappearance/llpolymorph.h b/indra/llappearance/llpolymorph.h new file mode 100644 index 0000000000..d6cf9e52ca --- /dev/null +++ b/indra/llappearance/llpolymorph.h @@ -0,0 +1,182 @@ +/**  + * @file llpolymorph.h + * @brief Implementation of LLPolyMesh class + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLPOLYMORPH_H +#define LL_LLPOLYMORPH_H + +#include <string> +#include <vector> + +#include "llviewervisualparam.h" + +class LLAvatarJointCollisionVolume; +class LLPolyMeshSharedData; +class LLVector2; +class LLAvatarJointCollisionVolume; +class LLWearable; + +//----------------------------------------------------------------------------- +// LLPolyMorphData() +//----------------------------------------------------------------------------- +class LLPolyMorphData +{ +public: +	LLPolyMorphData(const std::string& morph_name); +	~LLPolyMorphData(); +	LLPolyMorphData(const LLPolyMorphData &rhs); + +	BOOL			loadBinary(LLFILE* fp, LLPolyMeshSharedData *mesh); +	const std::string& getName() { return mName; } + +public: +	std::string			mName; + +	// morphology +	U32					mNumIndices; +	U32*				mVertexIndices; +	U32					mCurrentIndex; +	LLVector4a*			mCoords; +	LLVector4a*			mNormals; +	LLVector4a*			mBinormals; +	LLVector2*			mTexCoords; + +	F32					mTotalDistortion;	// vertex distortion summed over entire morph +	F32					mMaxDistortion;		// maximum single vertex distortion in a given morph +	LLVector4a			mAvgDistortion;		// average vertex distortion, to infer directionality of the morph +	LLPolyMeshSharedData*	mMesh; +}; + +//----------------------------------------------------------------------------- +// LLPolyVertexMask() +//----------------------------------------------------------------------------- +class LLPolyVertexMask +{ +public: +	LLPolyVertexMask(LLPolyMorphData* morph_data); +	~LLPolyVertexMask(); + +	void generateMask(U8 *maskData, S32 width, S32 height, S32 num_components, BOOL invert, LLVector4a *clothing_weights); +	F32* getMorphMaskWeights(); + + +protected: +	F32*		mWeights; +	LLPolyMorphData *mMorphData; +	BOOL			mWeightsGenerated; + +}; + +//----------------------------------------------------------------------------- +// LLPolyMorphTarget Data structs +//----------------------------------------------------------------------------- +struct LLPolyVolumeMorphInfo +{ +	LLPolyVolumeMorphInfo(std::string &name, LLVector3 &scale, LLVector3 &pos) +		: mName(name), mScale(scale), mPos(pos) {}; + +	std::string						mName; +	LLVector3						mScale; +	LLVector3						mPos; +}; + +struct LLPolyVolumeMorph +{ +	LLPolyVolumeMorph(LLAvatarJointCollisionVolume* volume, LLVector3 scale, LLVector3 pos) +		: mVolume(volume), mScale(scale), mPos(pos) {}; + +	LLAvatarJointCollisionVolume*	mVolume; +	LLVector3						mScale; +	LLVector3						mPos; +}; + +//----------------------------------------------------------------------------- +// LLPolyMorphTargetInfo +// Shared information for LLPolyMorphTargets +//----------------------------------------------------------------------------- +class LLPolyMorphTargetInfo : public LLViewerVisualParamInfo +{ +	friend class LLPolyMorphTarget; +public: +	LLPolyMorphTargetInfo(); +	/*virtual*/ ~LLPolyMorphTargetInfo() {}; +	 +	/*virtual*/ BOOL parseXml(LLXmlTreeNode* node); + +protected: +	std::string		mMorphName; +	BOOL			mIsClothingMorph; +	typedef std::vector<LLPolyVolumeMorphInfo> volume_info_list_t; +	volume_info_list_t mVolumeInfoList;	 +}; + +//----------------------------------------------------------------------------- +// LLPolyMorphTarget +// A set of vertex data associated with morph target. +// These morph targets must be topologically consistent with a given Polymesh +// (share face sets) +//----------------------------------------------------------------------------- +class LLPolyMorphTarget : public LLViewerVisualParam +{ +public: +	LLPolyMorphTarget(LLPolyMesh *poly_mesh); +	~LLPolyMorphTarget(); + +	// Special: These functions are overridden by child classes +	LLPolyMorphTargetInfo*	getInfo() const { return (LLPolyMorphTargetInfo*)mInfo; } +	//   This sets mInfo and calls initialization functions +	BOOL					setInfo(LLPolyMorphTargetInfo *info); + +	/*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable) const; + +	// LLVisualParam Virtual functions +	///*virtual*/ BOOL				parseData(LLXmlTreeNode* node); +	/*virtual*/ void				apply( ESex sex ); +	 +	// LLViewerVisualParam Virtual functions +	/*virtual*/ F32					getTotalDistortion(); +	/*virtual*/ const LLVector4a&	getAvgDistortion(); +	/*virtual*/ F32					getMaxDistortion(); +	/*virtual*/ LLVector4a			getVertexDistortion(S32 index, LLPolyMesh *poly_mesh); +	/*virtual*/ const LLVector4a*	getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh); +	/*virtual*/ const LLVector4a*	getNextDistortion(U32 *index, LLPolyMesh **poly_mesh); + +	void	applyMask(U8 *maskData, S32 width, S32 height, S32 num_components, BOOL invert); +	void	addPendingMorphMask() { mNumMorphMasksPending++; } + +protected: +	LLPolyMorphData*				mMorphData; +	LLPolyMesh*						mMesh; +	LLPolyVertexMask *				mVertMask; +	ESex							mLastSex; +	// number of morph masks that haven't been generated, must be 0 before this morph is applied +	BOOL							mNumMorphMasksPending;	 + +	typedef std::vector<LLPolyVolumeMorph> volume_list_t; +	volume_list_t 					mVolumeMorphs; + +}; + +#endif // LL_LLPOLYMORPH_H diff --git a/indra/llappearance/llpolyskeletaldistortion.cpp b/indra/llappearance/llpolyskeletaldistortion.cpp new file mode 100644 index 0000000000..4ba16691c2 --- /dev/null +++ b/indra/llappearance/llpolyskeletaldistortion.cpp @@ -0,0 +1,293 @@ +/**  + * @file llpolyskeletaldistortion.cpp + * @brief Implementation of LLPolySkeletalDistortion classes + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +//----------------------------------------------------------------------------- +// Header Files +//----------------------------------------------------------------------------- +#include "llpreprocessor.h" +#include "llerrorlegacy.h" +//#include "llcommon.h" +//#include "llmemory.h" +#include "llavatarappearance.h" +#include "llavatarjoint.h" +#include "llpolymorph.h" +//#include "llviewercontrol.h" +//#include "llxmltree.h" +//#include "llvoavatar.h" +#include "llwearable.h" +//#include "lldir.h" +//#include "llvolume.h" +//#include "llendianswizzle.h" + +#include "llpolyskeletaldistortion.h" + +//----------------------------------------------------------------------------- +// LLPolySkeletalDistortionInfo() +//----------------------------------------------------------------------------- +LLPolySkeletalDistortionInfo::LLPolySkeletalDistortionInfo() +{ +} + +BOOL LLPolySkeletalDistortionInfo::parseXml(LLXmlTreeNode* node) +{ +        llassert( node->hasName( "param" ) && node->getChildByName( "param_skeleton" ) ); +         +        if (!LLViewerVisualParamInfo::parseXml(node)) +                return FALSE; + +        LLXmlTreeNode* skeletalParam = node->getChildByName("param_skeleton"); + +        if (NULL == skeletalParam) +        { +                llwarns << "Failed to getChildByName(\"param_skeleton\")" +                        << llendl; +                return FALSE; +        } + +        for( LLXmlTreeNode* bone = skeletalParam->getFirstChild(); bone; bone = skeletalParam->getNextChild() ) +        { +                if (bone->hasName("bone")) +                { +                        std::string name; +                        LLVector3 scale; +                        LLVector3 pos; +                        BOOL haspos = FALSE; +                         +                        static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name"); +                        if (!bone->getFastAttributeString(name_string, name)) +                        { +                                llwarns << "No bone name specified for skeletal param." << llendl; +                                continue; +                        } + +                        static LLStdStringHandle scale_string = LLXmlTree::addAttributeString("scale"); +                        if (!bone->getFastAttributeVector3(scale_string, scale)) +                        { +                                llwarns << "No scale specified for bone " << name << "." << llendl; +                                continue; +                        } + +                        // optional offset deformation (translation) +                        static LLStdStringHandle offset_string = LLXmlTree::addAttributeString("offset"); +                        if (bone->getFastAttributeVector3(offset_string, pos)) +                        { +                                haspos = TRUE; +                        } +                        mBoneInfoList.push_back(LLPolySkeletalBoneInfo(name, scale, pos, haspos)); +                } +                else +                { +                        llwarns << "Unrecognized element " << bone->getName() << " in skeletal distortion" << llendl; +                        continue; +                } +        } +        return TRUE; +} + +//----------------------------------------------------------------------------- +// LLPolySkeletalDistortion() +//----------------------------------------------------------------------------- +LLPolySkeletalDistortion::LLPolySkeletalDistortion(LLAvatarAppearance *avatarp) +{ +        mAvatar = avatarp; +        mDefaultVec.splat(0.001f); +} + +//----------------------------------------------------------------------------- +// ~LLPolySkeletalDistortion() +//----------------------------------------------------------------------------- +LLPolySkeletalDistortion::~LLPolySkeletalDistortion() +{ +} + +BOOL LLPolySkeletalDistortion::setInfo(LLPolySkeletalDistortionInfo *info) +{ +        llassert(mInfo == NULL); +        if (info->mID < 0) +                return FALSE; +        mInfo = info; +        mID = info->mID; +        setWeight(getDefaultWeight(), FALSE ); + +        LLPolySkeletalDistortionInfo::bone_info_list_t::iterator iter; +        for (iter = getInfo()->mBoneInfoList.begin(); iter != getInfo()->mBoneInfoList.end(); iter++) +        { +                LLPolySkeletalBoneInfo *bone_info = &(*iter); +                LLJoint* joint = mAvatar->getJoint(bone_info->mBoneName); +                if (!joint) +                { +                        llwarns << "Joint " << bone_info->mBoneName << " not found." << llendl; +                        continue; +                } + +                if (mJointScales.find(joint) != mJointScales.end()) +                { +                        llwarns << "Scale deformation already supplied for joint " << joint->getName() << "." << llendl; +                } + +                // store it +                mJointScales[joint] = bone_info->mScaleDeformation; + +                // apply to children that need to inherit it +                for (LLJoint::child_list_t::iterator iter = joint->mChildren.begin(); +                     iter != joint->mChildren.end(); ++iter) +                { +                        LLAvatarJoint* child_joint = (LLAvatarJoint*)(*iter); +                        if (child_joint->inheritScale()) +                        { +                                LLVector3 childDeformation = LLVector3(child_joint->getScale()); +                                childDeformation.scaleVec(bone_info->mScaleDeformation); +                                mJointScales[child_joint] = childDeformation; +                        } +                } + +                if (bone_info->mHasPositionDeformation) +                { +                        if (mJointOffsets.find(joint) != mJointOffsets.end()) +                        { +                                llwarns << "Offset deformation already supplied for joint " << joint->getName() << "." << llendl; +                        } +                        mJointOffsets[joint] = bone_info->mPositionDeformation; +                } +        } +        return TRUE; +} + +/*virtual*/ LLViewerVisualParam* LLPolySkeletalDistortion::cloneParam(LLWearable* wearable) const +{ +        LLPolySkeletalDistortion *new_param = new LLPolySkeletalDistortion(mAvatar); +        *new_param = *this; +        return new_param; +} + +//----------------------------------------------------------------------------- +// apply() +//----------------------------------------------------------------------------- +static LLFastTimer::DeclareTimer FTM_POLYSKELETAL_DISTORTION_APPLY("Skeletal Distortion"); + +void LLPolySkeletalDistortion::apply( ESex avatar_sex ) +{ +	LLFastTimer t(FTM_POLYSKELETAL_DISTORTION_APPLY); + +        F32 effective_weight = ( getSex() & avatar_sex ) ? mCurWeight : getDefaultWeight(); + +        LLJoint* joint; +        joint_vec_map_t::iterator iter; + +        for (iter = mJointScales.begin(); +             iter != mJointScales.end(); +             iter++) +        { +                joint = iter->first; +                LLVector3 newScale = joint->getScale(); +                LLVector3 scaleDelta = iter->second; +                newScale = newScale + (effective_weight * scaleDelta) - (mLastWeight * scaleDelta); +                joint->setScale(newScale); +        } + +        for (iter = mJointOffsets.begin(); +             iter != mJointOffsets.end(); +             iter++) +        { +                joint = iter->first; +                LLVector3 newPosition = joint->getPosition(); +                LLVector3 positionDelta = iter->second; +                newPosition = newPosition + (effective_weight * positionDelta) - (mLastWeight * positionDelta); +                joint->setPosition(newPosition); +        } + +        if (mLastWeight != mCurWeight && !mIsAnimating) +        { +                mAvatar->setSkeletonSerialNum(mAvatar->getSkeletonSerialNum() + 1); +        } +        mLastWeight = mCurWeight; +} + + +LLPolyMorphData *clone_morph_param_duplicate(const LLPolyMorphData *src_data, +					     const std::string &name) +{ +        LLPolyMorphData* cloned_morph_data = new LLPolyMorphData(*src_data); +        cloned_morph_data->mName = name; +        for (U32 v=0; v < cloned_morph_data->mNumIndices; v++) +        { +                cloned_morph_data->mCoords[v] = src_data->mCoords[v]; +                cloned_morph_data->mNormals[v] = src_data->mNormals[v]; +                cloned_morph_data->mBinormals[v] = src_data->mBinormals[v]; +        } +        return cloned_morph_data; +} + +LLPolyMorphData *clone_morph_param_direction(const LLPolyMorphData *src_data, +					     const LLVector3 &direction, +					     const std::string &name) +{ +        LLPolyMorphData* cloned_morph_data = new LLPolyMorphData(*src_data); +        cloned_morph_data->mName = name; +		LLVector4a dir; +		dir.load3(direction.mV); + +        for (U32 v=0; v < cloned_morph_data->mNumIndices; v++) +        { +                cloned_morph_data->mCoords[v] = dir; +                cloned_morph_data->mNormals[v].clear(); +                cloned_morph_data->mBinormals[v].clear(); +        } +        return cloned_morph_data; +} + +LLPolyMorphData *clone_morph_param_cleavage(const LLPolyMorphData *src_data, +                                            F32 scale, +                                            const std::string &name) +{ +        LLPolyMorphData* cloned_morph_data = new LLPolyMorphData(*src_data); +        cloned_morph_data->mName = name; + +		LLVector4a sc; +		sc.splat(scale); + +		LLVector4a nsc; +		nsc.set(scale, -scale, scale, scale); + +        for (U32 v=0; v < cloned_morph_data->mNumIndices; v++) +        { +            if (cloned_morph_data->mCoords[v][1] < 0) +            { +                cloned_morph_data->mCoords[v].setMul(src_data->mCoords[v],nsc); +				cloned_morph_data->mNormals[v].setMul(src_data->mNormals[v],nsc); +				cloned_morph_data->mBinormals[v].setMul(src_data->mBinormals[v],nsc); +			} +			else +			{ +				cloned_morph_data->mCoords[v].setMul(src_data->mCoords[v],sc); +				cloned_morph_data->mNormals[v].setMul(src_data->mNormals[v], sc); +				cloned_morph_data->mBinormals[v].setMul(src_data->mBinormals[v],sc); +			} +        } +        return cloned_morph_data; +} + +// End diff --git a/indra/llappearance/llpolyskeletaldistortion.h b/indra/llappearance/llpolyskeletaldistortion.h new file mode 100644 index 0000000000..040cf841ea --- /dev/null +++ b/indra/llappearance/llpolyskeletaldistortion.h @@ -0,0 +1,119 @@ +/**  + * @file llpolyskeletaldistortion.h + * @brief Implementation of LLPolyMesh class + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLPOLYSKELETALDISTORTION_H +#define LL_LLPOLYSKELETALDISTORTION_H + +#include "llcommon.h" + +#include <string> +#include <map> +#include "llstl.h" + +#include "v3math.h" +#include "v2math.h" +#include "llquaternion.h" +//#include "llpolymorph.h" +#include "lljoint.h" +#include "llviewervisualparam.h" +//#include "lldarray.h" + +//class LLSkinJoint; +class LLAvatarAppearance; + +//#define USE_STRIPS	// Use tri-strips for rendering. + +//----------------------------------------------------------------------------- +// LLPolySkeletalDeformationInfo +// Shared information for LLPolySkeletalDeformations +//----------------------------------------------------------------------------- +struct LLPolySkeletalBoneInfo +{ +	LLPolySkeletalBoneInfo(std::string &name, LLVector3 &scale, LLVector3 &pos, BOOL haspos) +		: mBoneName(name), +		  mScaleDeformation(scale), +		  mPositionDeformation(pos), +		  mHasPositionDeformation(haspos) {} +	std::string mBoneName; +	LLVector3 mScaleDeformation; +	LLVector3 mPositionDeformation; +	BOOL mHasPositionDeformation; +}; + +class LLPolySkeletalDistortionInfo : public LLViewerVisualParamInfo +{ +	friend class LLPolySkeletalDistortion; +public: +	LLPolySkeletalDistortionInfo(); +	/*virtual*/ ~LLPolySkeletalDistortionInfo() {}; +	 +	/*virtual*/ BOOL parseXml(LLXmlTreeNode* node); + +protected: +	typedef std::vector<LLPolySkeletalBoneInfo> bone_info_list_t; +	bone_info_list_t mBoneInfoList; +}; + +//----------------------------------------------------------------------------- +// LLPolySkeletalDeformation +// A set of joint scale data for deforming the avatar mesh +//----------------------------------------------------------------------------- +class LLPolySkeletalDistortion : public LLViewerVisualParam +{ +public: +	LLPolySkeletalDistortion(LLAvatarAppearance *avatarp); +	~LLPolySkeletalDistortion(); + +	// Special: These functions are overridden by child classes +	LLPolySkeletalDistortionInfo*	getInfo() const { return (LLPolySkeletalDistortionInfo*)mInfo; } +	//   This sets mInfo and calls initialization functions +	BOOL							setInfo(LLPolySkeletalDistortionInfo *info); + +	/*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable) const; + +	// LLVisualParam Virtual functions +	///*virtual*/ BOOL				parseData(LLXmlTreeNode* node); +	/*virtual*/ void				apply( ESex sex ); +	 +	// LLViewerVisualParam Virtual functions +	/*virtual*/ F32					getTotalDistortion() { return 0.1f; } +	/*virtual*/ const LLVector4a&	getAvgDistortion()	{ return mDefaultVec; } +	/*virtual*/ F32					getMaxDistortion() { return 0.1f; } +	/*virtual*/ LLVector4a			getVertexDistortion(S32 index, LLPolyMesh *poly_mesh){return LLVector4a(0.001f, 0.001f, 0.001f);} +	/*virtual*/ const LLVector4a*	getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh){index = 0; poly_mesh = NULL; return &mDefaultVec;}; +	/*virtual*/ const LLVector4a*	getNextDistortion(U32 *index, LLPolyMesh **poly_mesh){index = 0; poly_mesh = NULL; return NULL;}; + +protected: +	typedef std::map<LLJoint*, LLVector3> joint_vec_map_t; +	joint_vec_map_t mJointScales; +	joint_vec_map_t mJointOffsets; +	LLVector4a	mDefaultVec; +	// Backlink only; don't make this an LLPointer. +	LLAvatarAppearance *mAvatar; +}; + +#endif // LL_LLPOLYSKELETALDISTORTION_H + diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 21b1512e58..7942e815ae 100755 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -443,8 +443,6 @@ set(viewer_SOURCE_FILES      llplacesinventorybridge.cpp      llplacesinventorypanel.cpp      llpopupview.cpp -    llpolymesh.cpp -    llpolymorph.cpp      llpostcard.cpp      llpreview.cpp      llpreviewanim.cpp @@ -1000,8 +998,6 @@ set(viewer_HEADER_FILES      llpipelinelistener.h      llplacesinventorybridge.h      llplacesinventorypanel.h -    llpolymesh.h -    llpolymorph.h      llpopupview.h      llpostcard.h      llpreview.h diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp index e1ef0d5399..7f4d33753d 100644 --- a/indra/newview/llagentcamera.cpp +++ b/indra/newview/llagentcamera.cpp @@ -1078,8 +1078,8 @@ void LLAgentCamera::updateLookAt(const S32 mouse_x, const S32 mouse_y)  	if (!isAgentAvatarValid()) return; -	LLQuaternion av_inv_rot = ~gAgentAvatarp->mRoot.getWorldRotation(); -	LLVector3 root_at = LLVector3::x_axis * gAgentAvatarp->mRoot.getWorldRotation(); +	LLQuaternion av_inv_rot = ~gAgentAvatarp->mRoot->getWorldRotation(); +	LLVector3 root_at = LLVector3::x_axis * gAgentAvatarp->mRoot->getWorldRotation();  	if 	((gViewerWindow->getMouseVelocityStat()->getCurrent() < 0.01f) &&  		 (root_at * last_at_axis > 0.95f)) @@ -1432,7 +1432,7 @@ void LLAgentCamera::updateCamera()  			LLVector3(0.08f, 0.f, 0.05f) * gAgentAvatarp->mHeadp->getWorldRotation() +   			LLVector3(0.1f, 0.f, 0.f) * gAgentAvatarp->mPelvisp->getWorldRotation();  		LLVector3 diff = mCameraPositionAgent - head_pos; -		diff = diff * ~gAgentAvatarp->mRoot.getWorldRotation(); +		diff = diff * ~gAgentAvatarp->mRoot->getWorldRotation();  		LLJoint* torso_joint = gAgentAvatarp->mTorsop;  		LLJoint* chest_joint = gAgentAvatarp->mChestp; @@ -1456,7 +1456,7 @@ void LLAgentCamera::updateCamera()  		gAgentAvatarp->mPelvisp->setPosition(gAgentAvatarp->mPelvisp->getPosition() + diff); -		gAgentAvatarp->mRoot.updateWorldMatrixChildren(); +		gAgentAvatarp->mRoot->updateWorldMatrixChildren();  		for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin();   			 iter != gAgentAvatarp->mAttachmentPoints.end(); ) @@ -1684,7 +1684,7 @@ LLVector3d LLAgentCamera::calcCameraPositionTargetGlobal(BOOL *hit_limit)  	F32			camera_land_height;  	LLVector3d	frame_center_global = !isAgentAvatarValid() ?   		gAgent.getPositionGlobal() : -		gAgent.getPosGlobalFromAgent(gAgentAvatarp->mRoot.getWorldPosition()); +		gAgent.getPosGlobalFromAgent(gAgentAvatarp->mRoot->getWorldPosition());  	BOOL		isConstrained = FALSE;  	LLVector3d	head_offset; diff --git a/indra/newview/llfloaterbvhpreview.cpp b/indra/newview/llfloaterbvhpreview.cpp index fa0ad20fdb..ce67c6c65d 100644 --- a/indra/newview/llfloaterbvhpreview.cpp +++ b/indra/newview/llfloaterbvhpreview.cpp @@ -1097,12 +1097,12 @@ BOOL	LLPreviewAnimation::render()  	gGL.flush(); -	LLVector3 target_pos = avatarp->mRoot.getWorldPosition(); +	LLVector3 target_pos = avatarp->mRoot->getWorldPosition();  	LLQuaternion camera_rot = LLQuaternion(mCameraPitch, LLVector3::y_axis) *   		LLQuaternion(mCameraYaw, LLVector3::z_axis); -	LLQuaternion av_rot = avatarp->mRoot.getWorldRotation() * camera_rot; +	LLQuaternion av_rot = avatarp->mRoot->getWorldRotation() * camera_rot;  	LLViewerCamera::getInstance()->setOriginAndLookAt(  		target_pos + ((LLVector3(mCameraDistance, 0.f, 0.f) + mCameraOffset) * av_rot),		// camera  		LLVector3::z_axis,																	// up diff --git a/indra/newview/llfloaterimagepreview.cpp b/indra/newview/llfloaterimagepreview.cpp index 6b2492d927..887cd2f4b0 100644 --- a/indra/newview/llfloaterimagepreview.cpp +++ b/indra/newview/llfloaterimagepreview.cpp @@ -593,7 +593,7 @@ S8 LLImagePreviewAvatar::getType() const  void LLImagePreviewAvatar::setPreviewTarget(const std::string& joint_name, const std::string& mesh_name, LLImageRaw* imagep, F32 distance, BOOL male)   {  -	mTargetJoint = mDummyAvatar->mRoot.findJoint(joint_name); +	mTargetJoint = mDummyAvatar->mRoot->findJoint(joint_name);  	// clear out existing test mesh  	if (mTargetMesh)  	{ @@ -612,9 +612,9 @@ void LLImagePreviewAvatar::setPreviewTarget(const std::string& joint_name, const  		mDummyAvatar->updateVisualParams();  		mDummyAvatar->updateGeometry(mDummyAvatar->mDrawable);  	} -	mDummyAvatar->mRoot.setVisible(FALSE, TRUE); +	mDummyAvatar->mRoot->setVisible(FALSE, TRUE); -	mTargetMesh = (LLViewerJointMesh*)mDummyAvatar->mRoot.findJoint(mesh_name); +	mTargetMesh = (LLViewerJointMesh*)mDummyAvatar->mRoot->findJoint(mesh_name);  	mTargetMesh->setTestTexture(mTextureName);  	mTargetMesh->setVisible(TRUE, FALSE);  	mCameraDistance = distance; @@ -631,7 +631,7 @@ void LLImagePreviewAvatar::clearPreviewTexture(const std::string& mesh_name)  {  	if (mDummyAvatar)  	{ -		LLViewerJointMesh *mesh = (LLViewerJointMesh*)mDummyAvatar->mRoot.findJoint(mesh_name); +		LLViewerJointMesh *mesh = (LLViewerJointMesh*)mDummyAvatar->mRoot->findJoint(mesh_name);  		// clear out existing test mesh  		if (mesh)  		{ diff --git a/indra/newview/llhudeffectlookat.cpp b/indra/newview/llhudeffectlookat.cpp index bc3b220dc0..9dde65ceb6 100644 --- a/indra/newview/llhudeffectlookat.cpp +++ b/indra/newview/llhudeffectlookat.cpp @@ -636,7 +636,7 @@ bool LLHUDEffectLookAt::calcTargetPosition()  			}  			else  			{ -				target_rot = target_av->mRoot.getWorldRotation(); +				target_rot = target_av->mRoot->getWorldRotation();  			}  		}  		else // target obj is not an avatar diff --git a/indra/newview/llpolymorph.h b/indra/newview/llpolymorph.h index 46e23b7792..28d7755d4d 100644 --- a/indra/newview/llpolymorph.h +++ b/indra/newview/llpolymorph.h @@ -35,7 +35,7 @@  class LLPolyMeshSharedData;  class LLVOAvatar;  class LLVector2; -class LLViewerJointCollisionVolume; +class LLAvatarJointCollisionVolume;  class LLWearable;  //----------------------------------------------------------------------------- @@ -104,10 +104,10 @@ struct LLPolyVolumeMorphInfo  struct LLPolyVolumeMorph  { -	LLPolyVolumeMorph(LLViewerJointCollisionVolume* volume, LLVector3 scale, LLVector3 pos) +	LLPolyVolumeMorph(LLAvatarJointCollisionVolume* volume, LLVector3 scale, LLVector3 pos)  		: mVolume(volume), mScale(scale), mPos(pos) {}; -	LLViewerJointCollisionVolume*	mVolume; +	LLAvatarJointCollisionVolume*	mVolume;  	LLVector3						mScale;  	LLVector3						mPos;  }; diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index c804898cc3..fadaaf4541 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -4028,7 +4028,7 @@ void renderAgentTarget(LLVOAvatar* avatar)  	{  		renderCrossHairs(avatar->getPositionAgent(), 0.2f, LLColor4(1, 0, 0, 0.8f));  		renderCrossHairs(avatar->mDrawable->getPositionAgent(), 0.2f, LLColor4(1, 0, 0, 0.8f)); -		renderCrossHairs(avatar->mRoot.getWorldPosition(), 0.2f, LLColor4(1, 1, 1, 0.8f)); +		renderCrossHairs(avatar->mRoot->getWorldPosition(), 0.2f, LLColor4(1, 1, 1, 0.8f));  		renderCrossHairs(avatar->mPelvisp->getWorldPosition(), 0.2f, LLColor4(0, 0, 1, 0.8f));  	}  } diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 6782e3ef8a..ab06b1f5aa 100755 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -1247,6 +1247,9 @@ bool idle_startup()  		LLPostProcess::initClass();  		display_startup(); +		LLAvatarAppearance::initClass(); +		display_startup(); +  		LLViewerObject::initVOClasses();  		display_startup(); diff --git a/indra/newview/llviewerjoint.cpp b/indra/newview/llviewerjoint.cpp index a907f102f8..bb45cf89fc 100644 --- a/indra/newview/llviewerjoint.cpp +++ b/indra/newview/llviewerjoint.cpp @@ -53,7 +53,7 @@ BOOL					LLViewerJoint::sDisableLOD = FALSE;  // Class Constructor  //-----------------------------------------------------------------------------  LLViewerJoint::LLViewerJoint() -	:       LLJoint() +	:       LLAvatarJoint()  {  	init();  } @@ -64,7 +64,7 @@ LLViewerJoint::LLViewerJoint()  // Class Constructor  //-----------------------------------------------------------------------------  LLViewerJoint::LLViewerJoint(const std::string &name, LLJoint *parent) -	:	LLJoint(name, parent) +	:	LLAvatarJoint(name, parent)  {  	init();  } @@ -91,31 +91,6 @@ LLViewerJoint::~LLViewerJoint()  //-------------------------------------------------------------------- -// setValid() -//-------------------------------------------------------------------- -void LLViewerJoint::setValid( BOOL valid, BOOL recursive ) -{ -	//---------------------------------------------------------------- -	// set visibility for this joint -	//---------------------------------------------------------------- -	mValid = valid; -	 -	//---------------------------------------------------------------- -	// set visibility for children -	//---------------------------------------------------------------- -	if (recursive) -	{ -		for (child_list_t::iterator iter = mChildren.begin(); -			 iter != mChildren.end(); ++iter) -		{ -			LLViewerJoint* joint = (LLViewerJoint*)(*iter); -			joint->setValid(valid, TRUE); -		} -	} - -} - -//--------------------------------------------------------------------  // renderSkeleton()  // DEBUG (UNUSED)  //-------------------------------------------------------------------- @@ -522,98 +497,6 @@ void LLViewerJoint::setMeshesToChildren()  		addChild((LLViewerJointMesh *) *iter);  	}  } -//----------------------------------------------------------------------------- -// LLViewerJointCollisionVolume() -//----------------------------------------------------------------------------- - -LLViewerJointCollisionVolume::LLViewerJointCollisionVolume() -{ -	mUpdateXform = FALSE; -} -LLViewerJointCollisionVolume::LLViewerJointCollisionVolume(const std::string &name, LLJoint *parent) : LLViewerJoint(name, parent) -{ -	 -} - -void LLViewerJointCollisionVolume::renderCollision() -{ -	updateWorldMatrix(); -	 -	gGL.pushMatrix(); -	gGL.multMatrix( &mXform.getWorldMatrix().mMatrix[0][0] ); - -	gGL.diffuseColor3f( 0.f, 0.f, 1.f ); -	 -	gGL.begin(LLRender::LINES); -	 -	LLVector3 v[] =  -	{ -		LLVector3(1,0,0), -		LLVector3(-1,0,0), -		LLVector3(0,1,0), -		LLVector3(0,-1,0), - -		LLVector3(0,0,-1), -		LLVector3(0,0,1), -	}; - -	//sides -	gGL.vertex3fv(v[0].mV);  -	gGL.vertex3fv(v[2].mV); - -	gGL.vertex3fv(v[0].mV);  -	gGL.vertex3fv(v[3].mV); - -	gGL.vertex3fv(v[1].mV);  -	gGL.vertex3fv(v[2].mV); - -	gGL.vertex3fv(v[1].mV);  -	gGL.vertex3fv(v[3].mV); - - -	//top -	gGL.vertex3fv(v[0].mV);  -	gGL.vertex3fv(v[4].mV); - -	gGL.vertex3fv(v[1].mV);  -	gGL.vertex3fv(v[4].mV); - -	gGL.vertex3fv(v[2].mV);  -	gGL.vertex3fv(v[4].mV); - -	gGL.vertex3fv(v[3].mV);  -	gGL.vertex3fv(v[4].mV); - - -	//bottom -	gGL.vertex3fv(v[0].mV);  -	gGL.vertex3fv(v[5].mV); - -	gGL.vertex3fv(v[1].mV);  -	gGL.vertex3fv(v[5].mV); - -	gGL.vertex3fv(v[2].mV);  -	gGL.vertex3fv(v[5].mV); - -	gGL.vertex3fv(v[3].mV);  -	gGL.vertex3fv(v[5].mV); - -	gGL.end(); - -	gGL.popMatrix(); -} - -LLVector3 LLViewerJointCollisionVolume::getVolumePos(LLVector3 &offset) -{ -	mUpdateXform = TRUE; -	 -	LLVector3 result = offset; -	result.scaleVec(getScale()); -	result.rotVec(getWorldRotation()); -	result += getWorldPosition(); - -	return result; -}  // End diff --git a/indra/newview/llviewerjoint.h b/indra/newview/llviewerjoint.h index 531c0f765c..37c80dafeb 100644 --- a/indra/newview/llviewerjoint.h +++ b/indra/newview/llviewerjoint.h @@ -30,7 +30,7 @@  //-----------------------------------------------------------------------------  // Header Files  //----------------------------------------------------------------------------- -#include "lljoint.h" +#include "llavatarjoint.h"  #include "lljointpickname.h"  class LLFace; @@ -40,7 +40,7 @@ class LLViewerJointMesh;  // class LLViewerJoint  //-----------------------------------------------------------------------------  class LLViewerJoint : -	public LLJoint +	public LLAvatarJoint  {  public:  	LLViewerJoint(); @@ -50,9 +50,6 @@ public:  	// Gets the validity of this joint  	BOOL getValid() { return mValid; } -	// Sets the validity of this joint -	virtual void setValid( BOOL valid, BOOL recursive=FALSE ); -  	// Primarily for debugging and character setup  	// Derived classes may add text/graphic output.  	// Draw skeleton graphic for debugging and character setup @@ -134,19 +131,6 @@ protected:  	S32			mMeshID;  }; -class LLViewerJointCollisionVolume : public LLViewerJoint -{ -public: -	LLViewerJointCollisionVolume(); -	LLViewerJointCollisionVolume(const std::string &name, LLJoint *parent = NULL); -	virtual ~LLViewerJointCollisionVolume() {}; - -	virtual BOOL inheritScale() { return TRUE; } - -	void renderCollision(); -	LLVector3 getVolumePos(LLVector3 &offset); -}; -  #endif // LL_LLVIEWERJOINT_H diff --git a/indra/newview/llviewerjointmesh.cpp b/indra/newview/llviewerjointmesh.cpp index 3532fac1bc..8d479ab0bf 100755 --- a/indra/newview/llviewerjointmesh.cpp +++ b/indra/newview/llviewerjointmesh.cpp @@ -67,101 +67,20 @@ static const U32 sRenderMask = LLVertexBuffer::MAP_VERTEX |  							   LLVertexBuffer::MAP_NORMAL |  							   LLVertexBuffer::MAP_TEXCOORD0; - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -// LLViewerJointMesh::LLSkinJoint -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- - -//----------------------------------------------------------------------------- -// LLSkinJoint -//----------------------------------------------------------------------------- -LLSkinJoint::LLSkinJoint() -{ -	mJoint       = NULL; -} - -//----------------------------------------------------------------------------- -// ~LLSkinJoint -//----------------------------------------------------------------------------- -LLSkinJoint::~LLSkinJoint() -{ -	mJoint = NULL; -} - - -//----------------------------------------------------------------------------- -// LLSkinJoint::setupSkinJoint() -//----------------------------------------------------------------------------- -BOOL LLSkinJoint::setupSkinJoint( LLViewerJoint *joint) -{ -	// find the named joint -	mJoint = joint; -	if ( !mJoint ) -	{ -		llinfos << "Can't find joint" << llendl; -	} - -	// compute the inverse root skin matrix -	mRootToJointSkinOffset.clearVec(); - -	LLVector3 rootSkinOffset; -	while (joint) -	{ -		rootSkinOffset += joint->getSkinOffset(); -		joint = (LLViewerJoint*)joint->getParent(); -	} - -	mRootToJointSkinOffset = -rootSkinOffset; -	mRootToParentJointSkinOffset = mRootToJointSkinOffset; -	mRootToParentJointSkinOffset += mJoint->getSkinOffset(); - -	return TRUE; -} - -  //-----------------------------------------------------------------------------  //-----------------------------------------------------------------------------  // LLViewerJointMesh  //-----------------------------------------------------------------------------  //----------------------------------------------------------------------------- -BOOL LLViewerJointMesh::sPipelineRender = FALSE; -EAvatarRenderPass LLViewerJointMesh::sRenderPass = AVATAR_RENDER_PASS_SINGLE; -U32 LLViewerJointMesh::sClothingMaskImageName = 0; -LLColor4 LLViewerJointMesh::sClothingInnerColor;  //-----------------------------------------------------------------------------  // LLViewerJointMesh()  //-----------------------------------------------------------------------------  LLViewerJointMesh::LLViewerJointMesh()  	: -	mTexture( NULL ), -	mLayerSet( NULL ), -	mTestImageName( 0 ), -	mFaceIndexCount(0), -	mIsTransparent(FALSE) +	LLAvatarJointMesh()  { - -	mColor[0] = 1.0f; -	mColor[1] = 1.0f; -	mColor[2] = 1.0f; -	mColor[3] = 1.0f; -	mShiny = 0.0f; -	mCullBackFaces = TRUE; - -	mMesh = NULL; - -	mNumSkinJoints = 0; -	mSkinJoints = NULL; - -	mFace = NULL; - -	mMeshID = 0; -	mUpdateXform = FALSE; - -	mValid = FALSE;  } @@ -171,199 +90,6 @@ LLViewerJointMesh::LLViewerJointMesh()  //-----------------------------------------------------------------------------  LLViewerJointMesh::~LLViewerJointMesh()  { -	mMesh = NULL; -	mTexture = NULL; -	freeSkinData(); -} - - -//----------------------------------------------------------------------------- -// LLViewerJointMesh::allocateSkinData() -//----------------------------------------------------------------------------- -BOOL LLViewerJointMesh::allocateSkinData( U32 numSkinJoints ) -{ -	mSkinJoints = new LLSkinJoint[ numSkinJoints ]; -	mNumSkinJoints = numSkinJoints; -	return TRUE; -} - -//----------------------------------------------------------------------------- -// LLViewerJointMesh::freeSkinData() -//----------------------------------------------------------------------------- -void LLViewerJointMesh::freeSkinData() -{ -	mNumSkinJoints = 0; -	delete [] mSkinJoints; -	mSkinJoints = NULL; -} - -//-------------------------------------------------------------------- -// LLViewerJointMesh::getColor() -//-------------------------------------------------------------------- -void LLViewerJointMesh::getColor( F32 *red, F32 *green, F32 *blue, F32 *alpha ) -{ -	*red   = mColor[0]; -	*green = mColor[1]; -	*blue  = mColor[2]; -	*alpha = mColor[3]; -} - -//-------------------------------------------------------------------- -// LLViewerJointMesh::setColor() -//-------------------------------------------------------------------- -void LLViewerJointMesh::setColor( F32 red, F32 green, F32 blue, F32 alpha ) -{ -	mColor[0] = red; -	mColor[1] = green; -	mColor[2] = blue; -	mColor[3] = alpha; -} - - -//-------------------------------------------------------------------- -// LLViewerJointMesh::getTexture() -//-------------------------------------------------------------------- -//LLViewerTexture *LLViewerJointMesh::getTexture() -//{ -//	return mTexture; -//} - -//-------------------------------------------------------------------- -// LLViewerJointMesh::setTexture() -//-------------------------------------------------------------------- -void LLViewerJointMesh::setTexture( LLViewerTexture *texture ) -{ -	mTexture = texture; - -	// texture and dynamic_texture are mutually exclusive -	if( texture ) -	{ -		mLayerSet = NULL; -		//texture->bindTexture(0); -		//texture->setClamp(TRUE, TRUE); -	} -} - -//-------------------------------------------------------------------- -// LLViewerJointMesh::setLayerSet() -// Sets the shape texture (takes precedence over normal texture) -//-------------------------------------------------------------------- -void LLViewerJointMesh::setLayerSet( LLViewerTexLayerSet* layer_set ) -{ -	mLayerSet = layer_set; -	 -	// texture and dynamic_texture are mutually exclusive -	if( layer_set ) -	{ -		mTexture = NULL; -	} -} - - - -//-------------------------------------------------------------------- -// LLViewerJointMesh::getMesh() -//-------------------------------------------------------------------- -LLPolyMesh *LLViewerJointMesh::getMesh() -{ -	return mMesh; -} - -//----------------------------------------------------------------------------- -// LLViewerJointMesh::setMesh() -//----------------------------------------------------------------------------- -void LLViewerJointMesh::setMesh( LLPolyMesh *mesh ) -{ -	// set the mesh pointer -	mMesh = mesh; - -	// release any existing skin joints -	freeSkinData(); - -	if ( mMesh == NULL ) -	{ -		return; -	} - -	// acquire the transform from the mesh object -	setPosition( mMesh->getPosition() ); -	setRotation( mMesh->getRotation() ); -	setScale( mMesh->getScale() ); - -	// create skin joints if necessary -	if ( mMesh->hasWeights() && !mMesh->isLOD()) -	{ -		U32 numJointNames = mMesh->getNumJointNames(); -		 -		allocateSkinData( numJointNames ); -		std::string *jointNames = mMesh->getJointNames(); - -		U32 jn; -		for (jn = 0; jn < numJointNames; jn++) -		{ -			//llinfos << "Setting up joint " << jointNames[jn] << llendl; -			LLViewerJoint* joint = (LLViewerJoint*)(getRoot()->findJoint(jointNames[jn]) ); -			mSkinJoints[jn].setupSkinJoint( joint ); -		} -	} - -	// setup joint array -	if (!mMesh->isLOD()) -	{ -		setupJoint((LLViewerJoint*)getRoot()); -	} - -//	llinfos << "joint render entries: " << mMesh->mJointRenderData.count() << llendl; -} - -//----------------------------------------------------------------------------- -// setupJoint() -//----------------------------------------------------------------------------- -void LLViewerJointMesh::setupJoint(LLViewerJoint* current_joint) -{ -//	llinfos << "Mesh: " << getName() << llendl; - -//	S32 joint_count = 0; -	U32 sj; -	for (sj=0; sj<mNumSkinJoints; sj++) -	{ -		LLSkinJoint &js = mSkinJoints[sj]; - -		if (js.mJoint != current_joint) -		{ -			continue; -		} - -		// we've found a skinjoint for this joint.. - -		// is the last joint in the array our parent? -		if(mMesh->mJointRenderData.count() && mMesh->mJointRenderData[mMesh->mJointRenderData.count() - 1]->mWorldMatrix == ¤t_joint->getParent()->getWorldMatrix()) -		{ -			// ...then just add ourselves -			LLViewerJoint* jointp = js.mJoint; -			mMesh->mJointRenderData.put(new LLJointRenderData(&jointp->getWorldMatrix(), &js)); -//			llinfos << "joint " << joint_count << js.mJoint->getName() << llendl; -//			joint_count++; -		} -		// otherwise add our parent and ourselves -		else -		{ -			mMesh->mJointRenderData.put(new LLJointRenderData(¤t_joint->getParent()->getWorldMatrix(), NULL)); -//			llinfos << "joint " << joint_count << current_joint->getParent()->getName() << llendl; -//			joint_count++; -			mMesh->mJointRenderData.put(new LLJointRenderData(¤t_joint->getWorldMatrix(), &js)); -//			llinfos << "joint " << joint_count << current_joint->getName() << llendl; -//			joint_count++; -		} -	} - -	// depth-first traversal -	for (LLJoint::child_list_t::iterator iter = current_joint->mChildren.begin(); -		 iter != current_joint->mChildren.end(); ++iter) -	{ -		LLViewerJoint* child_joint = (LLViewerJoint*)(*iter); -		setupJoint(child_joint); -	}  }  const S32 NUM_AXES = 3; @@ -544,6 +270,7 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)  	llassert( !(mTexture.notNull() && mLayerSet) );  // mutually exclusive  	LLTexUnit::eTextureAddressMode old_mode = LLTexUnit::TAM_WRAP; +	LLViewerTexLayerSet *layerset = dynamic_cast<LLViewerTexLayerSet*>(mLayerSet);  	if (mTestImageName)  	{  		gGL.getTexUnit(diffuse_channel)->bindManual(LLTexUnit::TT_TEXTURE, mTestImageName); @@ -558,11 +285,11 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)  			gGL.getTexUnit(diffuse_channel)->setTextureColorBlend(LLTexUnit::TBO_LERP_TEX_ALPHA, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_PREV_COLOR);  		}  	} -	else if( !is_dummy && mLayerSet ) +	else if( !is_dummy && layerset )  	{ -		if(	mLayerSet->hasComposite() ) +		if(	layerset->hasComposite() )  		{ -			gGL.getTexUnit(diffuse_channel)->bind(mLayerSet->getViewerComposite()); +			gGL.getTexUnit(diffuse_channel)->bind(layerset->getViewerComposite());  		}  		else  		{ diff --git a/indra/newview/llviewerjointmesh.h b/indra/newview/llviewerjointmesh.h index ff6bed4f0f..039175830f 100755 --- a/indra/newview/llviewerjointmesh.h +++ b/indra/newview/llviewerjointmesh.h @@ -29,6 +29,7 @@  #include "llviewerjoint.h"  #include "llviewertexture.h" +#include "llavatarjointmesh.h"  #include "llpolymesh.h"  #include "v4color.h" @@ -37,56 +38,12 @@ class LLFace;  class LLCharacter;  class LLViewerTexLayerSet; -typedef enum e_avatar_render_pass -{ -	AVATAR_RENDER_PASS_SINGLE, -	AVATAR_RENDER_PASS_CLOTHING_INNER, -	AVATAR_RENDER_PASS_CLOTHING_OUTER -} EAvatarRenderPass; - -class LLSkinJoint -{ -public: -	LLSkinJoint(); -	~LLSkinJoint(); -	BOOL setupSkinJoint( LLViewerJoint *joint); - -	LLViewerJoint	*mJoint; -	LLVector3		mRootToJointSkinOffset; -	LLVector3		mRootToParentJointSkinOffset; -}; -  //-----------------------------------------------------------------------------  // class LLViewerJointMesh  //----------------------------------------------------------------------------- -class LLViewerJointMesh : public LLViewerJoint +class LLViewerJointMesh : public LLAvatarJointMesh  {  	friend class LLVOAvatar; -protected: -	LLColor4					mColor;			// color value -// 	LLColor4					mSpecular;		// specular color (always white for now) -	F32							mShiny;			// shiny value -	LLPointer<LLViewerTexture>	mTexture;		// ptr to a global texture -	LLViewerTexLayerSet*		mLayerSet;		// ptr to a layer set owned by the avatar -	U32 						mTestImageName;		// handle to a temporary texture for previewing uploads -	LLPolyMesh*					mMesh;			// ptr to a global polymesh -	BOOL						mCullBackFaces;	// true by default -	LLFace*						mFace;			// ptr to a face w/ AGP copy of mesh - -	U32							mFaceIndexCount; -	BOOL						mIsTransparent; - -	U32							mNumSkinJoints; -	LLSkinJoint*				mSkinJoints; -	S32							mMeshID; - -public: -	static BOOL					sPipelineRender; -	//RN: this is here for testing purposes -	static U32					sClothingMaskImageName; -	static EAvatarRenderPass	sRenderPass; -	static LLColor4				sClothingInnerColor; -  public:  	// Constructor  	LLViewerJointMesh(); @@ -94,41 +51,9 @@ public:  	// Destructor  	virtual ~LLViewerJointMesh(); -	// Gets the shape color -	void getColor( F32 *red, F32 *green, F32 *blue, F32 *alpha ); - -	// Sets the shape color -	void setColor( F32 red, F32 green, F32 blue, F32 alpha ); - -	// Sets the shininess -	void setSpecular( const LLColor4& color, F32 shiny ) { /*mSpecular = color;*/ mShiny = shiny; }; - -	// Sets the shape texture -	void setTexture( LLViewerTexture *texture ); - -	void setTestTexture( U32 name ) { mTestImageName = name; } - -	// Sets layer set responsible for a dynamic shape texture (takes precedence over normal texture) -	void setLayerSet( LLViewerTexLayerSet* layer_set ); - -	// Gets the poly mesh -	LLPolyMesh *getMesh(); - -	// Sets the poly mesh -	void setMesh( LLPolyMesh *mesh ); - -	// Sets up joint matrix data for rendering -	void setupJoint(LLViewerJoint* current_joint); -  	// Render time method to upload batches of joint matrices  	void uploadJointMatrices(); -	// Sets ID for picking -	void setMeshID( S32 id ) {mMeshID = id;} - -	// Gets ID for picking -	S32 getMeshID() { return mMeshID; }	 -  	// overloaded from base class  	/*virtual*/ void drawBone();  	/*virtual*/ BOOL isTransparent(); @@ -148,13 +73,6 @@ private:  	//copy mesh into given face's vertex buffer, applying current animation pose  	static void updateGeometry(LLFace* face, LLPolyMesh* mesh); - -private: -	// Allocate skin data -	BOOL allocateSkinData( U32 numSkinJoints ); - -	// Free skin data -	void freeSkinData();  };  #endif // LL_LLVIEWERJOINTMESH_H diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index d5ca01931f..8fc5a3f277 100755 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -382,7 +382,7 @@ public:  			if (isAgentAvatarValid())  			{ -				tvector = gAgent.getPosGlobalFromAgent(gAgentAvatarp->mRoot.getWorldPosition()); +				tvector = gAgent.getPosGlobalFromAgent(gAgentAvatarp->mRoot->getWorldPosition());  				agent_root_center_text = llformat("AgentRootCenter %f %f %f",  												  (F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ]));  			} diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index f6cac6d2d6..f0f469e959 100755 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -139,7 +139,6 @@ const LLUUID ANIM_AGENT_PHYSICS_MOTION = LLUUID("7360e029-3cb8-ebc4-863e-212df44  //-----------------------------------------------------------------------------  // Constants  //----------------------------------------------------------------------------- -const std::string AVATAR_DEFAULT_CHAR = "avatar";  const S32 MIN_PIXEL_AREA_FOR_COMPOSITE = 1024;  const F32 SHADOW_OFFSET_AMT = 0.03f; @@ -220,58 +219,6 @@ struct LLTextureMaskData   **   **/ -//------------------------------------------------------------------------ -// LLVOBoneInfo -// Trans/Scale/Rot etc. info about each avatar bone.  Used by LLVOAvatarSkeleton. -//------------------------------------------------------------------------ -class LLVOAvatarBoneInfo -{ -	friend class LLVOAvatar; -	friend class LLVOAvatarSkeletonInfo; -public: -	LLVOAvatarBoneInfo() : mIsJoint(FALSE) {} -	~LLVOAvatarBoneInfo() -	{ -		std::for_each(mChildList.begin(), mChildList.end(), DeletePointer()); -	} -	BOOL parseXml(LLXmlTreeNode* node); -	 -private: -	std::string mName; -	BOOL mIsJoint; -	LLVector3 mPos; -	LLVector3 mRot; -	LLVector3 mScale; -	LLVector3 mPivot; -	typedef std::vector<LLVOAvatarBoneInfo*> child_list_t; -	child_list_t mChildList; -}; - -//------------------------------------------------------------------------ -// LLVOAvatarSkeletonInfo -// Overall avatar skeleton -//------------------------------------------------------------------------ -class LLVOAvatarSkeletonInfo -{ -	friend class LLVOAvatar; -public: -	LLVOAvatarSkeletonInfo() : -		mNumBones(0), mNumCollisionVolumes(0) {} -	~LLVOAvatarSkeletonInfo() -	{ -		std::for_each(mBoneInfoList.begin(), mBoneInfoList.end(), DeletePointer()); -	} -	BOOL parseXml(LLXmlTreeNode* node); -	S32 getNumBones() const { return mNumBones; } -	S32 getNumCollisionVolumes() const { return mNumCollisionVolumes; } -	 -private: -	S32 mNumBones; -	S32 mNumCollisionVolumes; -	typedef std::vector<LLVOAvatarBoneInfo*> bone_info_list_t; -	bone_info_list_t mBoneInfoList; -}; -  //-----------------------------------------------------------------------------  // class LLBodyNoiseMotion  //----------------------------------------------------------------------------- @@ -593,10 +540,6 @@ private:  //-----------------------------------------------------------------------------  // Static Data  //----------------------------------------------------------------------------- -LLXmlTree LLVOAvatar::sXMLTree; -LLXmlTree LLVOAvatar::sSkeletonXMLTree; -LLVOAvatarSkeletonInfo* LLVOAvatar::sAvatarSkeletonInfo = NULL; -LLVOAvatar::LLVOAvatarXmlInfo* LLVOAvatar::sAvatarXmlInfo = NULL;  LLAvatarAppearanceDictionary *LLVOAvatar::sAvatarDictionary = NULL;  S32 LLVOAvatar::sFreezeCounter = 0;  U32 LLVOAvatar::sMaxVisible = 12; @@ -650,9 +593,7 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,  	mAttachmentGeometryBytes(0),  	mAttachmentSurfaceArea(0.f),  	mTurning(FALSE), -	mPelvisToFoot(0.f),  	mLastSkeletonSerialNum( 0 ), -	mHeadOffset(),  	mIsSitting(FALSE),  	mTimeVisible(),  	mTyping(FALSE), @@ -707,13 +648,6 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,  	mMeshTexturesDirty = FALSE;  	mHeadp = NULL; -	mIsBuilt = FALSE; - -	mNumJoints = 0; -	mSkeleton = NULL; - -	mNumCollisionVolumes = 0; -	mCollisionVolumes = NULL;  	// set up animation variables  	mSpeed = 0.f; @@ -802,35 +736,9 @@ LLVOAvatar::~LLVOAvatar()  	lldebugs << "LLVOAvatar Destructor (0x" << this << ") id:" << mID << llendl; -	mRoot.removeAllChildren(); -	mJointMap.clear(); - -	deleteAndClearArray(mSkeleton); -	deleteAndClearArray(mCollisionVolumes); - -	mNumJoints = 0; -  	std::for_each(mAttachmentPoints.begin(), mAttachmentPoints.end(), DeletePairedPointer());  	mAttachmentPoints.clear(); -	deleteAndClear(mTexSkinColor); -	deleteAndClear(mTexHairColor); -	deleteAndClear(mTexEyeColor); - -	std::for_each(mMeshes.begin(), mMeshes.end(), DeletePairedPointer()); -	mMeshes.clear(); - -	for (std::vector<LLViewerJoint*>::iterator jointIter = mMeshLOD.begin(); -		 jointIter != mMeshLOD.end();  -		 ++jointIter) -	{ -		LLViewerJoint* joint = (LLViewerJoint *) *jointIter; -		std::for_each(joint->mMeshParts.begin(), joint->mMeshParts.end(), DeletePointer()); -		joint->mMeshParts.clear(); -	} -	std::for_each(mMeshLOD.begin(), mMeshLOD.end(), DeletePointer()); -	mMeshLOD.clear(); -	  	mDead = TRUE;  	mAnimationSources.clear(); @@ -1127,109 +1035,6 @@ void LLVOAvatar::deleteCachedImages(bool clearAll)  //------------------------------------------------------------------------  void LLVOAvatar::initClass()  {  -	std::string xmlFile; - -	xmlFile = gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,AVATAR_DEFAULT_CHAR) + "_lad.xml"; -	BOOL success = sXMLTree.parseFile( xmlFile, FALSE ); -	if (!success) -	{ -		llerrs << "Problem reading avatar configuration file:" << xmlFile << llendl; -	} - -	// now sanity check xml file -	LLXmlTreeNode* root = sXMLTree.getRoot(); -	if (!root)  -	{ -		llerrs << "No root node found in avatar configuration file: " << xmlFile << llendl; -		return; -	} - -	//------------------------------------------------------------------------- -	// <linden_avatar version="1.0"> (root) -	//------------------------------------------------------------------------- -	if( !root->hasName( "linden_avatar" ) ) -	{ -		llerrs << "Invalid avatar file header: " << xmlFile << llendl; -	} -	 -	std::string version; -	static LLStdStringHandle version_string = LLXmlTree::addAttributeString("version"); -	if( !root->getFastAttributeString( version_string, version ) || (version != "1.0") ) -	{ -		llerrs << "Invalid avatar file version: " << version << " in file: " << xmlFile << llendl; -	} - -	S32 wearable_def_version = 1; -	static LLStdStringHandle wearable_definition_version_string = LLXmlTree::addAttributeString("wearable_definition_version"); -	root->getFastAttributeS32( wearable_definition_version_string, wearable_def_version ); -	LLWearable::setCurrentDefinitionVersion( wearable_def_version ); - -	std::string mesh_file_name; - -	LLXmlTreeNode* skeleton_node = root->getChildByName( "skeleton" ); -	if (!skeleton_node) -	{ -		llerrs << "No skeleton in avatar configuration file: " << xmlFile << llendl; -		return; -	} -	 -	std::string skeleton_file_name; -	static LLStdStringHandle file_name_string = LLXmlTree::addAttributeString("file_name"); -	if (!skeleton_node->getFastAttributeString(file_name_string, skeleton_file_name)) -	{ -		llerrs << "No file name in skeleton node in avatar config file: " << xmlFile << llendl; -	} -	 -	std::string skeleton_path; -	skeleton_path = gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,skeleton_file_name); -	if (!parseSkeletonFile(skeleton_path)) -	{ -		llerrs << "Error parsing skeleton file: " << skeleton_path << llendl; -	} - -	// Process XML data - -	// avatar_skeleton.xml -	if (sAvatarSkeletonInfo) -	{ //this can happen if a login attempt failed -		delete sAvatarSkeletonInfo; -	} -	sAvatarSkeletonInfo = new LLVOAvatarSkeletonInfo; -	if (!sAvatarSkeletonInfo->parseXml(sSkeletonXMLTree.getRoot())) -	{ -		llerrs << "Error parsing skeleton XML file: " << skeleton_path << llendl; -	} -	// parse avatar_lad.xml -	if (sAvatarXmlInfo) -	{ //this can happen if a login attempt failed -		deleteAndClear(sAvatarXmlInfo); -	} -	sAvatarXmlInfo = new LLVOAvatarXmlInfo; -	if (!sAvatarXmlInfo->parseXmlSkeletonNode(root)) -	{ -		llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl; -	} -	if (!sAvatarXmlInfo->parseXmlMeshNodes(root)) -	{ -		llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl; -	} -	if (!sAvatarXmlInfo->parseXmlColorNodes(root)) -	{ -		llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl; -	} -	if (!sAvatarXmlInfo->parseXmlLayerNodes(root)) -	{ -		llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl; -	} -	if (!sAvatarXmlInfo->parseXmlDriverNodes(root)) -	{ -		llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl; -	} -	if (!sAvatarXmlInfo->parseXmlMorphNodes(root)) -	{ -		llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl; -	} -  	gAnimLibrary.animStateSetString(ANIM_AGENT_BODY_NOISE,"body_noise");  	gAnimLibrary.animStateSetString(ANIM_AGENT_BREATHE_ROT,"breathe_rot");  	gAnimLibrary.animStateSetString(ANIM_AGENT_PHYSICS_MOTION,"physics_motion"); @@ -1256,7 +1061,12 @@ void LLVOAvatar::initInstance(void)  	//-------------------------------------------------------------------------  	// initialize joint, mesh and shape members  	//------------------------------------------------------------------------- -	mRoot.setName( "mRoot" ); +	if (mRoot) +	{ +		delete mRoot; +	} +	mRoot = new LLViewerJoint(); +	mRoot->setName( "mRoot" );  	for (LLAvatarAppearanceDictionary::Meshes::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getMeshes().begin();  		 iter != LLAvatarAppearanceDictionary::getInstance()->getMeshes().end(); @@ -1314,7 +1124,7 @@ void LLVOAvatar::initInstance(void)  		// Skip it if there's no associated baked texture.  		if (baked_texture_index == BAKED_NUM_INDICES) continue; -		for (std::vector<LLViewerJointMesh* >::iterator iter = mMeshLOD[mesh_index]->mMeshParts.begin(); +		for (std::vector<LLAvatarJointMesh* >::iterator iter = mMeshLOD[mesh_index]->mMeshParts.begin();  			 iter != mMeshLOD[mesh_index]->mMeshParts.end();   			 ++iter)  		{ @@ -1707,160 +1517,6 @@ LLViewerObject* LLVOAvatar::lineSegmentIntersectRiggedAttachments(const LLVector  	return hit;  } -//----------------------------------------------------------------------------- -// parseSkeletonFile() -//----------------------------------------------------------------------------- -BOOL LLVOAvatar::parseSkeletonFile(const std::string& filename) -{ -	LLMemType mt(LLMemType::MTYPE_AVATAR); -	 -	//------------------------------------------------------------------------- -	// parse the file -	//------------------------------------------------------------------------- -	BOOL parsesuccess = sSkeletonXMLTree.parseFile( filename, FALSE ); - -	if (!parsesuccess) -	{ -		llerrs << "Can't parse skeleton file: " << filename << llendl; -		return FALSE; -	} - -	// now sanity check xml file -	LLXmlTreeNode* root = sSkeletonXMLTree.getRoot(); -	if (!root)  -	{ -		llerrs << "No root node found in avatar skeleton file: " << filename << llendl; -		return FALSE; -	} - -	if( !root->hasName( "linden_skeleton" ) ) -	{ -		llerrs << "Invalid avatar skeleton file header: " << filename << llendl; -		return FALSE; -	} - -	std::string version; -	static LLStdStringHandle version_string = LLXmlTree::addAttributeString("version"); -	if( !root->getFastAttributeString( version_string, version ) || (version != "1.0") ) -	{ -		llerrs << "Invalid avatar skeleton file version: " << version << " in file: " << filename << llendl; -		return FALSE; -	} - -	return TRUE; -} - -//----------------------------------------------------------------------------- -// setupBone() -//----------------------------------------------------------------------------- -BOOL LLVOAvatar::setupBone(const LLVOAvatarBoneInfo* info, LLViewerJoint* parent, S32 &volume_num, S32 &joint_num) -{ -	LLMemType mt(LLMemType::MTYPE_AVATAR); -	 -	LLViewerJoint* joint = NULL; - -	if (info->mIsJoint) -	{ -		joint = (LLViewerJoint*)getCharacterJoint(joint_num); -		if (!joint) -		{ -			llwarns << "Too many bones" << llendl; -			return FALSE; -		} -		joint->setName( info->mName ); -	} -	else // collision volume -	{ -		if (volume_num >= (S32)mNumCollisionVolumes) -		{ -			llwarns << "Too many bones" << llendl; -			return FALSE; -		} -		joint = (LLViewerJoint*)(&mCollisionVolumes[volume_num]); -		joint->setName( info->mName ); -	} - -	// add to parent -	if (parent) -	{ -		parent->addChild( joint ); -	} - -	joint->setPosition(info->mPos); -	joint->setRotation(mayaQ(info->mRot.mV[VX], info->mRot.mV[VY], -							 info->mRot.mV[VZ], LLQuaternion::XYZ)); -	joint->setScale(info->mScale); - -	joint->setDefaultFromCurrentXform(); -	 -	if (info->mIsJoint) -	{ -		joint->setSkinOffset( info->mPivot ); -		joint_num++; -	} -	else // collision volume -	{ -		volume_num++; -	} - -	// setup children -	LLVOAvatarBoneInfo::child_list_t::const_iterator iter; -	for (iter = info->mChildList.begin(); iter != info->mChildList.end(); ++iter) -	{ -		LLVOAvatarBoneInfo *child_info = *iter; -		if (!setupBone(child_info, joint, volume_num, joint_num)) -		{ -			return FALSE; -		} -	} - -	return TRUE; -} - -//----------------------------------------------------------------------------- -// buildSkeleton() -//----------------------------------------------------------------------------- -BOOL LLVOAvatar::buildSkeleton(const LLVOAvatarSkeletonInfo *info) -{ -	LLMemType mt(LLMemType::MTYPE_AVATAR); -	 -	//------------------------------------------------------------------------- -	// allocate joints -	//------------------------------------------------------------------------- -	if (!allocateCharacterJoints(info->mNumBones)) -	{ -		llerrs << "Can't allocate " << info->mNumBones << " joints" << llendl; -		return FALSE; -	} -	 -	//------------------------------------------------------------------------- -	// allocate volumes -	//------------------------------------------------------------------------- -	if (info->mNumCollisionVolumes) -	{ -		if (!allocateCollisionVolumes(info->mNumCollisionVolumes)) -		{ -			llerrs << "Can't allocate " << info->mNumCollisionVolumes << " collision volumes" << llendl; -			return FALSE; -		} -	} - -	S32 current_joint_num = 0; -	S32 current_volume_num = 0; -	LLVOAvatarSkeletonInfo::bone_info_list_t::const_iterator iter; -	for (iter = info->mBoneInfoList.begin(); iter != info->mBoneInfoList.end(); ++iter) -	{ -		LLVOAvatarBoneInfo *info = *iter; -		if (!setupBone(info, NULL, current_volume_num, current_joint_num)) -		{ -			llerrs << "Error parsing bone in skeleton file" << llendl; -			return FALSE; -		} -	} - -	return TRUE; -} -  LLVOAvatar* LLVOAvatar::asAvatar()  {  	return this; @@ -1892,27 +1548,13 @@ void LLVOAvatar::startDefaultMotions()  // LLVOAvatar::buildCharacter()  // Deferred initialization and rebuild of the avatar.  //----------------------------------------------------------------------------- +// virtual  void LLVOAvatar::buildCharacter()  { -	LLMemType mt(LLMemType::MTYPE_AVATAR); -	 -	//------------------------------------------------------------------------- -	// remove all references to our existing skeleton -	// so we can rebuild it -	//------------------------------------------------------------------------- -	flushAllMotions(); - -	//------------------------------------------------------------------------- -	// remove all of mRoot's children -	//------------------------------------------------------------------------- -	mRoot.removeAllChildren(); -	mJointMap.clear(); -	mIsBuilt = FALSE; -  	//-------------------------------------------------------------------------  	// clear mesh data  	//------------------------------------------------------------------------- -	for (std::vector<LLViewerJoint*>::iterator jointIter = mMeshLOD.begin(); +	for (std::vector<LLAvatarJoint*>::iterator jointIter = mMeshLOD.begin();  		 jointIter != mMeshLOD.end(); ++jointIter)  	{  		LLViewerJoint* joint = (LLViewerJoint*) *jointIter; @@ -1924,84 +1566,9 @@ void LLVOAvatar::buildCharacter()  		}  	} -	//------------------------------------------------------------------------- -	// (re)load our skeleton and meshes -	//------------------------------------------------------------------------- -	LLTimer timer; - -	BOOL status = loadAvatar(); -	stop_glerror(); - -// 	gPrintMessagesThisFrame = TRUE; -	lldebugs << "Avatar load took " << timer.getElapsedTimeF32() << " seconds." << llendl; - -	if (!status) -	{ -		if (isSelf()) -		{ -			llerrs << "Unable to load user's avatar" << llendl; -		} -		else -		{ -			llwarns << "Unable to load other's avatar" << llendl; -		} -		return; -	} - -	//------------------------------------------------------------------------- -	// initialize "well known" joint pointers -	//------------------------------------------------------------------------- -	mPelvisp		= (LLViewerJoint*)mRoot.findJoint("mPelvis"); -	mTorsop			= (LLViewerJoint*)mRoot.findJoint("mTorso"); -	mChestp			= (LLViewerJoint*)mRoot.findJoint("mChest"); -	mNeckp			= (LLViewerJoint*)mRoot.findJoint("mNeck"); -	mHeadp			= (LLViewerJoint*)mRoot.findJoint("mHead"); -	mSkullp			= (LLViewerJoint*)mRoot.findJoint("mSkull"); -	mHipLeftp		= (LLViewerJoint*)mRoot.findJoint("mHipLeft"); -	mHipRightp		= (LLViewerJoint*)mRoot.findJoint("mHipRight"); -	mKneeLeftp		= (LLViewerJoint*)mRoot.findJoint("mKneeLeft"); -	mKneeRightp		= (LLViewerJoint*)mRoot.findJoint("mKneeRight"); -	mAnkleLeftp		= (LLViewerJoint*)mRoot.findJoint("mAnkleLeft"); -	mAnkleRightp	= (LLViewerJoint*)mRoot.findJoint("mAnkleRight"); -	mFootLeftp		= (LLViewerJoint*)mRoot.findJoint("mFootLeft"); -	mFootRightp		= (LLViewerJoint*)mRoot.findJoint("mFootRight"); -	mWristLeftp		= (LLViewerJoint*)mRoot.findJoint("mWristLeft"); -	mWristRightp	= (LLViewerJoint*)mRoot.findJoint("mWristRight"); -	mEyeLeftp		= (LLViewerJoint*)mRoot.findJoint("mEyeLeft"); -	mEyeRightp		= (LLViewerJoint*)mRoot.findJoint("mEyeRight"); +	LLAvatarAppearance::buildCharacter();  	//------------------------------------------------------------------------- -	// Make sure "well known" pointers exist -	//------------------------------------------------------------------------- -	if (!(mPelvisp &&  -		  mTorsop && -		  mChestp && -		  mNeckp && -		  mHeadp && -		  mSkullp && -		  mHipLeftp && -		  mHipRightp && -		  mKneeLeftp && -		  mKneeRightp && -		  mAnkleLeftp && -		  mAnkleRightp && -		  mFootLeftp && -		  mFootRightp && -		  mWristLeftp && -		  mWristRightp && -		  mEyeLeftp && -		  mEyeRightp)) -	{ -		llerrs << "Failed to create avatar." << llendl; -		return; -	} - -	//------------------------------------------------------------------------- -	// initialize the pelvis -	//------------------------------------------------------------------------- -	mPelvisp->setPosition( LLVector3(0.0f, 0.0f, 0.0f) ); -	 -	//-------------------------------------------------------------------------  	// set head offset from pelvis  	//-------------------------------------------------------------------------  	updateHeadOffset(); @@ -2033,9 +1600,6 @@ void LLVOAvatar::buildCharacter()  	//-------------------------------------------------------------------------  	processAnimationStateChanges(); -	mIsBuilt = TRUE; -	stop_glerror(); -  	mMeshValid = TRUE;  } @@ -2055,7 +1619,7 @@ void LLVOAvatar::releaseMeshData()  	//llinfos << "Releasing" << llendl;  	// cleanup mesh data -	for (std::vector<LLViewerJoint*>::iterator iter = mMeshLOD.begin(); +	for (std::vector<LLAvatarJoint*>::iterator iter = mMeshLOD.begin();  		 iter != mMeshLOD.end();   		 ++iter)  	{ @@ -2149,7 +1713,11 @@ void LLVOAvatar::updateMeshData()  				last_v_num = num_vertices ;  				last_i_num = num_indices ; -				mMeshLOD[part_index++]->updateFaceSizes(num_vertices, num_indices, mAdjustedPixelArea); +				LLViewerJoint* part_mesh = getViewerJoint(part_index++); +				if (part_mesh) +				{ +					part_mesh->updateFaceSizes(num_vertices, num_indices, mAdjustedPixelArea); +				}  			}  			if(num_vertices < 1)//skip empty meshes  			{ @@ -2223,7 +1791,11 @@ void LLVOAvatar::updateMeshData()  					rigid = true;  				} -				mMeshLOD[k]->updateFaceData(facep, mAdjustedPixelArea, k == MESH_ID_HAIR, terse_update && !rigid); +				LLViewerJoint* mesh = getViewerJoint(k); +				if (mesh) +				{ +					mesh->updateFaceData(facep, mAdjustedPixelArea, k == MESH_ID_HAIR, terse_update && !rigid); +				}  			}  			stop_glerror(); @@ -2244,72 +1816,6 @@ void LLVOAvatar::updateMeshData()  //------------------------------------------------------------------------  //------------------------------------------------------------------------ -// The viewer can only suggest a good size for the agent, -// the simulator will keep it inside a reasonable range. -void LLVOAvatar::computeBodySize()  -{ -	LLVector3 pelvis_scale = mPelvisp->getScale(); - -	// some of the joints have not been cached -	LLVector3 skull = mSkullp->getPosition(); -	LLVector3 skull_scale = mSkullp->getScale(); - -	LLVector3 neck = mNeckp->getPosition(); -	LLVector3 neck_scale = mNeckp->getScale(); - -	LLVector3 chest = mChestp->getPosition(); -	LLVector3 chest_scale = mChestp->getScale(); - -	// the rest of the joints have been cached -	LLVector3 head = mHeadp->getPosition(); -	LLVector3 head_scale = mHeadp->getScale(); - -	LLVector3 torso = mTorsop->getPosition(); -	LLVector3 torso_scale = mTorsop->getScale(); - -	LLVector3 hip = mHipLeftp->getPosition(); -	LLVector3 hip_scale = mHipLeftp->getScale(); - -	LLVector3 knee = mKneeLeftp->getPosition(); -	LLVector3 knee_scale = mKneeLeftp->getScale(); - -	LLVector3 ankle = mAnkleLeftp->getPosition(); -	LLVector3 ankle_scale = mAnkleLeftp->getScale(); - -	LLVector3 foot  = mFootLeftp->getPosition(); - -	mPelvisToFoot = hip.mV[VZ] * pelvis_scale.mV[VZ] - -				 	knee.mV[VZ] * hip_scale.mV[VZ] - -				 	ankle.mV[VZ] * knee_scale.mV[VZ] - -				 	foot.mV[VZ] * ankle_scale.mV[VZ]; - -	LLVector3 new_body_size; -	new_body_size.mV[VZ] = mPelvisToFoot + -					   // the sqrt(2) correction below is an approximate -					   // correction to get to the top of the head -					   F_SQRT2 * (skull.mV[VZ] * head_scale.mV[VZ]) +  -					   head.mV[VZ] * neck_scale.mV[VZ] +  -					   neck.mV[VZ] * chest_scale.mV[VZ] +  -					   chest.mV[VZ] * torso_scale.mV[VZ] +  -					   torso.mV[VZ] * pelvis_scale.mV[VZ];  - -	// TODO -- measure the real depth and width -	new_body_size.mV[VX] = DEFAULT_AGENT_DEPTH; -	new_body_size.mV[VY] = DEFAULT_AGENT_WIDTH; - -	if (new_body_size != mBodySize) -	{ -		mBodySize = new_body_size; - -		if (isSelf() && !LLAppearanceMgr::instance().isInUpdateAppearanceFromCOF()) -		{	// notify simulator of change in size -			// but not if we are in the middle of updating appearance -			gAgent.sendAgentSetAppearance(); -		} -	} -} - -//------------------------------------------------------------------------  // LLVOAvatar::processUpdateMessage()  //------------------------------------------------------------------------  U32 LLVOAvatar::processUpdateMessage(LLMessageSystem *mesgsys, @@ -2478,7 +1984,7 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)  	// animate the character  	// store off last frame's root position to be consistent with camera position -	LLVector3 root_pos_last = mRoot.getWorldPosition(); +	LLVector3 root_pos_last = mRoot->getWorldPosition();  	BOOL detailed_update = updateCharacter(agent);  	static LLUICachedControl<bool> visualizers_in_calls("ShowVoiceVisualizersInCalls", false); @@ -2597,11 +2103,11 @@ void LLVOAvatar::idleUpdateVoiceVisualizer(bool voice_enabled)  		if ( mIsSitting )  		{  			LLVector3 headOffset = LLVector3( 0.0f, 0.0f, mHeadOffset.mV[2] ); -			mVoiceVisualizer->setVoiceSourceWorldPosition( mRoot.getWorldPosition() + headOffset ); +			mVoiceVisualizer->setVoiceSourceWorldPosition( mRoot->getWorldPosition() + headOffset );  		}  		else   		{ -			LLVector3 tagPos = mRoot.getWorldPosition(); +			LLVector3 tagPos = mRoot->getWorldPosition();  			tagPos[VZ] -= mPelvisToFoot;  			tagPos[VZ] += ( mBodySize[VZ] + 0.125f );  			mVoiceVisualizer->setVoiceSourceWorldPosition( tagPos ); @@ -3338,7 +2844,7 @@ void LLVOAvatar::invalidateNameTags()  // Compute name tag position during idle update  LLVector3 LLVOAvatar::idleUpdateNameTagPosition(const LLVector3& root_pos_last)  { -	LLQuaternion root_rot = mRoot.getWorldRotation(); +	LLQuaternion root_rot = mRoot->getWorldRotation();  	LLVector3 pixel_right_vec;  	LLVector3 pixel_up_vec;  	LLViewerCamera::getInstance()->getPixelVectors(root_pos_last, pixel_up_vec, pixel_right_vec); @@ -3352,7 +2858,7 @@ LLVector3 LLVOAvatar::idleUpdateNameTagPosition(const LLVector3& root_pos_last)  	local_camera_up.scaleVec(mBodySize * 0.5f);  	local_camera_at.scaleVec(mBodySize * 0.5f); -	LLVector3 name_position = mRoot.getWorldPosition(); +	LLVector3 name_position = mRoot->getWorldPosition();  	name_position[VZ] -= mPelvisToFoot;  	name_position[VZ] += (mBodySize[VZ]* 0.55f);  	name_position += (local_camera_up * root_rot) - (projected_vec(local_camera_at * root_rot, camera_to_av));	 @@ -3417,13 +2923,13 @@ void LLVOAvatar::idleUpdateBelowWater()  void LLVOAvatar::slamPosition()  {  	gAgent.setPositionAgent(getPositionAgent()); -	mRoot.setWorldPosition(getPositionAgent()); // teleport +	mRoot->setWorldPosition(getPositionAgent()); // teleport  	setChanged(TRANSLATED);  	if (mDrawable.notNull())  	{  		gPipeline.updateMoveNormalAsync(mDrawable);  	} -	mRoot.updateWorldMatrixChildren(); +	mRoot->updateWorldMatrixChildren();  }  bool LLVOAvatar::isVisuallyMuted() const @@ -3600,8 +3106,8 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)  			throttle = FALSE;  			// put the pelvis at slaved position/mRotation -			mRoot.setWorldPosition( getPositionAgent() ); // first frame -			mRoot.setWorldRotation( getRotation() ); +			mRoot->setWorldPosition( getPositionAgent() ); // first frame +			mRoot->setWorldRotation( getRotation() );  		}  		//-------------------------------------------------------------------- @@ -3644,10 +3150,10 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)  		LLVector3 newPosition = gAgent.getPosAgentFromGlobal(root_pos); -		if (newPosition != mRoot.getXform()->getWorldPosition()) +		if (newPosition != mRoot->getXform()->getWorldPosition())  		{		 -			mRoot.touch(); -			mRoot.setWorldPosition( newPosition ); // regular update				 +			mRoot->touch(); +			mRoot->setWorldPosition( newPosition ); // regular update				  		} @@ -3708,7 +3214,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)  			} -			LLQuaternion root_rotation = mRoot.getWorldMatrix().quaternion(); +			LLQuaternion root_rotation = mRoot->getWorldMatrix().quaternion();  			F32 root_roll, root_pitch, root_yaw;  			root_rotation.getEulerAngles(&root_roll, &root_pitch, &root_yaw); @@ -3717,7 +3223,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)  			// and head turn.  Once in motion, it must conform however.  			BOOL self_in_mouselook = isSelf() && gAgentCamera.cameraMouselook(); -			LLVector3 pelvisDir( mRoot.getWorldMatrix().getFwdRow4().mV ); +			LLVector3 pelvisDir( mRoot->getWorldMatrix().getFwdRow4().mV );  			static LLCachedControl<F32> s_pelvis_rot_threshold_slow(gSavedSettings, "AvatarRotateThresholdSlow");  			static LLCachedControl<F32> s_pelvis_rot_threshold_fast(gSavedSettings, "AvatarRotateThresholdFast"); @@ -3803,14 +3309,14 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)  			F32 u = llclamp((deltaTime / pelvis_lag_time), 0.0f, 1.0f);	 -			mRoot.setWorldRotation( slerp(u, mRoot.getWorldRotation(), wQv) ); +			mRoot->setWorldRotation( slerp(u, mRoot->getWorldRotation(), wQv) );  		}  	}  	else if (mDrawable.notNull())  	{ -		mRoot.setPosition(mDrawable->getPosition()); -		mRoot.setRotation(mDrawable->getRotation()); +		mRoot->setPosition(mDrawable->getPosition()); +		mRoot->setRotation(mDrawable->getRotation());  	}  	//------------------------------------------------------------------------- @@ -3910,7 +3416,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)  		}  	} -	mRoot.updateWorldMatrixChildren(); +	mRoot->updateWorldMatrixChildren();  	if (!mDebugText.size() && mText.notNull())  	{ @@ -3934,7 +3440,7 @@ void LLVOAvatar::updateHeadOffset()  {  	// since we only care about Z, just grab one of the eyes  	LLVector3 midEyePt = mEyeLeftp->getWorldPosition(); -	midEyePt -= mDrawable.notNull() ? mDrawable->getWorldPosition() : mRoot.getWorldPosition(); +	midEyePt -= mDrawable.notNull() ? mDrawable->getWorldPosition() : mRoot->getWorldPosition();  	midEyePt.mV[VZ] = llmax(-mPelvisToFoot + LLViewerCamera::getInstance()->getNear(), midEyePt.mV[VZ]);  	if (mDrawable.notNull()) @@ -3972,8 +3478,8 @@ void LLVOAvatar::setPelvisOffset( bool hasOffset, const LLVector3& offsetAmount,  void LLVOAvatar::postPelvisSetRecalc( void )  {	  	computeBodySize();  -	mRoot.touch(); -	mRoot.updateWorldMatrixChildren();	 +	mRoot->touch(); +	mRoot->updateWorldMatrixChildren();	  	dirtyMesh();  	updateHeadOffset();  } @@ -4207,19 +3713,44 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass)  		if (mNeedsSkin)  		{  			//generate animated mesh -			mMeshLOD[MESH_ID_LOWER_BODY]->updateJointGeometry(); -			mMeshLOD[MESH_ID_UPPER_BODY]->updateJointGeometry(); +			LLViewerJoint* lower_mesh = getViewerJoint(MESH_ID_LOWER_BODY); +			LLViewerJoint* upper_mesh = getViewerJoint(MESH_ID_UPPER_BODY); +			LLViewerJoint* skirt_mesh = getViewerJoint(MESH_ID_SKIRT); +			LLViewerJoint* eyelash_mesh = getViewerJoint(MESH_ID_EYELASH); +			LLViewerJoint* head_mesh = getViewerJoint(MESH_ID_HEAD); +			LLViewerJoint* hair_mesh = getViewerJoint(MESH_ID_HAIR); + +			if(upper_mesh) +			{ +				upper_mesh->updateJointGeometry(); +			} +			if (lower_mesh) +			{ +				lower_mesh->updateJointGeometry(); +			}  			if( isWearingWearableType( LLWearableType::WT_SKIRT ) )  			{ -				mMeshLOD[MESH_ID_SKIRT]->updateJointGeometry(); +				if(skirt_mesh) +				{ +					skirt_mesh->updateJointGeometry(); +				}  			}  			if (!isSelf() || gAgent.needsRenderHead() || LLPipeline::sShadowRender)  			{ -				mMeshLOD[MESH_ID_EYELASH]->updateJointGeometry(); -				mMeshLOD[MESH_ID_HEAD]->updateJointGeometry(); -				mMeshLOD[MESH_ID_HAIR]->updateJointGeometry(); +				if(eyelash_mesh) +				{ +					eyelash_mesh->updateJointGeometry(); +				} +				if(head_mesh) +				{ +					head_mesh->updateJointGeometry(); +				} +				if(hair_mesh) +				{ +					hair_mesh->updateJointGeometry(); +				}  			}  			mNeedsSkin = FALSE;  			mLastSkinTime = gFrameTimeSeconds; @@ -4336,19 +3867,31 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass)  			{  				if (isTextureVisible(TEX_HEAD_BAKED) || mIsDummy)  				{ -					num_indices += mMeshLOD[MESH_ID_HEAD]->render(mAdjustedPixelArea, TRUE, mIsDummy); +					LLViewerJoint* head_mesh = getViewerJoint(MESH_ID_HEAD); +					if (head_mesh) +					{ +						num_indices += head_mesh->render(mAdjustedPixelArea, TRUE, mIsDummy); +					}  					first_pass = FALSE;  				}  			}  			if (isTextureVisible(TEX_UPPER_BAKED) || mIsDummy)  			{ -				num_indices += mMeshLOD[MESH_ID_UPPER_BODY]->render(mAdjustedPixelArea, first_pass, mIsDummy); +				LLViewerJoint* upper_mesh = getViewerJoint(MESH_ID_UPPER_BODY); +				if (upper_mesh) +				{ +					num_indices += upper_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy); +				}  				first_pass = FALSE;  			}  			if (isTextureVisible(TEX_LOWER_BAKED) || mIsDummy)  			{ -				num_indices += mMeshLOD[MESH_ID_LOWER_BODY]->render(mAdjustedPixelArea, first_pass, mIsDummy); +				LLViewerJoint* lower_mesh = getViewerJoint(MESH_ID_LOWER_BODY); +				if (lower_mesh) +				{ +					num_indices += lower_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy); +				}  				first_pass = FALSE;  			}  		} @@ -4381,7 +3924,11 @@ U32 LLVOAvatar::renderTransparent(BOOL first_pass)  	if( isWearingWearableType( LLWearableType::WT_SKIRT ) && (mIsDummy || isTextureVisible(TEX_SKIRT_BAKED)) )  	{  		gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.25f); -		num_indices += mMeshLOD[MESH_ID_SKIRT]->render(mAdjustedPixelArea, FALSE); +		LLViewerJoint* skirt_mesh = getViewerJoint(MESH_ID_SKIRT); +		if (skirt_mesh) +		{ +			num_indices += skirt_mesh->render(mAdjustedPixelArea, FALSE); +		}  		first_pass = FALSE;  		gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);  	} @@ -4395,14 +3942,22 @@ U32 LLVOAvatar::renderTransparent(BOOL first_pass)  		if (isTextureVisible(TEX_HEAD_BAKED))  		{ -			num_indices += mMeshLOD[MESH_ID_EYELASH]->render(mAdjustedPixelArea, first_pass, mIsDummy); +			LLViewerJoint* eyelash_mesh = getViewerJoint(MESH_ID_EYELASH); +			if (eyelash_mesh) +			{ +				num_indices += eyelash_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy); +			}  			first_pass = FALSE;  		}  		// Can't test for baked hair being defined, since that won't always be the case (not all viewers send baked hair)  		// TODO: 1.25 will be able to switch this logic back to calling isTextureVisible();  		if (getImage(TEX_HAIR_BAKED, 0)->getID() != IMG_INVISIBLE || LLDrawPoolAlpha::sShowDebugAlpha)  		{ -			num_indices += mMeshLOD[MESH_ID_HAIR]->render(mAdjustedPixelArea, first_pass, mIsDummy); +			LLViewerJoint* hair_mesh = getViewerJoint(MESH_ID_HAIR); +			if (hair_mesh) +			{ +				num_indices += hair_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy); +			}  			first_pass = FALSE;  		}  		if (LLPipeline::sImpostorRender) @@ -4446,8 +4001,16 @@ U32 LLVOAvatar::renderRigid()  	if (isTextureVisible(TEX_EYES_BAKED)  || mIsDummy)  	{ -		num_indices += mMeshLOD[MESH_ID_EYEBALL_LEFT]->render(mAdjustedPixelArea, TRUE, mIsDummy); -		num_indices += mMeshLOD[MESH_ID_EYEBALL_RIGHT]->render(mAdjustedPixelArea, TRUE, mIsDummy); +		LLViewerJoint* eyeball_left = getViewerJoint(MESH_ID_EYEBALL_LEFT); +		LLViewerJoint* eyeball_right = getViewerJoint(MESH_ID_EYEBALL_RIGHT); +		if (eyeball_left) +		{ +			num_indices += eyeball_left->render(mAdjustedPixelArea, TRUE, mIsDummy); +		} +		if(eyeball_right) +		{ +			num_indices += eyeball_right->render(mAdjustedPixelArea, TRUE, mIsDummy); +		}  	}  	if (should_alpha_mask && !LLGLSLShader::sNoFixedFunction) @@ -5139,7 +4702,7 @@ LLJoint *LLVOAvatar::getJoint( const std::string &name )  	if (iter == mJointMap.end() || iter->second == NULL)  	{ //search for joint and cache found joint in lookup table -		jointp = mRoot.findJoint(name); +		jointp = mRoot->findJoint(name);  		mJointMap[name] = jointp;  	}  	else @@ -5168,7 +4731,7 @@ void LLVOAvatar::resetJointPositions( void )  //-----------------------------------------------------------------------------  void LLVOAvatar::resetSpecificJointPosition( const std::string& name )  { -	LLJoint* pJoint = mRoot.findJoint( name ); +	LLJoint* pJoint = mRoot->findJoint( name );  	if ( pJoint  && pJoint->doesJointNeedToBeReset() )  	{ @@ -5356,23 +4919,6 @@ BOOL LLVOAvatar::allocateCharacterJoints( U32 num )  	return TRUE;  } -//----------------------------------------------------------------------------- -// allocateCollisionVolumes() -//----------------------------------------------------------------------------- -BOOL LLVOAvatar::allocateCollisionVolumes( U32 num ) -{ -	deleteAndClearArray(mCollisionVolumes); -	mNumCollisionVolumes = 0; - -	mCollisionVolumes = new LLViewerJointCollisionVolume[num]; -	if (!mCollisionVolumes) -	{ -		return FALSE; -	} - -	mNumCollisionVolumes = num; -	return TRUE; -}  //----------------------------------------------------------------------------- @@ -5398,153 +4944,13 @@ void LLVOAvatar::requestStopMotion( LLMotion* motion )  }  //----------------------------------------------------------------------------- -// loadAvatar() -//----------------------------------------------------------------------------- -static LLFastTimer::DeclareTimer FTM_LOAD_AVATAR("Load Avatar"); - -BOOL LLVOAvatar::loadAvatar() -{ -// 	LLFastTimer t(FTM_LOAD_AVATAR); -	 -	// avatar_skeleton.xml -	if( !buildSkeleton(sAvatarSkeletonInfo) ) -	{ -		llwarns << "avatar file: buildSkeleton() failed" << llendl; -		return FALSE; -	} - -	// avatar_lad.xml : <skeleton> -	if( !loadSkeletonNode() ) -	{ -		llwarns << "avatar file: loadNodeSkeleton() failed" << llendl; -		return FALSE; -	} -	 -	// avatar_lad.xml : <mesh> -	if( !loadMeshNodes() ) -	{ -		llwarns << "avatar file: loadNodeMesh() failed" << llendl; -		return FALSE; -	} -	 -	// avatar_lad.xml : <global_color> -	if( sAvatarXmlInfo->mTexSkinColorInfo ) -	{ -		mTexSkinColor = new LLTexGlobalColor( this ); -		if( !mTexSkinColor->setInfo( sAvatarXmlInfo->mTexSkinColorInfo ) ) -		{ -			llwarns << "avatar file: mTexSkinColor->setInfo() failed" << llendl; -			return FALSE; -		} -	} -	else -	{ -		llwarns << "<global_color> name=\"skin_color\" not found" << llendl; -		return FALSE; -	} -	if( sAvatarXmlInfo->mTexHairColorInfo ) -	{ -		mTexHairColor = new LLTexGlobalColor( this ); -		if( !mTexHairColor->setInfo( sAvatarXmlInfo->mTexHairColorInfo ) ) -		{ -			llwarns << "avatar file: mTexHairColor->setInfo() failed" << llendl; -			return FALSE; -		} -	} -	else -	{ -		llwarns << "<global_color> name=\"hair_color\" not found" << llendl; -		return FALSE; -	} -	if( sAvatarXmlInfo->mTexEyeColorInfo ) -	{ -		mTexEyeColor = new LLTexGlobalColor( this ); -		if( !mTexEyeColor->setInfo( sAvatarXmlInfo->mTexEyeColorInfo ) ) -		{ -			llwarns << "avatar file: mTexEyeColor->setInfo() failed" << llendl; -			return FALSE; -		} -	} -	else -	{ -		llwarns << "<global_color> name=\"eye_color\" not found" << llendl; -		return FALSE; -	} -	 -	// avatar_lad.xml : <layer_set> -	if (sAvatarXmlInfo->mLayerInfoList.empty()) -	{ -		llwarns << "avatar file: missing <layer_set> node" << llendl; -		return FALSE; -	} - -	if (sAvatarXmlInfo->mMorphMaskInfoList.empty()) -	{ -		llwarns << "avatar file: missing <morph_masks> node" << llendl; -		return FALSE; -	} - -	// avatar_lad.xml : <morph_masks> -	for (LLVOAvatarXmlInfo::morph_info_list_t::iterator iter = sAvatarXmlInfo->mMorphMaskInfoList.begin(); -		 iter != sAvatarXmlInfo->mMorphMaskInfoList.end(); -		 ++iter) -	{ -		LLVOAvatarXmlInfo::LLVOAvatarMorphInfo *info = *iter; - -		EBakedTextureIndex baked = LLAvatarAppearanceDictionary::findBakedByRegionName(info->mRegion);  -		if (baked != BAKED_NUM_INDICES) -		{ -			LLVisualParam* morph_param; -			const std::string *name = &info->mName; -			morph_param = getVisualParam(name->c_str()); -			if (morph_param) -			{ -				BOOL invert = info->mInvert; -				addMaskedMorph(baked, morph_param, invert, info->mLayer); -			} -		} - -	} - -	loadLayersets();	 -	 -	// avatar_lad.xml : <driver_parameters> -	for (LLVOAvatarXmlInfo::driver_info_list_t::iterator iter = sAvatarXmlInfo->mDriverInfoList.begin(); -		 iter != sAvatarXmlInfo->mDriverInfoList.end();  -		 ++iter) -	{ -		LLDriverParamInfo *info = *iter; -		LLDriverParam* driver_param = new LLDriverParam( this ); -		if (driver_param->setInfo(info)) -		{ -			addVisualParam( driver_param ); -			LLVisualParam*(LLVOAvatar::*avatar_function)(S32)const = &LLVOAvatar::getVisualParam;  -			if( !driver_param->linkDrivenParams(boost::bind(avatar_function,(LLVOAvatar*)this,_1 ), false)) -			{ -				llwarns << "could not link driven params for avatar " << this->getFullname() << " id: " << driver_param->getID() << llendl; -				continue; -			} -		} -		else -		{ -			delete driver_param; -			llwarns << "avatar file: driver_param->parseData() failed" << llendl; -			return FALSE; -		} -	} - -	 -	return TRUE; -} - -//-----------------------------------------------------------------------------  // loadSkeletonNode(): loads <skeleton> node from XML tree  //----------------------------------------------------------------------------- +//virtual  BOOL LLVOAvatar::loadSkeletonNode ()  { -	mRoot.addChild( &mSkeleton[0] ); - -	for (std::vector<LLViewerJoint *>::iterator iter = mMeshLOD.begin(); +	// make meshes children before calling parent version of the function +	for (std::vector<LLAvatarJoint *>::iterator iter = mMeshLOD.begin();  		 iter != mMeshLOD.end();   		 ++iter)  	{ @@ -5553,60 +4959,19 @@ BOOL LLVOAvatar::loadSkeletonNode ()  		joint->setMeshesToChildren();  	} -	mRoot.addChild(mMeshLOD[MESH_ID_HEAD]); -	mRoot.addChild(mMeshLOD[MESH_ID_EYELASH]); -	mRoot.addChild(mMeshLOD[MESH_ID_UPPER_BODY]); -	mRoot.addChild(mMeshLOD[MESH_ID_LOWER_BODY]); -	mRoot.addChild(mMeshLOD[MESH_ID_SKIRT]); -	mRoot.addChild(mMeshLOD[MESH_ID_HEAD]); - -	LLViewerJoint *skull = (LLViewerJoint*)mRoot.findJoint("mSkull"); -	if (skull) -	{ -		skull->addChild(mMeshLOD[MESH_ID_HAIR] ); -	} - -	LLViewerJoint *eyeL = (LLViewerJoint*)mRoot.findJoint("mEyeLeft"); -	if (eyeL) +	if (!LLAvatarAppearance::loadSkeletonNode())  	{ -		eyeL->addChild( mMeshLOD[MESH_ID_EYEBALL_LEFT] ); -	} - -	LLViewerJoint *eyeR = (LLViewerJoint*)mRoot.findJoint("mEyeRight"); -	if (eyeR) -	{ -		eyeR->addChild( mMeshLOD[MESH_ID_EYEBALL_RIGHT] ); +		return FALSE;  	} -	// SKELETAL DISTORTIONS -	{ -		LLVOAvatarXmlInfo::skeletal_distortion_info_list_t::iterator iter; -		for (iter = sAvatarXmlInfo->mSkeletalDistortionInfoList.begin(); -			 iter != sAvatarXmlInfo->mSkeletalDistortionInfoList.end();  -			 ++iter) -		{ -			LLPolySkeletalDistortionInfo *info = *iter; -			LLPolySkeletalDistortion *param = new LLPolySkeletalDistortion(this); -			if (!param->setInfo(info)) -			{ -				delete param; -				return FALSE; -			} -			else -			{ -				addVisualParam(param); -			}				 -		} -	} -	  	// ATTACHMENTS  	{ -		LLVOAvatarXmlInfo::attachment_info_list_t::iterator iter; +		LLAvatarXmlInfo::attachment_info_list_t::iterator iter;  		for (iter = sAvatarXmlInfo->mAttachmentInfoList.begin();  			 iter != sAvatarXmlInfo->mAttachmentInfoList.end();   			 ++iter)  		{ -			LLVOAvatarXmlInfo::LLVOAvatarAttachmentInfo *info = *iter; +			LLAvatarXmlInfo::LLAvatarAttachmentInfo *info = *iter;  			if (!isSelf() && info->mJointName == "mScreen")  			{ //don't process screen joint for other avatars  				continue; @@ -5679,144 +5044,6 @@ BOOL LLVOAvatar::loadSkeletonNode ()  }  //----------------------------------------------------------------------------- -// loadMeshNodes(): loads <mesh> nodes from XML tree -//----------------------------------------------------------------------------- -BOOL LLVOAvatar::loadMeshNodes() -{ -	for (LLVOAvatarXmlInfo::mesh_info_list_t::const_iterator meshinfo_iter = sAvatarXmlInfo->mMeshInfoList.begin(); -		 meshinfo_iter != sAvatarXmlInfo->mMeshInfoList.end();  -		 ++meshinfo_iter) -	{ -		const LLVOAvatarXmlInfo::LLVOAvatarMeshInfo *info = *meshinfo_iter; -		const std::string &type = info->mType; -		S32 lod = info->mLOD; - -		LLViewerJointMesh* mesh = NULL; -		U8 mesh_id = 0; -		BOOL found_mesh_id = FALSE; - -		/* if (type == "hairMesh") -			switch(lod) -			  case 0: -				mesh = &mHairMesh0; */ -		for (LLAvatarAppearanceDictionary::Meshes::const_iterator mesh_iter = LLAvatarAppearanceDictionary::getInstance()->getMeshes().begin(); -			 mesh_iter != LLAvatarAppearanceDictionary::getInstance()->getMeshes().end(); -			 ++mesh_iter) -		{ -			const EMeshIndex mesh_index = mesh_iter->first; -			const LLAvatarAppearanceDictionary::MeshEntry *mesh_dict = mesh_iter->second; -			if (type.compare(mesh_dict->mName) == 0) -			{ -				mesh_id = mesh_index; -				found_mesh_id = TRUE; -				break; -			} -		} - -		if (found_mesh_id) -		{ -			if (lod < (S32)mMeshLOD[mesh_id]->mMeshParts.size()) -			{ -				mesh = mMeshLOD[mesh_id]->mMeshParts[lod]; -			} -			else -			{ -				llwarns << "Avatar file: <mesh> has invalid lod setting " << lod << llendl; -				return FALSE; -			} -		} -		else  -		{ -			llwarns << "Ignoring unrecognized mesh type: " << type << llendl; -			return FALSE; -		} - -		//	llinfos << "Parsing mesh data for " << type << "..." << llendl; - -		// If this isn't set to white (1.0), avatars will *ALWAYS* be darker than their surroundings. -		// Do not touch!!! -		mesh->setColor( 1.0f, 1.0f, 1.0f, 1.0f ); - -		LLPolyMesh *poly_mesh = NULL; - -		if (!info->mReferenceMeshName.empty()) -		{ -			polymesh_map_t::const_iterator polymesh_iter = mMeshes.find(info->mReferenceMeshName); -			if (polymesh_iter != mMeshes.end()) -			{ -				poly_mesh = LLPolyMesh::getMesh(info->mMeshFileName, polymesh_iter->second); -				poly_mesh->setAvatar(this); -			} -			else -			{ -				// This should never happen -				LL_WARNS("Avatar") << "Could not find avatar mesh: " << info->mReferenceMeshName << LL_ENDL; -			} -		} -		else -		{ -			poly_mesh = LLPolyMesh::getMesh(info->mMeshFileName); -			poly_mesh->setAvatar(this); -		} - -		if( !poly_mesh ) -		{ -			llwarns << "Failed to load mesh of type " << type << llendl; -			return FALSE; -		} - -		// Multimap insert -		mMeshes.insert(std::make_pair(info->mMeshFileName, poly_mesh)); -	 -		mesh->setMesh( poly_mesh ); -		mesh->setLOD( info->mMinPixelArea ); - -		for (LLVOAvatarXmlInfo::LLVOAvatarMeshInfo::morph_info_list_t::const_iterator xmlinfo_iter = info->mPolyMorphTargetInfoList.begin(); -			 xmlinfo_iter != info->mPolyMorphTargetInfoList.end();  -			 ++xmlinfo_iter) -		{ -			const LLVOAvatarXmlInfo::LLVOAvatarMeshInfo::morph_info_pair_t *info_pair = &(*xmlinfo_iter); -			LLPolyMorphTarget *param = new LLPolyMorphTarget(mesh->getMesh()); -			if (!param->setInfo(info_pair->first)) -			{ -				delete param; -				return FALSE; -			} -			else -			{ -				if (info_pair->second) -				{ -					addSharedVisualParam(param); -				} -				else -				{ -					addVisualParam(param); -				} -			}				 -		} -	} - -	return TRUE; -} - -//----------------------------------------------------------------------------- -// loadLayerSets() -//----------------------------------------------------------------------------- -BOOL LLVOAvatar::loadLayersets() -{ -	BOOL success = TRUE; -	for (LLVOAvatarXmlInfo::layer_info_list_t::const_iterator layerset_iter = sAvatarXmlInfo->mLayerInfoList.begin(); -		 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); -	} -	return success; -} - -//-----------------------------------------------------------------------------  // updateVisualParams()  //-----------------------------------------------------------------------------  void LLVOAvatar::updateVisualParams() @@ -5829,7 +5056,7 @@ void LLVOAvatar::updateVisualParams()  	{  		computeBodySize();  		mLastSkeletonSerialNum = mSkeletonSerialNum; -		mRoot.updateWorldMatrixChildren(); +		mRoot->updateWorldMatrixChildren();  	}  	dirtyMesh(); @@ -5919,7 +5146,12 @@ BOOL LLVOAvatar::updateJointLODs()  		}  		// now select meshes to render based on adjusted pixel area -		BOOL res = mRoot.updateLOD(mAdjustedPixelArea, TRUE); +		LLViewerJoint* root = dynamic_cast<LLViewerJoint*>(mRoot); +		BOOL res = FALSE; +		if (root) +		{ +			res = root->updateLOD(mAdjustedPixelArea, TRUE); +		}   		if (res)  		{  			sNumLODChangesThisFrame++; @@ -6009,6 +5241,15 @@ void LLVOAvatar::dirtyMesh(S32 priority)  {  	mDirtyMesh = llmax(mDirtyMesh, priority);  } + +//----------------------------------------------------------------------------- +// getViewerJoint() +//----------------------------------------------------------------------------- +LLViewerJoint*	LLVOAvatar::getViewerJoint(S32 idx) +{ +	return dynamic_cast<LLViewerJoint*>(mMeshLOD[idx]); +} +  //-----------------------------------------------------------------------------  // hideSkirt()  //----------------------------------------------------------------------------- @@ -6322,9 +5563,9 @@ void LLVOAvatar::sitOnObject(LLViewerObject *sit_object)  	// Notice that removing sitDown() from here causes avatars sitting on  	// objects to be not rendered for new arrivals. See EXT-6835 and EXT-1655.  	sitDown(TRUE); -	mRoot.getXform()->setParent(&sit_object->mDrawable->mXform); // LLVOAvatar::sitOnObject -	mRoot.setPosition(getPosition()); -	mRoot.updateWorldMatrixChildren(); +	mRoot->getXform()->setParent(&sit_object->mDrawable->mXform); // LLVOAvatar::sitOnObject +	mRoot->setPosition(getPosition()); +	mRoot->updateWorldMatrixChildren();  	stopMotion(ANIM_AGENT_BODY_NOISE); @@ -6370,10 +5611,10 @@ void LLVOAvatar::getOffObject()  	sitDown(FALSE); -	mRoot.getXform()->setParent(NULL); // LLVOAvatar::getOffObject -	mRoot.setPosition(cur_position_world); -	mRoot.setRotation(cur_rotation_world); -	mRoot.getXform()->update(); +	mRoot->getXform()->setParent(NULL); // LLVOAvatar::getOffObject +	mRoot->setPosition(cur_position_world); +	mRoot->setRotation(cur_rotation_world); +	mRoot->getXform()->update();  	startMotion(ANIM_AGENT_BODY_NOISE); @@ -7752,501 +6993,20 @@ void LLVOAvatar::startAppearanceAnimation()  	}  } -// virtual -void LLVOAvatar::removeMissingBakedTextures() -{	 -} - -//----------------------------------------------------------------------------- -// LLVOAvatarXmlInfo -//----------------------------------------------------------------------------- - -LLVOAvatar::LLVOAvatarXmlInfo::LLVOAvatarXmlInfo() -	: mTexSkinColorInfo(0), mTexHairColorInfo(0), mTexEyeColorInfo(0) -{ -} - -LLVOAvatar::LLVOAvatarXmlInfo::~LLVOAvatarXmlInfo() -{ -	std::for_each(mMeshInfoList.begin(), mMeshInfoList.end(), DeletePointer()); -	std::for_each(mSkeletalDistortionInfoList.begin(), mSkeletalDistortionInfoList.end(), DeletePointer());		 -	std::for_each(mAttachmentInfoList.begin(), mAttachmentInfoList.end(), DeletePointer()); -	deleteAndClear(mTexSkinColorInfo); -	deleteAndClear(mTexHairColorInfo); -	deleteAndClear(mTexEyeColorInfo); -	std::for_each(mLayerInfoList.begin(), mLayerInfoList.end(), DeletePointer());		 -	std::for_each(mDriverInfoList.begin(), mDriverInfoList.end(), DeletePointer()); -	std::for_each(mMorphMaskInfoList.begin(), mMorphMaskInfoList.end(), DeletePointer()); -} - -//----------------------------------------------------------------------------- -// LLVOAvatarBoneInfo::parseXml() -//----------------------------------------------------------------------------- -BOOL LLVOAvatarBoneInfo::parseXml(LLXmlTreeNode* node) -{ -	if (node->hasName("bone")) -	{ -		mIsJoint = TRUE; -		static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name"); -		if (!node->getFastAttributeString(name_string, mName)) -		{ -			llwarns << "Bone without name" << llendl; -			return FALSE; -		} -	} -	else if (node->hasName("collision_volume")) -	{ -		mIsJoint = FALSE; -		static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name"); -		if (!node->getFastAttributeString(name_string, mName)) -		{ -			mName = "Collision Volume"; -		} -	} -	else -	{ -		llwarns << "Invalid node " << node->getName() << llendl; -		return FALSE; -	} - -	static LLStdStringHandle pos_string = LLXmlTree::addAttributeString("pos"); -	if (!node->getFastAttributeVector3(pos_string, mPos)) -	{ -		llwarns << "Bone without position" << llendl; -		return FALSE; -	} - -	static LLStdStringHandle rot_string = LLXmlTree::addAttributeString("rot"); -	if (!node->getFastAttributeVector3(rot_string, mRot)) -	{ -		llwarns << "Bone without rotation" << llendl; -		return FALSE; -	} -	 -	static LLStdStringHandle scale_string = LLXmlTree::addAttributeString("scale"); -	if (!node->getFastAttributeVector3(scale_string, mScale)) -	{ -		llwarns << "Bone without scale" << llendl; -		return FALSE; -	} - -	if (mIsJoint) -	{ -		static LLStdStringHandle pivot_string = LLXmlTree::addAttributeString("pivot"); -		if (!node->getFastAttributeVector3(pivot_string, mPivot)) -		{ -			llwarns << "Bone without pivot" << llendl; -			return FALSE; -		} -	} - -	// parse children -	LLXmlTreeNode* child; -	for( child = node->getFirstChild(); child; child = node->getNextChild() ) -	{ -		LLVOAvatarBoneInfo *child_info = new LLVOAvatarBoneInfo; -		if (!child_info->parseXml(child)) -		{ -			delete child_info; -			return FALSE; -		} -		mChildList.push_back(child_info); -	} -	return TRUE; -} - -//----------------------------------------------------------------------------- -// LLVOAvatarSkeletonInfo::parseXml() -//----------------------------------------------------------------------------- -BOOL LLVOAvatarSkeletonInfo::parseXml(LLXmlTreeNode* node) -{ -	static LLStdStringHandle num_bones_string = LLXmlTree::addAttributeString("num_bones"); -	if (!node->getFastAttributeS32(num_bones_string, mNumBones)) -	{ -		llwarns << "Couldn't find number of bones." << llendl; -		return FALSE; -	} - -	static LLStdStringHandle num_collision_volumes_string = LLXmlTree::addAttributeString("num_collision_volumes"); -	node->getFastAttributeS32(num_collision_volumes_string, mNumCollisionVolumes); - -	LLXmlTreeNode* child; -	for( child = node->getFirstChild(); child; child = node->getNextChild() ) -	{ -		LLVOAvatarBoneInfo *info = new LLVOAvatarBoneInfo; -		if (!info->parseXml(child)) -		{ -			delete info; -			llwarns << "Error parsing bone in skeleton file" << llendl; -			return FALSE; -		} -		mBoneInfoList.push_back(info); -	} -	return TRUE; -} - -//----------------------------------------------------------------------------- -// parseXmlSkeletonNode(): parses <skeleton> nodes from XML tree -//----------------------------------------------------------------------------- -BOOL LLVOAvatar::LLVOAvatarXmlInfo::parseXmlSkeletonNode(LLXmlTreeNode* root) -{ -	LLXmlTreeNode* node = root->getChildByName( "skeleton" ); -	if( !node ) -	{ -		llwarns << "avatar file: missing <skeleton>" << llendl; -		return FALSE; -	} - -	LLXmlTreeNode* child; - -	// SKELETON DISTORTIONS -	for (child = node->getChildByName( "param" ); -		 child; -		 child = node->getNextNamedChild()) -	{ -		if (!child->getChildByName("param_skeleton")) -		{ -			if (child->getChildByName("param_morph")) -			{ -				llwarns << "Can't specify morph param in skeleton definition." << llendl; -			} -			else -			{ -				llwarns << "Unknown param type." << llendl; -			} -			continue; -		} -		 -		LLPolySkeletalDistortionInfo *info = new LLPolySkeletalDistortionInfo; -		if (!info->parseXml(child)) -		{ -			delete info; -			return FALSE; -		} - -		mSkeletalDistortionInfoList.push_back(info); -	} - -	// ATTACHMENT POINTS -	for (child = node->getChildByName( "attachment_point" ); -		 child; -		 child = node->getNextNamedChild()) -	{ -		LLVOAvatarAttachmentInfo* info = new LLVOAvatarAttachmentInfo(); - -		static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name"); -		if (!child->getFastAttributeString(name_string, info->mName)) -		{ -			llwarns << "No name supplied for attachment point." << llendl; -			delete info; -			continue; -		} - -		static LLStdStringHandle joint_string = LLXmlTree::addAttributeString("joint"); -		if (!child->getFastAttributeString(joint_string, info->mJointName)) -		{ -			llwarns << "No bone declared in attachment point " << info->mName << llendl; -			delete info; -			continue; -		} - -		static LLStdStringHandle position_string = LLXmlTree::addAttributeString("position"); -		if (child->getFastAttributeVector3(position_string, info->mPosition)) -		{ -			info->mHasPosition = TRUE; -		} - -		static LLStdStringHandle rotation_string = LLXmlTree::addAttributeString("rotation"); -		if (child->getFastAttributeVector3(rotation_string, info->mRotationEuler)) -		{ -			info->mHasRotation = TRUE; -		} -		 static LLStdStringHandle group_string = LLXmlTree::addAttributeString("group"); -		if (child->getFastAttributeS32(group_string, info->mGroup)) -		{ -			if (info->mGroup == -1) -				info->mGroup = -1111; // -1 = none parsed, < -1 = bad value -		} - -		static LLStdStringHandle id_string = LLXmlTree::addAttributeString("id"); -		if (!child->getFastAttributeS32(id_string, info->mAttachmentID)) -		{ -			llwarns << "No id supplied for attachment point " << info->mName << llendl; -			delete info; -			continue; -		} - -		static LLStdStringHandle slot_string = LLXmlTree::addAttributeString("pie_slice"); -		child->getFastAttributeS32(slot_string, info->mPieMenuSlice); -			 -		static LLStdStringHandle visible_in_first_person_string = LLXmlTree::addAttributeString("visible_in_first_person"); -		child->getFastAttributeBOOL(visible_in_first_person_string, info->mVisibleFirstPerson); - -		static LLStdStringHandle hud_attachment_string = LLXmlTree::addAttributeString("hud"); -		child->getFastAttributeBOOL(hud_attachment_string, info->mIsHUDAttachment); - -		mAttachmentInfoList.push_back(info); -	} - -	return TRUE; -} - -//----------------------------------------------------------------------------- -// parseXmlMeshNodes(): parses <mesh> nodes from XML tree -//----------------------------------------------------------------------------- -BOOL LLVOAvatar::LLVOAvatarXmlInfo::parseXmlMeshNodes(LLXmlTreeNode* root) -{ -	for (LLXmlTreeNode* node = root->getChildByName( "mesh" ); -		 node; -		 node = root->getNextNamedChild()) -	{ -		LLVOAvatarMeshInfo *info = new LLVOAvatarMeshInfo; - -		// attribute: type -		static LLStdStringHandle type_string = LLXmlTree::addAttributeString("type"); -		if( !node->getFastAttributeString( type_string, info->mType ) ) -		{ -			llwarns << "Avatar file: <mesh> is missing type attribute.  Ignoring element. " << llendl; -			delete info; -			return FALSE;  // Ignore this element -		} -		 -		static LLStdStringHandle lod_string = LLXmlTree::addAttributeString("lod"); -		if (!node->getFastAttributeS32( lod_string, info->mLOD )) -		{ -			llwarns << "Avatar file: <mesh> is missing lod attribute.  Ignoring element. " << llendl; -			delete info; -			return FALSE;  // Ignore this element -		} - -		static LLStdStringHandle file_name_string = LLXmlTree::addAttributeString("file_name"); -		if( !node->getFastAttributeString( file_name_string, info->mMeshFileName ) ) -		{ -			llwarns << "Avatar file: <mesh> is missing file_name attribute.  Ignoring: " << info->mType << llendl; -			delete info; -			return FALSE;  // Ignore this element -		} - -		static LLStdStringHandle reference_string = LLXmlTree::addAttributeString("reference"); -		node->getFastAttributeString( reference_string, info->mReferenceMeshName ); -		 -		// attribute: min_pixel_area -		static LLStdStringHandle min_pixel_area_string = LLXmlTree::addAttributeString("min_pixel_area"); -		static LLStdStringHandle min_pixel_width_string = LLXmlTree::addAttributeString("min_pixel_width"); -		if (!node->getFastAttributeF32( min_pixel_area_string, info->mMinPixelArea )) -		{ -			F32 min_pixel_area = 0.1f; -			if (node->getFastAttributeF32( min_pixel_width_string, min_pixel_area )) -			{ -				// this is square root of pixel area (sensible to use linear space in defining lods) -				min_pixel_area = min_pixel_area * min_pixel_area; -			} -			info->mMinPixelArea = min_pixel_area; -		} -		 -		// Parse visual params for this node only if we haven't already -		for (LLXmlTreeNode* child = node->getChildByName( "param" ); -			 child; -			 child = node->getNextNamedChild()) -		{ -			if (!child->getChildByName("param_morph")) -			{ -				if (child->getChildByName("param_skeleton")) -				{ -					llwarns << "Can't specify skeleton param in a mesh definition." << llendl; -				} -				else -				{ -					llwarns << "Unknown param type." << llendl; -				} -				continue; -			} - -			LLPolyMorphTargetInfo *morphinfo = new LLPolyMorphTargetInfo(); -			if (!morphinfo->parseXml(child)) -			{ -				delete morphinfo; -				delete info; -				return -1; -			} -			BOOL shared = FALSE; -			static LLStdStringHandle shared_string = LLXmlTree::addAttributeString("shared"); -			child->getFastAttributeBOOL(shared_string, shared); - -			info->mPolyMorphTargetInfoList.push_back(LLVOAvatarMeshInfo::morph_info_pair_t(morphinfo, shared)); -		} - -		mMeshInfoList.push_back(info); -	} -	return TRUE; -} - -//----------------------------------------------------------------------------- -// parseXmlColorNodes(): parses <global_color> nodes from XML tree -//----------------------------------------------------------------------------- -BOOL LLVOAvatar::LLVOAvatarXmlInfo::parseXmlColorNodes(LLXmlTreeNode* root) -{ -	for (LLXmlTreeNode* color_node = root->getChildByName( "global_color" ); -		 color_node; -		 color_node = root->getNextNamedChild()) -	{ -		std::string global_color_name; -		static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name"); -		if (color_node->getFastAttributeString( name_string, global_color_name ) ) -		{ -			if( global_color_name == "skin_color" ) -			{ -				if (mTexSkinColorInfo) -				{ -					llwarns << "avatar file: multiple instances of skin_color" << llendl; -					return FALSE; -				} -				mTexSkinColorInfo = new LLTexGlobalColorInfo; -				if( !mTexSkinColorInfo->parseXml( color_node ) ) -				{ -					deleteAndClear(mTexSkinColorInfo); -					llwarns << "avatar file: mTexSkinColor->parseXml() failed" << llendl; -					return FALSE; -				} -			} -			else if( global_color_name == "hair_color" ) -			{ -				if (mTexHairColorInfo) -				{ -					llwarns << "avatar file: multiple instances of hair_color" << llendl; -					return FALSE; -				} -				mTexHairColorInfo = new LLTexGlobalColorInfo; -				if( !mTexHairColorInfo->parseXml( color_node ) ) -				{ -					deleteAndClear(mTexHairColorInfo); -					llwarns << "avatar file: mTexHairColor->parseXml() failed" << llendl; -					return FALSE; -				} -			} -			else if( global_color_name == "eye_color" ) -			{ -				if (mTexEyeColorInfo) -				{ -					llwarns << "avatar file: multiple instances of eye_color" << llendl; -					return FALSE; -				} -				mTexEyeColorInfo = new LLTexGlobalColorInfo; -				if( !mTexEyeColorInfo->parseXml( color_node ) ) -				{ -					llwarns << "avatar file: mTexEyeColor->parseXml() failed" << llendl; -					return FALSE; -				} -			} -		} -	} -	return TRUE; -} - -//----------------------------------------------------------------------------- -// parseXmlLayerNodes(): parses <layer_set> nodes from XML tree -//----------------------------------------------------------------------------- -BOOL LLVOAvatar::LLVOAvatarXmlInfo::parseXmlLayerNodes(LLXmlTreeNode* root) -{ -	for (LLXmlTreeNode* layer_node = root->getChildByName( "layer_set" ); -		 layer_node; -		 layer_node = root->getNextNamedChild()) -	{ -		LLTexLayerSetInfo* layer_info = new LLTexLayerSetInfo(); -		if( layer_info->parseXml( layer_node ) ) -		{ -			mLayerInfoList.push_back(layer_info); -		} -		else -		{ -			delete layer_info; -			llwarns << "avatar file: layer_set->parseXml() failed" << llendl; -			return FALSE; -		} -	} -	return TRUE; -} - -//----------------------------------------------------------------------------- -// parseXmlDriverNodes(): parses <driver_parameters> nodes from XML tree -//----------------------------------------------------------------------------- -BOOL LLVOAvatar::LLVOAvatarXmlInfo::parseXmlDriverNodes(LLXmlTreeNode* root) +//virtual +void LLVOAvatar::bodySizeChanged()  { -	LLXmlTreeNode* driver = root->getChildByName( "driver_parameters" ); -	if( driver ) -	{ -		for (LLXmlTreeNode* grand_child = driver->getChildByName( "param" ); -			 grand_child; -			 grand_child = driver->getNextNamedChild()) -		{ -			if( grand_child->getChildByName( "param_driver" ) ) -			{ -				LLDriverParamInfo* driver_info = new LLDriverParamInfo(); -				if( driver_info->parseXml( grand_child ) ) -				{ -					mDriverInfoList.push_back(driver_info); -				} -				else -				{ -					delete driver_info; -					llwarns << "avatar file: driver_param->parseXml() failed" << llendl; -					return FALSE; -				} -			} -		} +	if (isSelf() && !LLAppearanceMgr::instance().isInUpdateAppearanceFromCOF()) +	{	// notify simulator of change in size +		// but not if we are in the middle of updating appearance +		gAgent.sendAgentSetAppearance();  	} -	return TRUE;  } -//----------------------------------------------------------------------------- -// parseXmlDriverNodes(): parses <driver_parameters> nodes from XML tree -//----------------------------------------------------------------------------- -BOOL LLVOAvatar::LLVOAvatarXmlInfo::parseXmlMorphNodes(LLXmlTreeNode* root) -{ -	LLXmlTreeNode* masks = root->getChildByName( "morph_masks" ); -	if( !masks ) -	{ -		return FALSE; -	} -	for (LLXmlTreeNode* grand_child = masks->getChildByName( "mask" ); -		 grand_child; -		 grand_child = masks->getNextNamedChild()) -	{ -		LLVOAvatarMorphInfo* info = new LLVOAvatarMorphInfo(); - -		static LLStdStringHandle name_string = LLXmlTree::addAttributeString("morph_name"); -		if (!grand_child->getFastAttributeString(name_string, info->mName)) -		{ -			llwarns << "No name supplied for morph mask." << llendl; -			delete info; -			continue; -		} - -		static LLStdStringHandle region_string = LLXmlTree::addAttributeString("body_region"); -		if (!grand_child->getFastAttributeString(region_string, info->mRegion)) -		{ -			llwarns << "No region supplied for morph mask." << llendl; -			delete info; -			continue; -		} - -		static LLStdStringHandle layer_string = LLXmlTree::addAttributeString("layer"); -		if (!grand_child->getFastAttributeString(layer_string, info->mLayer)) -		{ -			llwarns << "No layer supplied for morph mask." << llendl; -			delete info; -			continue; -		} - -		// optional parameter. don't throw a warning if not present. -		static LLStdStringHandle invert_string = LLXmlTree::addAttributeString("invert"); -		grand_child->getFastAttributeBOOL(invert_string, info->mInvert); - -		mMorphMaskInfoList.push_back(info); -	} - -	return TRUE; +// virtual +void LLVOAvatar::removeMissingBakedTextures() +{	  }  //virtual diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index dd8663f4dc..bda09b044d 100755 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -69,8 +69,7 @@ class LLVoiceVisualizer;  class LLHUDNameTag;  class LLHUDEffectSpiral;  class LLTexGlobalColor; -class LLVOAvatarBoneInfo; -class LLVOAvatarSkeletonInfo; +class LLViewerJoint;  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  // LLVOAvatar @@ -85,8 +84,6 @@ class LLVOAvatar :  public:  	friend class LLVOAvatarSelf; -protected: -	struct LLVOAvatarXmlInfo;  /********************************************************************************   **                                                                            ** @@ -111,9 +108,6 @@ public:  	virtual void 		initInstance(); // Called after construction to initialize the class.  protected:  	virtual				~LLVOAvatar(); -	BOOL				loadSkeletonNode(); -	BOOL				loadMeshNodes(); -	virtual BOOL		loadLayersets();  /**                    Initialization   **                                                                            ** @@ -190,7 +184,7 @@ public:  	void					dumpAnimationState();  	virtual LLJoint*		getJoint(const std::string &name); -	virtual LLJoint*     	getRootJoint() { return &mRoot; } +	virtual LLJoint*     	getRootJoint() { return mRoot; }  	void					resetJointPositions( void );  	void					resetJointPositionsToDefault( void ); @@ -224,7 +218,6 @@ public:  public:  	virtual bool 	isSelf() const { return false; } // True if this avatar is for this viewer's agent  	/*virtual*/BOOL	isUsingBakedTextures() const { return mUseServerBakes; } // e.g. false if in appearance edit mode		 -	bool isBuilt() const { return mIsBuilt; }  private: //aligned members  	LL_ALIGN_16(LLVector4a	mImpostorExtents[2]); @@ -343,7 +336,6 @@ protected:  /**                    State   **                                                                            **   *******************************************************************************/ -  /********************************************************************************   **                                                                            **   **                    SKELETON @@ -351,74 +343,22 @@ protected:  public:  	void				updateHeadOffset(); -	F32					getPelvisToFoot() const { return mPelvisToFoot; }  	void				setPelvisOffset( bool hasOffset, const LLVector3& translation, F32 offset ) ;  	bool				hasPelvisOffset( void ) { return mHasPelvisOffset; }  	void				postPelvisSetRecalc( void );  	void				setPelvisOffset( F32 pelvixFixupAmount ); +	/*virtual*/ BOOL	loadSkeletonNode(); +	/*virtual*/ void	buildCharacter(); +  	bool				mHasPelvisOffset;  	LLVector3			mPelvisOffset;  	F32					mLastPelvisToFoot;  	F32					mPelvisFixup;  	F32					mLastPelvisFixup; -	LLVector3			mHeadOffset; // current head position -	LLViewerJoint		mRoot; - -	typedef std::map<std::string, LLJoint*> joint_map_t; -	joint_map_t			mJointMap; - -protected: -	static BOOL			parseSkeletonFile(const std::string& filename); -	void				buildCharacter(); -	virtual BOOL		loadAvatar(); - -	BOOL				setupBone(const LLVOAvatarBoneInfo* info, LLViewerJoint* parent, S32 ¤t_volume_num, S32 ¤t_joint_num); -	BOOL				buildSkeleton(const LLVOAvatarSkeletonInfo *info); -private: -	BOOL				mIsBuilt; // state of deferred character building -	S32					mNumJoints; -	LLViewerJoint*		mSkeleton; -	 -	//-------------------------------------------------------------------- -	// Pelvis height adjustment members. -	//-------------------------------------------------------------------- -public: -	LLVector3			mBodySize;  	S32					mLastSkeletonSerialNum; -private: -	F32					mPelvisToFoot; -	//-------------------------------------------------------------------- -	// Cached pointers to well known joints -	//-------------------------------------------------------------------- -public: -	LLViewerJoint* 		mPelvisp; -	LLViewerJoint* 		mTorsop; -	LLViewerJoint* 		mChestp; -	LLViewerJoint* 		mNeckp; -	LLViewerJoint* 		mHeadp; -	LLViewerJoint* 		mSkullp; -	LLViewerJoint* 		mEyeLeftp; -	LLViewerJoint* 		mEyeRightp; -	LLViewerJoint* 		mHipLeftp; -	LLViewerJoint* 		mHipRightp; -	LLViewerJoint* 		mKneeLeftp; -	LLViewerJoint* 		mKneeRightp; -	LLViewerJoint* 		mAnkleLeftp; -	LLViewerJoint* 		mAnkleRightp; -	LLViewerJoint* 		mFootLeftp; -	LLViewerJoint* 		mFootRightp; -	LLViewerJoint* 		mWristLeftp; -	LLViewerJoint* 		mWristRightp; - -	//-------------------------------------------------------------------- -	// XML parse tree -	//-------------------------------------------------------------------- -private: -	static LLXmlTree 	sXMLTree; // avatar config file -	static LLXmlTree 	sSkeletonXMLTree; // avatar skeleton file  /**                    Skeleton   **                                                                            ** @@ -640,8 +580,6 @@ public:  private:  	static const LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary *getDictionary() { return sAvatarDictionary; }  	static LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary* sAvatarDictionary; -	static LLVOAvatarSkeletonInfo* 					sAvatarSkeletonInfo; -	static LLVOAvatarXmlInfo* 						sAvatarXmlInfo;  	//--------------------------------------------------------------------  	// Messaging @@ -671,13 +609,10 @@ protected:  	virtual void restoreMeshData();  private:  	virtual void	dirtyMesh(S32 priority); // Dirty the avatar mesh, with priority +	LLViewerJoint*	getViewerJoint(S32 idx);  	S32 			mDirtyMesh; // 0 -- not dirty, 1 -- morphed, 2 -- LOD  	BOOL			mMeshTexturesDirty; -	typedef std::multimap<std::string, LLPolyMesh*> polymesh_map_t; -	polymesh_map_t 									mMeshes; -	std::vector<LLViewerJoint *> 					mMeshLOD; -  	//--------------------------------------------------------------------  	// Destroy invisible mesh  	//-------------------------------------------------------------------- @@ -698,6 +633,7 @@ public:  	void 			processAvatarAppearance(LLMessageSystem* mesgsys);  	void 			hideSkirt();  	void			startAppearanceAnimation(); +	/*virtual*/ void bodySizeChanged();  	//--------------------------------------------------------------------  	// Appearance morphing @@ -840,15 +776,6 @@ private:  	F32			mSpeed; // misc. animation repeated state  	//-------------------------------------------------------------------- -	// Collision volumes -	//-------------------------------------------------------------------- -public: -  	S32			mNumCollisionVolumes; -	LLViewerJointCollisionVolume* mCollisionVolumes; -protected: -	BOOL		allocateCollisionVolumes(U32 num); - -	//--------------------------------------------------------------------  	// Dimensions  	//--------------------------------------------------------------------  public: @@ -858,7 +785,6 @@ public:  	void 		resolveRayCollisionAgent(const LLVector3d start_pt, const LLVector3d end_pt, LLVector3d &out_pos, LLVector3 &out_norm);  	void 		slamPosition(); // Slam position to transmitted position (for teleport);  protected: -	void 		computeBodySize();  	//--------------------------------------------------------------------  	// Material being stepped on @@ -1025,90 +951,6 @@ protected:  protected: // Shared with LLVOAvatarSelf -	struct LLVOAvatarXmlInfo -	{ -		LLVOAvatarXmlInfo(); -		~LLVOAvatarXmlInfo(); - -		BOOL 	parseXmlSkeletonNode(LLXmlTreeNode* root); -		BOOL 	parseXmlMeshNodes(LLXmlTreeNode* root); -		BOOL 	parseXmlColorNodes(LLXmlTreeNode* root); -		BOOL 	parseXmlLayerNodes(LLXmlTreeNode* root); -		BOOL 	parseXmlDriverNodes(LLXmlTreeNode* root); -		BOOL	parseXmlMorphNodes(LLXmlTreeNode* root); - -		struct LLVOAvatarMeshInfo -		{ -			typedef std::pair<LLPolyMorphTargetInfo*,BOOL> morph_info_pair_t; -			typedef std::vector<morph_info_pair_t> morph_info_list_t; - -			LLVOAvatarMeshInfo() : mLOD(0), mMinPixelArea(.1f) {} -			~LLVOAvatarMeshInfo() -			{ -				morph_info_list_t::iterator iter; -				for (iter = mPolyMorphTargetInfoList.begin(); iter != mPolyMorphTargetInfoList.end(); iter++) -				{ -					delete iter->first; -				} -				mPolyMorphTargetInfoList.clear(); -			} - -			std::string mType; -			S32			mLOD; -			std::string	mMeshFileName; -			std::string	mReferenceMeshName; -			F32			mMinPixelArea; -			morph_info_list_t mPolyMorphTargetInfoList; -		}; -		typedef std::vector<LLVOAvatarMeshInfo*> mesh_info_list_t; -		mesh_info_list_t mMeshInfoList; - -		typedef std::vector<LLPolySkeletalDistortionInfo*> skeletal_distortion_info_list_t; -		skeletal_distortion_info_list_t mSkeletalDistortionInfoList; -	 -		struct LLVOAvatarAttachmentInfo -		{ -			LLVOAvatarAttachmentInfo() -				: mGroup(-1), mAttachmentID(-1), mPieMenuSlice(-1), mVisibleFirstPerson(FALSE), -				  mIsHUDAttachment(FALSE), mHasPosition(FALSE), mHasRotation(FALSE) {} -			std::string mName; -			std::string mJointName; -			LLVector3 mPosition; -			LLVector3 mRotationEuler; -			S32 mGroup; -			S32 mAttachmentID; -			S32 mPieMenuSlice; -			BOOL mVisibleFirstPerson; -			BOOL mIsHUDAttachment; -			BOOL mHasPosition; -			BOOL mHasRotation; -		}; -		typedef std::vector<LLVOAvatarAttachmentInfo*> attachment_info_list_t; -		attachment_info_list_t mAttachmentInfoList; -	 -		LLTexGlobalColorInfo *mTexSkinColorInfo; -		LLTexGlobalColorInfo *mTexHairColorInfo; -		LLTexGlobalColorInfo *mTexEyeColorInfo; - -		typedef std::vector<LLTexLayerSetInfo*> layer_info_list_t; -		layer_info_list_t mLayerInfoList; - -		typedef std::vector<LLDriverParamInfo*> driver_info_list_t; -		driver_info_list_t mDriverInfoList; - -		struct LLVOAvatarMorphInfo -		{ -			LLVOAvatarMorphInfo() -				: mInvert(FALSE) {} -			std::string mName; -			std::string mRegion; -			std::string mLayer; -			BOOL mInvert; -		}; - -		typedef std::vector<LLVOAvatarMorphInfo*> morph_info_list_t; -		morph_info_list_t	mMorphMaskInfoList; -	};  /**                    Support classes   **                                                                            ** diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index fc52347041..f832a126bd 100755 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -255,7 +255,7 @@ BOOL LLVOAvatarSelf::loadAvatarSelf()  	return success;  } -BOOL LLVOAvatarSelf::buildSkeletonSelf(const LLVOAvatarSkeletonInfo *info) +BOOL LLVOAvatarSelf::buildSkeletonSelf(const LLAvatarSkeletonInfo *info)  {  	LLMemType mt(LLMemType::MTYPE_AVATAR); @@ -589,7 +589,7 @@ LLVOAvatarSelf::~LLVOAvatarSelf()  BOOL LLVOAvatarSelf::loadLayersets()  {  	BOOL success = TRUE; -	for (LLVOAvatarXmlInfo::layer_info_list_t::const_iterator iter = sAvatarXmlInfo->mLayerInfoList.begin(); +	for (LLAvatarXmlInfo::layer_info_list_t::const_iterator iter = sAvatarXmlInfo->mLayerInfoList.begin();  		 iter != sAvatarXmlInfo->mLayerInfoList.end();   		 ++iter)  	{ @@ -952,7 +952,7 @@ void LLVOAvatarSelf::updateRegion(LLViewerRegion *regionp)  void LLVOAvatarSelf::idleUpdateTractorBeam()  {  	// This is only done for yourself (maybe it should be in the agent?) -	if (!needsRenderBeam() || !mIsBuilt) +	if (!needsRenderBeam() || !isBuilt())  	{  		mBeam = NULL;  	} diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h index 75c2743ab0..bdc1ccf133 100755 --- a/indra/newview/llvoavatarself.h +++ b/indra/newview/llvoavatarself.h @@ -67,7 +67,7 @@ public:  protected:  	/*virtual*/ BOOL		loadAvatar();  	BOOL					loadAvatarSelf(); -	BOOL					buildSkeletonSelf(const LLVOAvatarSkeletonInfo *info); +	BOOL					buildSkeletonSelf(const LLAvatarSkeletonInfo *info);  	BOOL					buildMenus();  	/*virtual*/ BOOL		loadLayersets();  | 
