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.master
parent
2e933100bb
commit
77b33d9623
|
|
@ -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
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
||||
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1247,6 +1247,9 @@ bool idle_startup()
|
|||
LLPostProcess::initClass();
|
||||
display_startup();
|
||||
|
||||
LLAvatarAppearance::initClass();
|
||||
display_startup();
|
||||
|
||||
LLViewerObject::initVOClasses();
|
||||
display_startup();
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
@ -90,31 +90,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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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]));
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -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
|
||||
|
|
@ -839,15 +775,6 @@ private:
|
|||
BOOL mTurning; // controls hysteresis on avatar rotation
|
||||
F32 mSpeed; // misc. animation repeated state
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Collision volumes
|
||||
//--------------------------------------------------------------------
|
||||
public:
|
||||
S32 mNumCollisionVolumes;
|
||||
LLViewerJointCollisionVolume* mCollisionVolumes;
|
||||
protected:
|
||||
BOOL allocateCollisionVolumes(U32 num);
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Dimensions
|
||||
//--------------------------------------------------------------------
|
||||
|
|
@ -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
|
||||
** **
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue